This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH v16 04/12] namei: LOOKUP_NO_SYMLINKS: block symlink resolution
- From: Aleksa Sarai <cyphar at cyphar dot com>
- To: Al Viro <viro at zeniv dot linux dot org dot uk>, Jeff Layton <jlayton at kernel dot org>, "J. Bruce Fields" <bfields at fieldses dot org>, Arnd Bergmann <arnd at arndb dot de>, David Howells <dhowells at redhat dot com>, Shuah Khan <shuah at kernel dot org>, Shuah Khan <skhan at linuxfoundation dot org>, Ingo Molnar <mingo at redhat dot com>, Peter Zijlstra <peterz at infradead dot org>, Alexei Starovoitov <ast at kernel dot org>, Daniel Borkmann <daniel at iogearbox dot net>, Martin KaFai Lau <kafai at fb dot com>, Song Liu <songliubraving at fb dot com>, Yonghong Song <yhs at fb dot com>, Andrii Nakryiko <andriin at fb dot com>
- Cc: Aleksa Sarai <cyphar at cyphar dot com>, Christian Brauner <christian dot brauner at ubuntu dot com>, Linus Torvalds <torvalds at linux-foundation dot org>, Eric Biederman <ebiederm at xmission dot com>, Andy Lutomirski <luto at kernel dot org>, Andrew Morton <akpm at linux-foundation dot org>, Kees Cook <keescook at chromium dot org>, Jann Horn <jannh at google dot com>, Tycho Andersen <tycho at tycho dot ws>, David Drysdale <drysdale at google dot com>, Chanho Min <chanho dot min at lge dot com>, Oleg Nesterov <oleg at redhat dot com>, Rasmus Villemoes <linux at rasmusvillemoes dot dk>, Alexander Shishkin <alexander dot shishkin at linux dot intel dot com>, Jiri Olsa <jolsa at redhat dot com>, Namhyung Kim <namhyung at kernel dot org>, Christian Brauner <christian at brauner dot io>, Aleksa Sarai <asarai at suse dot de>, dev at opencontainers dot org, containers at lists dot linux-foundation dot org, bpf at vger dot kernel dot org, netdev at vger dot kernel dot org, linux-alpha at vger dot kernel dot org, linux-api at vger dot kernel dot org, libc-alpha at sourceware dot org, linux-arch at vger dot kernel dot org, linux-arm-kernel at lists dot infradead dot org, linux-fsdevel at vger dot kernel dot org, linux-ia64 at vger dot kernel dot org, linux-kernel at vger dot kernel dot org, linux-kselftest at vger dot kernel dot org, linux-m68k at lists dot linux-m68k dot org, linux-mips at vger dot kernel dot org, linux-parisc at vger dot kernel dot org, linuxppc-dev at lists dot ozlabs dot org, linux-s390 at vger dot kernel dot org, linux-sh at vger dot kernel dot org, linux-xtensa at linux-xtensa dot org, sparclinux at vger dot kernel dot org
- Date: Sat, 16 Nov 2019 11:27:54 +1100
- Subject: [PATCH v16 04/12] namei: LOOKUP_NO_SYMLINKS: block symlink resolution
- References: <20191116002802.6663-1-cyphar@cyphar.com>
/* 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 <christian.brauner@ubuntu.com>
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
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 259652667881..14d6d3afb9d3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1052,6 +1052,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 758e9b47db6f..0d86e75c04a7 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 0x010000 /* 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.24.0