@@ -391,3 +391,4 @@
382 i386 pkey_free sys_pkey_free
383 i386 statx sys_statx
384 i386 arch_prctl sys_arch_prctl compat_sys_arch_prctl
+385 i386 destroy_creds sys_destroy_creds
@@ -339,6 +339,7 @@
330 common pkey_alloc sys_pkey_alloc
331 common pkey_free sys_pkey_free
332 common statx sys_statx
+333 common destroy_creds sys_destroy_creds
#
# x32-specific system call numbers start at 512 to avoid cache impact
@@ -2085,3 +2085,25 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
return ret;
}
EXPORT_SYMBOL(vfs_dedupe_file_range);
+
+long vfs_destroy_creds(struct file *fd)
+{
+ struct inode *inode = file_inode(fd);
+
+ if (!S_ISDIR(inode->i_mode))
+ return -EINVAL;
+ if (fd->f_op->destroy_creds)
+ return fd->f_op->destroy_creds(fd);
+ return 0;
+}
+EXPORT_SYMBOL(vfs_destroy_creds);
+
+SYSCALL_DEFINE1(destroy_creds, int, fd_in)
+{
+ struct fd f_in;
+
+ f_in = fdget(fd_in);
+ if (!f_in.file)
+ return 0;
+ return vfs_destroy_creds(f_in.file);
+}
@@ -1690,6 +1690,7 @@ struct file_operations {
u64);
ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
u64);
+ int (*destroy_creds)(struct file *);
};
struct inode_operations {
@@ -1770,6 +1771,7 @@ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
loff_t len, bool *is_same);
extern int vfs_dedupe_file_range(struct file *file,
struct file_dedupe_range *same);
+extern long vfs_destroy_creds(struct file *fd);
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
@@ -905,5 +905,5 @@ asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len,
asmlinkage long sys_pkey_free(int pkey);
asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
unsigned mask, struct statx __user *buffer);
-
+asmlinkage long sys_destroy_creds(int fd_in);
#endif
@@ -731,9 +731,11 @@
__SYSCALL(__NR_pkey_free, sys_pkey_free)
#define __NR_statx 291
__SYSCALL(__NR_statx, sys_statx)
+#define __NR_destroy_creds 292
+__SYSCALL(__NR_destroy_creds, sys_destroy_creds)
#undef __NR_syscalls
-#define __NR_syscalls 292
+#define __NR_syscalls 293
/*
* All syscalls below here should go away really,
@@ -178,6 +178,7 @@ asmlinkage long sys_ni_syscall(void)
cond_syscall(sys_capget);
cond_syscall(sys_capset);
cond_syscall(sys_copy_file_range);
+cond_syscall(sys_destroy_creds);
/* arch-specific weak syscall entries */
cond_syscall(sys_pciconfig_read);
Filesystems (like NFS) would benefit from an ability to destroy credentials for the current uid. Systemcall takes in a file descriptor that's a mount point of the file system. If a non-directory file descriptor supplied it will failed with EINVAL. It will return 1 upto success. If the file system doesn't define a destroy_creds callout, it will return 0. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> --- arch/x86/entry/syscalls/syscall_32.tbl | 1 + arch/x86/entry/syscalls/syscall_64.tbl | 1 + fs/read_write.c | 22 ++++++++++++++++++++++ include/linux/fs.h | 2 ++ include/linux/syscalls.h | 2 +- include/uapi/asm-generic/unistd.h | 4 +++- kernel/sys_ni.c | 1 + 7 files changed, 31 insertions(+), 2 deletions(-)