* [PATCH v3 2/2] fs/xattr: add *at family syscalls
@ 2024-04-26 16:20 Christian Göttsche
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Christian Göttsche @ 2024-04-26 16:20 UTC (permalink / raw)
To: cgzones
Cc: x86, linux-alpha, linux-kernel, linux-arm-kernel, linux-ia64,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, audit, linux-arch, linux-api,
linux-security-module, selinux, Richard Henderson,
Ivan Kokshaysky, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Aneesh Kumar K.V, Naveen N. Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, Eric Paris,
Arnd Bergmann, Jens Axboe, Pavel Begunkov, Peter Zijlstra,
Sohil Mehta, Palmer Dabbelt, Miklos Szeredi, Nhat Pham,
Casey Schaufler, Florian Fainelli, Kees Cook, Rick Edgecombe,
Mark Rutland, io-uring
From: Christian Göttsche <[email protected]>
Add the four syscalls setxattrat(), getxattrat(), listxattrat() and
removexattrat(). Those can be used to operate on extended attributes,
especially security related ones, either relative to a pinned directory
or on a file descriptor without read access, avoiding a
/proc/<pid>/fd/<fd> detour, requiring a mounted procfs.
One use case will be setfiles(8) setting SELinux file contexts
("security.selinux") without race conditions and without a file
descriptor opened with read access requiring SELinux read permission.
Use the do_{name}at() pattern from fs/open.c.
Pass the value of the extended attribute, its length, and for
setxattrat(2) the command (XATTR_CREATE or XATTR_REPLACE) via an added
struct xattr_args to not exceed six syscall arguments and not
merging the AT_* and XATTR_* flags.
Signed-off-by: Christian Göttsche <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
---
v3:
- pass value, size and xattr_flags via new struct xattr_args to
split AT_* and XATTR_* flags
v2: https://lore.kernel.org/lkml/[email protected]/
- squash syscall introduction and wire up commits
- add AT_XATTR_CREATE and AT_XATTR_REPLACE constants
v1 discussion: https://lore.kernel.org/all/[email protected]/
Previous approach ("f*xattr: allow O_PATH descriptors"): https://lore.kernel.org/all/[email protected]/
---
arch/alpha/kernel/syscalls/syscall.tbl | 4 +
arch/arm/tools/syscall.tbl | 4 +
arch/arm64/include/asm/unistd.h | 2 +-
arch/arm64/include/asm/unistd32.h | 8 ++
arch/m68k/kernel/syscalls/syscall.tbl | 4 +
arch/microblaze/kernel/syscalls/syscall.tbl | 4 +
arch/mips/kernel/syscalls/syscall_n32.tbl | 4 +
arch/mips/kernel/syscalls/syscall_n64.tbl | 4 +
arch/mips/kernel/syscalls/syscall_o32.tbl | 4 +
arch/parisc/kernel/syscalls/syscall.tbl | 4 +
arch/powerpc/kernel/syscalls/syscall.tbl | 4 +
arch/s390/kernel/syscalls/syscall.tbl | 4 +
arch/sh/kernel/syscalls/syscall.tbl | 4 +
arch/sparc/kernel/syscalls/syscall.tbl | 4 +
arch/x86/entry/syscalls/syscall_32.tbl | 4 +
arch/x86/entry/syscalls/syscall_64.tbl | 4 +
arch/xtensa/kernel/syscalls/syscall.tbl | 4 +
fs/xattr.c | 128 ++++++++++++++++----
include/asm-generic/audit_change_attr.h | 6 +
include/linux/syscalls.h | 10 ++
include/uapi/asm-generic/unistd.h | 12 +-
include/uapi/linux/xattr.h | 6 +
22 files changed, 208 insertions(+), 24 deletions(-)
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 8ff110826ce2..fdc11249f1b8 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -501,3 +501,7 @@
569 common lsm_get_self_attr sys_lsm_get_self_attr
570 common lsm_set_self_attr sys_lsm_set_self_attr
571 common lsm_list_modules sys_lsm_list_modules
+572 common setxattrat sys_setxattrat
+573 common getxattrat sys_getxattrat
+574 common listxattrat sys_listxattrat
+575 common removexattrat sys_removexattrat
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index b6c9e01e14f5..22fbbcd8e2b5 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -475,3 +475,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 491b2b9bd553..f3a77719eb05 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -39,7 +39,7 @@
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
-#define __NR_compat_syscalls 462
+#define __NR_compat_syscalls 466
#endif
#define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 7118282d1c79..963c999b8d2e 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -929,6 +929,14 @@ __SYSCALL(__NR_lsm_get_self_attr, sys_lsm_get_self_attr)
__SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
#define __NR_lsm_list_modules 461
__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
+#define __NR_setxattrat 462
+__SYSCALL(__NR_setxattrat, sys_setxattrat)
+#define __NR_getxattrat 463
+__SYSCALL(__NR_getxattrat, sys_getxattrat)
+#define __NR_listxattrat 464
+__SYSCALL(__NR_listxattrat, sys_listxattrat)
+#define __NR_removexattrat 465
+__SYSCALL(__NR_removexattrat, sys_removexattrat)
/*
* Please add new compat syscalls above this comment and update
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 7fd43fd4c9f2..7e8e2d9c3b81 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -461,3 +461,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index b00ab2cabab9..7df7fc7c0528 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -467,3 +467,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 83cfc9eb6b88..07141274f9ff 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -400,3 +400,7 @@
459 n32 lsm_get_self_attr sys_lsm_get_self_attr
460 n32 lsm_set_self_attr sys_lsm_set_self_attr
461 n32 lsm_list_modules sys_lsm_list_modules
+462 n32 setxattrat sys_setxattrat
+463 n32 getxattrat sys_getxattrat
+464 n32 listxattrat sys_listxattrat
+465 n32 removexattrat sys_removexattrat
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 532b855df589..9773412f2812 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -376,3 +376,7 @@
459 n64 lsm_get_self_attr sys_lsm_get_self_attr
460 n64 lsm_set_self_attr sys_lsm_set_self_attr
461 n64 lsm_list_modules sys_lsm_list_modules
+462 n64 setxattrat sys_setxattrat
+463 n64 getxattrat sys_getxattrat
+464 n64 listxattrat sys_listxattrat
+465 n64 removexattrat sys_removexattrat
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index f45c9530ea93..8b5fec66ec18 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -449,3 +449,7 @@
459 o32 lsm_get_self_attr sys_lsm_get_self_attr
460 o32 lsm_set_self_attr sys_lsm_set_self_attr
461 o32 lsm_list_modules sys_lsm_list_modules
+462 o32 setxattrat sys_setxattrat
+463 o32 getxattrat sys_getxattrat
+464 o32 listxattrat sys_listxattrat
+465 o32 removexattrat sys_removexattrat
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index b236a84c4e12..b6ebcaadd460 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -460,3 +460,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 17173b82ca21..7e522a720e1a 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -548,3 +548,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 095bb86339a7..71afa1eb35fb 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -464,3 +464,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat sys_removexattrat
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index 86fe269f0220..1fb0ac9f6c58 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -464,3 +464,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index b23d59313589..bdd90010c8d1 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -507,3 +507,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 5f8591ce7f25..779dd1a9835d 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -466,3 +466,7 @@
459 i386 lsm_get_self_attr sys_lsm_get_self_attr
460 i386 lsm_set_self_attr sys_lsm_set_self_attr
461 i386 lsm_list_modules sys_lsm_list_modules
+462 i386 setxattrat sys_setxattrat
+463 i386 getxattrat sys_getxattrat
+464 i386 listxattrat sys_listxattrat
+465 i386 removexattrat sys_removexattrat
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 7e8d46f4147f..819c90564f82 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -383,6 +383,10 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
#
# Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index dd116598fb25..36bdfe759878 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -432,3 +432,7 @@
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
+462 common setxattrat sys_setxattrat
+463 common getxattrat sys_getxattrat
+464 common listxattrat sys_listxattrat
+465 common removexattrat sys_removexattrat
diff --git a/fs/xattr.c b/fs/xattr.c
index 941aab719da0..d45e83224a7c 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -655,21 +655,28 @@ setxattr(struct mnt_idmap *idmap, struct dentry *d,
return error;
}
-static int path_setxattr(const char __user *pathname,
+static int do_setxattrat(int dfd, const char __user *pathname, unsigned int at_flags,
const char __user *name, const void __user *value,
- size_t size, int flags, unsigned int lookup_flags)
+ size_t size, int xattr_flags)
{
struct path path;
int error;
+ int lookup_flags;
+ if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ lookup_flags = (at_flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+ if (at_flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+ error = user_path_at(dfd, pathname, lookup_flags, &path);
if (error)
return error;
error = mnt_want_write(path.mnt);
if (!error) {
error = setxattr(mnt_idmap(path.mnt), path.dentry, name,
- value, size, flags);
+ value, size, xattr_flags);
mnt_drop_write(path.mnt);
}
path_put(&path);
@@ -680,18 +687,38 @@ static int path_setxattr(const char __user *pathname,
return error;
}
+SYSCALL_DEFINE6(setxattrat, int, dfd, const char __user *, pathname, unsigned int, at_flags,
+ const char __user *, name, const struct xattr_args __user *, uargs,
+ size_t, usize)
+{
+ struct xattr_args args = {};
+ int error;
+
+ if (usize > PAGE_SIZE)
+ return -E2BIG;
+ if (usize < sizeof(args))
+ return -EINVAL;
+
+ error = copy_struct_from_user(&args, sizeof(args), uargs, usize);
+ if (error)
+ return error;
+
+ return do_setxattrat(dfd, pathname, at_flags, name, (const void __user *)args.value,
+ args.size, args.flags);
+}
+
SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
- return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
+ return do_setxattrat(AT_FDCWD, pathname, 0, name, value, size, flags);
}
SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
- return path_setxattr(pathname, name, value, size, flags, 0);
+ return do_setxattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, name, value, size, flags);
}
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
@@ -774,14 +801,22 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d,
return error;
}
-static ssize_t path_getxattr(const char __user *pathname,
+static ssize_t do_getxattrat(int dfd, const char __user *pathname, unsigned int at_flags,
const char __user *name, void __user *value,
- size_t size, unsigned int lookup_flags)
+ size_t size)
{
struct path path;
ssize_t error;
+ int lookup_flags;
+
+ if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ lookup_flags = (at_flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+ if (at_flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+ error = user_path_at(dfd, pathname, lookup_flags, &path);
if (error)
return error;
error = getxattr(mnt_idmap(path.mnt), path.dentry, name, value, size);
@@ -793,16 +828,37 @@ static ssize_t path_getxattr(const char __user *pathname,
return error;
}
+SYSCALL_DEFINE6(getxattrat, int, dfd, const char __user *, pathname, unsigned int, at_flags,
+ const char __user *, name, struct xattr_args __user *, uargs, size_t, usize)
+{
+ struct xattr_args args = {};
+ int error;
+
+ if (usize > PAGE_SIZE)
+ return -E2BIG;
+ if (usize < sizeof(args))
+ return -EINVAL;
+
+ error = copy_struct_from_user(&args, sizeof(args), uargs, usize);
+ if (error)
+ return error;
+
+ if (args.flags != 0)
+ return -EINVAL;
+
+ return do_getxattrat(dfd, pathname, at_flags, name, (void __user *)args.value, args.size);
+}
+
SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
- return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
+ return do_getxattrat(AT_FDCWD, pathname, 0, name, value, size);
}
SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
- return path_getxattr(pathname, name, value, size, 0);
+ return do_getxattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, name, value, size);
}
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
@@ -852,13 +908,21 @@ listxattr(struct dentry *d, char __user *list, size_t size)
return error;
}
-static ssize_t path_listxattr(const char __user *pathname, char __user *list,
- size_t size, unsigned int lookup_flags)
+static ssize_t do_listxattrat(int dfd, const char __user *pathname, char __user *list,
+ size_t size, int flags)
{
struct path path;
ssize_t error;
+ int lookup_flags;
+
+ if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+ if (flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+ error = user_path_at(dfd, pathname, lookup_flags, &path);
if (error)
return error;
error = listxattr(path.dentry, list, size);
@@ -870,16 +934,22 @@ static ssize_t path_listxattr(const char __user *pathname, char __user *list,
return error;
}
+SYSCALL_DEFINE5(listxattrat, int, dfd, const char __user *, pathname, char __user *, list,
+ size_t, size, int, flags)
+{
+ return do_listxattrat(dfd, pathname, list, size, flags);
+}
+
SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
- return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
+ return do_listxattrat(AT_FDCWD, pathname, list, size, 0);
}
SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
- return path_listxattr(pathname, list, size, 0);
+ return do_listxattrat(AT_FDCWD, pathname, list, size, AT_SYMLINK_NOFOLLOW);
}
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
@@ -898,7 +968,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
/*
* Extended attribute REMOVE operations
*/
-static long
+static int
removexattr(struct mnt_idmap *idmap, struct dentry *d,
const char __user *name)
{
@@ -917,13 +987,21 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d,
return vfs_removexattr(idmap, d, kname);
}
-static int path_removexattr(const char __user *pathname,
- const char __user *name, unsigned int lookup_flags)
+static int do_removexattrat(int dfd, const char __user *pathname,
+ const char __user *name, int flags)
{
struct path path;
int error;
+ int lookup_flags;
+
+ if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+ if (flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+ error = user_path_at(dfd, pathname, lookup_flags, &path);
if (error)
return error;
error = mnt_want_write(path.mnt);
@@ -939,16 +1017,22 @@ static int path_removexattr(const char __user *pathname,
return error;
}
+SYSCALL_DEFINE4(removexattrat, int, dfd, const char __user *, pathname,
+ const char __user *, name, int, flags)
+{
+ return do_removexattrat(dfd, pathname, name, flags);
+}
+
SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
const char __user *, name)
{
- return path_removexattr(pathname, name, LOOKUP_FOLLOW);
+ return do_removexattrat(AT_FDCWD, pathname, name, 0);
}
SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
const char __user *, name)
{
- return path_removexattr(pathname, name, 0);
+ return do_removexattrat(AT_FDCWD, pathname, name, AT_SYMLINK_NOFOLLOW);
}
SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h
index 331670807cf0..cc840537885f 100644
--- a/include/asm-generic/audit_change_attr.h
+++ b/include/asm-generic/audit_change_attr.h
@@ -11,9 +11,15 @@ __NR_lchown,
__NR_fchown,
#endif
__NR_setxattr,
+#ifdef __NR_setxattrat
+__NR_setxattrat,
+#endif
__NR_lsetxattr,
__NR_fsetxattr,
__NR_removexattr,
+#ifdef __NR_removexattrat
+__NR_removexattrat,
+#endif
__NR_lremovexattr,
__NR_fremovexattr,
#ifdef __NR_fchownat
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e619ac10cd23..e06fffc48535 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -338,23 +338,33 @@ asmlinkage long sys_io_uring_register(unsigned int fd, unsigned int op,
void __user *arg, unsigned int nr_args);
asmlinkage long sys_setxattr(const char __user *path, const char __user *name,
const void __user *value, size_t size, int flags);
+asmlinkage long sys_setxattrat(int dfd, const char __user *path, unsigned int at_flags,
+ const char __user *name,
+ const struct xattr_args __user *args, size_t size);
asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name,
const void __user *value, size_t size, int flags);
asmlinkage long sys_fsetxattr(int fd, const char __user *name,
const void __user *value, size_t size, int flags);
asmlinkage long sys_getxattr(const char __user *path, const char __user *name,
void __user *value, size_t size);
+asmlinkage long sys_getxattrat(int dfd, const char __user *path, unsigned int at_flags,
+ const char __user *name,
+ struct xattr_args __user *args, size_t size);
asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name,
void __user *value, size_t size);
asmlinkage long sys_fgetxattr(int fd, const char __user *name,
void __user *value, size_t size);
asmlinkage long sys_listxattr(const char __user *path, char __user *list,
size_t size);
+asmlinkage long sys_listxattrat(int dfd, const char __user *path, char __user *list,
+ size_t size, int flags);
asmlinkage long sys_llistxattr(const char __user *path, char __user *list,
size_t size);
asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size);
asmlinkage long sys_removexattr(const char __user *path,
const char __user *name);
+asmlinkage long sys_removexattrat(int dfd, const char __user *path,
+ const char __user *name, int flags);
asmlinkage long sys_lremovexattr(const char __user *path,
const char __user *name);
asmlinkage long sys_fremovexattr(int fd, const char __user *name);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 75f00965ab15..21b275a8dcd6 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -842,8 +842,18 @@ __SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
#define __NR_lsm_list_modules 461
__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
+/* fs/xattr.c */
+#define __NR_setxattrat 462
+__SYSCALL(__NR_setxattrat, sys_setxattrat)
+#define __NR_getxattrat 463
+__SYSCALL(__NR_getxattrat, sys_getxattrat)
+#define __NR_listxattrat 464
+__SYSCALL(__NR_listxattrat, sys_listxattrat)
+#define __NR_removexattrat 465
+__SYSCALL(__NR_removexattrat, sys_removexattrat)
+
#undef __NR_syscalls
-#define __NR_syscalls 462
+#define __NR_syscalls 466
/*
* 32 bit systems traditionally used different
diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
index 9463db2dfa9d..e9ac2acc40c3 100644
--- a/include/uapi/linux/xattr.h
+++ b/include/uapi/linux/xattr.h
@@ -20,6 +20,12 @@
#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
+
+struct xattr_args {
+ __aligned_u64 __user value;
+ __u32 size;
+ __u32 flags;
+};
#endif
/* Namespaces */
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx
2024-04-26 16:20 [PATCH v3 2/2] fs/xattr: add *at family syscalls Christian Göttsche
@ 2024-04-26 16:20 ` Christian Göttsche
2024-04-30 10:09 ` Jan Kara
2024-04-30 12:40 ` Christian Brauner
2024-04-26 17:38 ` [PATCH v3 2/2] fs/xattr: add *at family syscalls Arnd Bergmann
2024-04-30 10:09 ` Jan Kara
2 siblings, 2 replies; 6+ messages in thread
From: Christian Göttsche @ 2024-04-26 16:20 UTC (permalink / raw)
To: cgzones
Cc: Christian Brauner, Alexander Viro, Jan Kara, Jens Axboe,
Pavel Begunkov, linux-fsdevel, linux-kernel, io-uring
From: Christian Göttsche <[email protected]>
Rename the struct xattr_ctx to increase distinction with the about to be
added user API struct xattr_args.
No functional change.
Suggested-by: Christian Brauner <[email protected]>
Signed-off-by: Christian Göttsche <[email protected]>
---
v3: added based on feedback
---
fs/internal.h | 8 ++++----
fs/xattr.c | 10 +++++-----
io_uring/xattr.c | 2 +-
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/internal.h b/fs/internal.h
index 7ca738904e34..1caa6a8f666f 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -260,7 +260,7 @@ struct xattr_name {
char name[XATTR_NAME_MAX + 1];
};
-struct xattr_ctx {
+struct kernel_xattr_ctx {
/* Value of attribute */
union {
const void __user *cvalue;
@@ -276,11 +276,11 @@ struct xattr_ctx {
ssize_t do_getxattr(struct mnt_idmap *idmap,
struct dentry *d,
- struct xattr_ctx *ctx);
+ struct kernel_xattr_ctx *ctx);
-int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
+int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx);
int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
- struct xattr_ctx *ctx);
+ struct kernel_xattr_ctx *ctx);
int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);
#ifdef CONFIG_FS_POSIX_ACL
diff --git a/fs/xattr.c b/fs/xattr.c
index f8b643f91a98..941aab719da0 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
* Extended attribute SET operations
*/
-int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
+int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx)
{
int error;
@@ -620,7 +620,7 @@ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
}
int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
- struct xattr_ctx *ctx)
+ struct kernel_xattr_ctx *ctx)
{
if (is_posix_acl_xattr(ctx->kname->name))
return do_set_acl(idmap, dentry, ctx->kname->name,
@@ -636,7 +636,7 @@ setxattr(struct mnt_idmap *idmap, struct dentry *d,
int flags)
{
struct xattr_name kname;
- struct xattr_ctx ctx = {
+ struct kernel_xattr_ctx ctx = {
.cvalue = value,
.kvalue = NULL,
.size = size,
@@ -719,7 +719,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
*/
ssize_t
do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
- struct xattr_ctx *ctx)
+ struct kernel_xattr_ctx *ctx)
{
ssize_t error;
char *kname = ctx->kname->name;
@@ -754,7 +754,7 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d,
{
ssize_t error;
struct xattr_name kname;
- struct xattr_ctx ctx = {
+ struct kernel_xattr_ctx ctx = {
.value = value,
.kvalue = NULL,
.size = size,
diff --git a/io_uring/xattr.c b/io_uring/xattr.c
index 44905b82eea8..28b8f7b1af7c 100644
--- a/io_uring/xattr.c
+++ b/io_uring/xattr.c
@@ -18,7 +18,7 @@
struct io_xattr {
struct file *file;
- struct xattr_ctx ctx;
+ struct kernel_xattr_ctx ctx;
struct filename *filename;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
@ 2024-04-30 10:09 ` Jan Kara
2024-04-30 12:40 ` Christian Brauner
1 sibling, 0 replies; 6+ messages in thread
From: Jan Kara @ 2024-04-30 10:09 UTC (permalink / raw)
To: cgzones
Cc: Christian Brauner, Alexander Viro, Jan Kara, Jens Axboe,
Pavel Begunkov, linux-fsdevel, linux-kernel, io-uring
On Fri 26-04-24 18:20:15, Christian Göttsche wrote:
> From: Christian Göttsche <[email protected]>
>
> Rename the struct xattr_ctx to increase distinction with the about to be
> added user API struct xattr_args.
>
> No functional change.
>
> Suggested-by: Christian Brauner <[email protected]>
> Signed-off-by: Christian Göttsche <[email protected]>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <[email protected]>
Honza
> ---
> v3: added based on feedback
> ---
> fs/internal.h | 8 ++++----
> fs/xattr.c | 10 +++++-----
> io_uring/xattr.c | 2 +-
> 3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/fs/internal.h b/fs/internal.h
> index 7ca738904e34..1caa6a8f666f 100644
> --- a/fs/internal.h
> +++ b/fs/internal.h
> @@ -260,7 +260,7 @@ struct xattr_name {
> char name[XATTR_NAME_MAX + 1];
> };
>
> -struct xattr_ctx {
> +struct kernel_xattr_ctx {
> /* Value of attribute */
> union {
> const void __user *cvalue;
> @@ -276,11 +276,11 @@ struct xattr_ctx {
>
> ssize_t do_getxattr(struct mnt_idmap *idmap,
> struct dentry *d,
> - struct xattr_ctx *ctx);
> + struct kernel_xattr_ctx *ctx);
>
> -int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
> +int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx);
> int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> - struct xattr_ctx *ctx);
> + struct kernel_xattr_ctx *ctx);
> int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);
>
> #ifdef CONFIG_FS_POSIX_ACL
> diff --git a/fs/xattr.c b/fs/xattr.c
> index f8b643f91a98..941aab719da0 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
> * Extended attribute SET operations
> */
>
> -int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
> +int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx)
> {
> int error;
>
> @@ -620,7 +620,7 @@ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
> }
>
> int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
> - struct xattr_ctx *ctx)
> + struct kernel_xattr_ctx *ctx)
> {
> if (is_posix_acl_xattr(ctx->kname->name))
> return do_set_acl(idmap, dentry, ctx->kname->name,
> @@ -636,7 +636,7 @@ setxattr(struct mnt_idmap *idmap, struct dentry *d,
> int flags)
> {
> struct xattr_name kname;
> - struct xattr_ctx ctx = {
> + struct kernel_xattr_ctx ctx = {
> .cvalue = value,
> .kvalue = NULL,
> .size = size,
> @@ -719,7 +719,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
> */
> ssize_t
> do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
> - struct xattr_ctx *ctx)
> + struct kernel_xattr_ctx *ctx)
> {
> ssize_t error;
> char *kname = ctx->kname->name;
> @@ -754,7 +754,7 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d,
> {
> ssize_t error;
> struct xattr_name kname;
> - struct xattr_ctx ctx = {
> + struct kernel_xattr_ctx ctx = {
> .value = value,
> .kvalue = NULL,
> .size = size,
> diff --git a/io_uring/xattr.c b/io_uring/xattr.c
> index 44905b82eea8..28b8f7b1af7c 100644
> --- a/io_uring/xattr.c
> +++ b/io_uring/xattr.c
> @@ -18,7 +18,7 @@
>
> struct io_xattr {
> struct file *file;
> - struct xattr_ctx ctx;
> + struct kernel_xattr_ctx ctx;
> struct filename *filename;
> };
>
> --
> 2.43.0
>
--
Jan Kara <[email protected]>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
2024-04-30 10:09 ` Jan Kara
@ 2024-04-30 12:40 ` Christian Brauner
1 sibling, 0 replies; 6+ messages in thread
From: Christian Brauner @ 2024-04-30 12:40 UTC (permalink / raw)
To: cgzones, cgoettsche
Cc: Christian Brauner, Alexander Viro, Jan Kara, Jens Axboe,
Pavel Begunkov, linux-fsdevel, linux-kernel, io-uring
On Fri, 26 Apr 2024 18:20:15 +0200, Christian Göttsche wrote:
> Rename the struct xattr_ctx to increase distinction with the about to be
> added user API struct xattr_args.
>
> No functional change.
>
>
So I've picked that series up as this is still a useful addition.
Obviously too late for this merge window.
However, I stated multiple times that we're not going to add *xattrat()
variants that allow to set or get xattrs with AT_EMPTY_PATH on O_PATH
file descriptors. Not just because conceptually setting and getting
xattrs should be treated akin to read/write wrt to O_PATH but also
because it makes the concept of an O_PATH more and more meaningless if
we can do ever more things we it.
But it will also break assumptions of code that would be surprised if an
O_PATH fd suddenly can be used to set and get xattr. So I'll fix it up
so AT_EMPTY_PATH is handled to exclude O_PATH file descriptors.
---
Applied to the vfs.xattr branch of the vfs/vfs.git tree.
Patches in the vfs.xattr branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs.xattr
[1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx
https://git.kernel.org/vfs/vfs/c/836c8e8bb147
[2/2] fs/xattr: add *at family syscalls
https://git.kernel.org/vfs/vfs/c/71491cbe0205
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] fs/xattr: add *at family syscalls
2024-04-26 16:20 [PATCH v3 2/2] fs/xattr: add *at family syscalls Christian Göttsche
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
@ 2024-04-26 17:38 ` Arnd Bergmann
2024-04-30 10:09 ` Jan Kara
2 siblings, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2024-04-26 17:38 UTC (permalink / raw)
To: cgzones
Cc: x86, linux-alpha, linux-kernel, linux-arm-kernel, linux-ia64,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, audit, Linux-Arch, linux-api,
linux-security-module, selinux, Richard Henderson,
Ivan Kokshaysky, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E . J . Bottomley, Helge Deller,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Aneesh Kumar K.V, Naveen N. Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S . Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, Eric Paris, Jens Axboe,
Pavel Begunkov, Peter Zijlstra, Sohil Mehta, Palmer Dabbelt,
Miklos Szeredi, Nhat Pham, Casey Schaufler, Florian Fainelli,
Kees Cook, Rick Edgecombe, Mark Rutland, io-uring
On Fri, Apr 26, 2024, at 18:20, Christian Göttsche wrote:
> From: Christian Göttsche <[email protected]>
>
> Add the four syscalls setxattrat(), getxattrat(), listxattrat() and
> removexattrat(). Those can be used to operate on extended attributes,
> especially security related ones, either relative to a pinned directory
> or on a file descriptor without read access, avoiding a
> /proc/<pid>/fd/<fd> detour, requiring a mounted procfs.
>
> One use case will be setfiles(8) setting SELinux file contexts
> ("security.selinux") without race conditions and without a file
> descriptor opened with read access requiring SELinux read permission.
>
> Use the do_{name}at() pattern from fs/open.c.
>
> Pass the value of the extended attribute, its length, and for
> setxattrat(2) the command (XATTR_CREATE or XATTR_REPLACE) via an added
> struct xattr_args to not exceed six syscall arguments and not
> merging the AT_* and XATTR_* flags.
>
> Signed-off-by: Christian Göttsche <[email protected]>
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]
I checked that the syscalls are all well-formed regarding
argument types, number of arguments and (absence of)
compat handling, and that they are wired up correctly
across architectures
I did not look at the actual implementation in detail.
Reviewed-by: Arnd Bergmann <[email protected]>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] fs/xattr: add *at family syscalls
2024-04-26 16:20 [PATCH v3 2/2] fs/xattr: add *at family syscalls Christian Göttsche
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
2024-04-26 17:38 ` [PATCH v3 2/2] fs/xattr: add *at family syscalls Arnd Bergmann
@ 2024-04-30 10:09 ` Jan Kara
2 siblings, 0 replies; 6+ messages in thread
From: Jan Kara @ 2024-04-30 10:09 UTC (permalink / raw)
To: cgzones
Cc: x86, linux-alpha, linux-kernel, linux-arm-kernel, linux-ia64,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, audit, linux-arch, linux-api,
linux-security-module, selinux, Richard Henderson,
Ivan Kokshaysky, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Aneesh Kumar K.V, Naveen N. Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Christian Brauner, Jan Kara, Paul Moore, Eric Paris,
Arnd Bergmann, Jens Axboe, Pavel Begunkov, Peter Zijlstra,
Sohil Mehta, Palmer Dabbelt, Miklos Szeredi, Nhat Pham,
Casey Schaufler, Florian Fainelli, Kees Cook, Rick Edgecombe,
Mark Rutland, io-uring
On Fri 26-04-24 18:20:14, Christian Göttsche wrote:
> From: Christian Göttsche <[email protected]>
>
> Add the four syscalls setxattrat(), getxattrat(), listxattrat() and
> removexattrat(). Those can be used to operate on extended attributes,
> especially security related ones, either relative to a pinned directory
> or on a file descriptor without read access, avoiding a
> /proc/<pid>/fd/<fd> detour, requiring a mounted procfs.
>
> One use case will be setfiles(8) setting SELinux file contexts
> ("security.selinux") without race conditions and without a file
> descriptor opened with read access requiring SELinux read permission.
>
> Use the do_{name}at() pattern from fs/open.c.
>
> Pass the value of the extended attribute, its length, and for
> setxattrat(2) the command (XATTR_CREATE or XATTR_REPLACE) via an added
> struct xattr_args to not exceed six syscall arguments and not
> merging the AT_* and XATTR_* flags.
>
> Signed-off-by: Christian Göttsche <[email protected]>
The patch looks good to me. Just a few nits below:
> -static int path_setxattr(const char __user *pathname,
> +static int do_setxattrat(int dfd, const char __user *pathname, unsigned int at_flags,
Can we please stay within 80 columns (happens in multiple places in the
patch)? I don't insist but it makes things easier to read in some setups so
I prefer it.
> @@ -852,13 +908,21 @@ listxattr(struct dentry *d, char __user *list, size_t size)
> return error;
> }
>
> -static ssize_t path_listxattr(const char __user *pathname, char __user *list,
> - size_t size, unsigned int lookup_flags)
> +static ssize_t do_listxattrat(int dfd, const char __user *pathname, char __user *list,
> + size_t size, int flags)
So I like how in previous syscalls you have 'at_flags', 'lookup_flags', and
'xattr_flags'. That makes things much easier to digest. Can you please stay
with that convention here as well and call this argument 'at_flags'? Also I
think the argument ordering like "dfd, pathname, at_flags, list, size" is
more consistent with other syscalls you define.
> @@ -870,16 +934,22 @@ static ssize_t path_listxattr(const char __user *pathname, char __user *list,
> return error;
> }
>
> +SYSCALL_DEFINE5(listxattrat, int, dfd, const char __user *, pathname, char __user *, list,
> + size_t, size, int, flags)
> +{
> + return do_listxattrat(dfd, pathname, list, size, flags);
> +}
> +
Same comment as above - "flags" -> "at_flags" and reorder args please.
> @@ -917,13 +987,21 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d,
> return vfs_removexattr(idmap, d, kname);
> }
>
> -static int path_removexattr(const char __user *pathname,
> - const char __user *name, unsigned int lookup_flags)
> +static int do_removexattrat(int dfd, const char __user *pathname,
> + const char __user *name, int flags)
> {
Same comment as above - "flags" -> "at_flags" and reorder args please.
> @@ -939,16 +1017,22 @@ static int path_removexattr(const char __user *pathname,
> return error;
> }
>
> +SYSCALL_DEFINE4(removexattrat, int, dfd, const char __user *, pathname,
> + const char __user *, name, int, flags)
> +{
Same comment as above - "flags" -> "at_flags" and reorder args please.
Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-04-30 12:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-26 16:20 [PATCH v3 2/2] fs/xattr: add *at family syscalls Christian Göttsche
2024-04-26 16:20 ` [PATCH v3 1/2] fs: rename struct xattr_ctx to kernel_xattr_ctx Christian Göttsche
2024-04-30 10:09 ` Jan Kara
2024-04-30 12:40 ` Christian Brauner
2024-04-26 17:38 ` [PATCH v3 2/2] fs/xattr: add *at family syscalls Arnd Bergmann
2024-04-30 10:09 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox