Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp520883ybx; Tue, 5 Nov 2019 01:08:35 -0800 (PST) X-Google-Smtp-Source: APXvYqwTtxI6cokVjhqerG4kYGHB9u2k/BljkXolxVtCmevqcYhUguFv3XEBxEFPScE47cY7yVlY X-Received: by 2002:a17:906:d293:: with SMTP id ay19mr7991374ejb.146.1572944915367; Tue, 05 Nov 2019 01:08:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1572944915; cv=none; d=google.com; s=arc-20160816; b=bk/yGfN1/WsEMtj3/qdNxXmncaX44+2OZ6ERkNCh9hkV8XUzfMEIXG+wr2EgOKpcse /d3usif+2KAgkaab1AdMZmsJZXcczE2G8j2p4m+hlXUxwceXutYyqImHJfR6IuKyyNHh Ce81OAydKaEqrDre2j6W67oOiPITmYgYA4fDZu/Tvq/TpGrcQy8dJi8FCQDfMC3SrGsL 4hmmLTCYRlJDKCNe5Vkd0bwMkedP2EAXOmneWvEiCdGlKVKLJGWfIE/2dWATiJHARDSa EgOUyC0HctYW/5gdx3heo6JN19MI7JLulLgVnvvJTpBbRbXkLggrH3fhgWlAYmXIUcR2 3Kgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=EUAVQBZeh4oWRm+zJewYEx5Ih+GhUqg/7lk04D8hq00=; b=wxV62Ta8dazJV4Ux0jzcztLZmtfjFKGw2AAghsVVqkxWs760Icycwtsy5xJ4f4OYVJ Atro5RM6cDjvgq70G+Zxt4Gem01/zECzDH9+xsuMMFlgN3mf0Egf+javmganYq9o84wI Akh1leyaDZJwZiFf2yFbBoVGLslB6/KzzOkzbLkt50nu40tP6wKXKr6BSD01gE36HN6E NxR2cLanSeljlwVeecu0cUnTuu+UoGUWyExrggnfNNaE61bMLEqQLjY1WuonwQvuBnX6 EJGlYKoAOVPW0T5Iz1hbHyJAwUX2rNMJkrwIT16BB506QsTe1O19J903lkVYbz5mgNb+ k5TQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f13si9616221eda.288.2019.11.05.01.08.11; Tue, 05 Nov 2019 01:08:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387656AbfKEJHZ (ORCPT + 99 others); Tue, 5 Nov 2019 04:07:25 -0500 Received: from mout-p-202.mailbox.org ([80.241.56.172]:31768 "EHLO mout-p-202.mailbox.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727093AbfKEJHZ (ORCPT ); Tue, 5 Nov 2019 04:07:25 -0500 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:105:465:1:2:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 476kMD5BTTzQlBr; Tue, 5 Nov 2019 10:07:20 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp2.mailbox.org ([80.241.60.241]) by hefe.heinlein-support.de (hefe.heinlein-support.de [91.198.250.172]) (amavisd-new, port 10030) with ESMTP id hBZfkmaeX9ST; Tue, 5 Nov 2019 10:07:08 +0100 (CET) From: Aleksa Sarai To: Al Viro , Jeff Layton , "J. Bruce Fields" , Arnd Bergmann , David Howells , Shuah Khan , Shuah Khan , Ingo Molnar , Peter Zijlstra Cc: Aleksa Sarai , Christian Brauner , Linus Torvalds , Eric Biederman , Andy Lutomirski , Andrew Morton , Alexei Starovoitov , Kees Cook , Jann Horn , Tycho Andersen , David Drysdale , Chanho Min , Oleg Nesterov , Rasmus Villemoes , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Christian Brauner , Aleksa Sarai , containers@lists.linux-foundation.org, linux-alpha@vger.kernel.org, linux-api@vger.kernel.org, libc-alpha@sourceware.org, linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-mips@vger.kernel.org, linux-parisc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, linux-xtensa@linux-xtensa.org, sparclinux@vger.kernel.org Subject: [PATCH v15 1/9] namei: LOOKUP_NO_SYMLINKS: block symlink resolution Date: Tue, 5 Nov 2019 20:05:45 +1100 Message-Id: <20191105090553.6350-2-cyphar@cyphar.com> In-Reply-To: <20191105090553.6350-1-cyphar@cyphar.com> References: <20191105090553.6350-1-cyphar@cyphar.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org /* Background. */ Userspace cannot easily resolve a path without resolving symlinks, and would have to manually resolve each path component with O_PATH and O_NOFOLLOW. This is clearly inefficient, and can be fairly easy to screw up (resulting in possible security bugs). Linus has mentioned that Git has a particular need for this kind of flag[1]. It also resolves a fairly long-standing perceived deficiency in O_NOFOLLOw -- that it only blocks the opening of trailing symlinks. This is part of a refresh of Al's AT_NO_JUMPS patchset[2] (which was a variation on David Drysdale's O_BENEATH patchset[3], which in turn was based on the Capsicum project[4]). /* Userspace API. */ LOOKUP_NO_SYMLINKS will be exposed to userspace through openat2(2). /* Semantics. */ Unlike most other LOOKUP flags (most notably LOOKUP_FOLLOW), LOOKUP_NO_SYMLINKS applies to all components of the path. With LOOKUP_NO_SYMLINKS, any symlink path component encountered during path resolution will yield -ELOOP. If the trailing component is a symlink (and no other components were symlinks), then O_PATH|O_NOFOLLOW will not error out and will instead provide a handle to the trailing symlink -- without resolving it. /* Testing. */ LOOKUP_NO_SYMLINKS is tested as part of the openat2(2) selftests. [1]: https://lore.kernel.org/lkml/CA+55aFyOKM7DW7+0sdDFKdZFXgptb5r1id9=Wvhd8AgSP7qjwQ@mail.gmail.com/ [2]: https://lore.kernel.org/lkml/20170429220414.GT29622@ZenIV.linux.org.uk/ [3]: https://lore.kernel.org/lkml/1415094884-18349-1-git-send-email-drysdale@google.com/ [4]: https://lore.kernel.org/lkml/1404124096-21445-1-git-send-email-drysdale@google.com/ Cc: Christian Brauner Suggested-by: Al Viro Suggested-by: Linus Torvalds Signed-off-by: Aleksa Sarai --- fs/namei.c | 3 +++ include/linux/namei.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/fs/namei.c b/fs/namei.c index 671c3c1a3425..4e85d6fa4048 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1045,6 +1045,9 @@ const char *get_link(struct nameidata *nd) int error; const char *res; + if (unlikely(nd->flags & LOOKUP_NO_SYMLINKS)) + return ERR_PTR(-ELOOP); + if (!(nd->flags & LOOKUP_RCU)) { touch_atime(&last->link); cond_resched(); diff --git a/include/linux/namei.h b/include/linux/namei.h index 397a08ade6a2..ee2e35af387f 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -39,6 +39,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_ROOT 0x2000 #define LOOKUP_ROOT_GRABBED 0x0008 +/* Scoping flags for lookup. */ +#define LOOKUP_NO_SYMLINKS 0x020000 /* No symlink crossing. */ + extern int path_pts(struct path *path); extern int user_path_at_empty(int, const char __user *, unsigned, struct path *, int *empty); -- 2.23.0