Thread (17 messages) 17 messages, 6 authors, 2017-08-11

[RFC v3 1/3] VFS adding destroy_creds call

From: Olga Kornievskaia <hidden>
Date: 2017-08-07 21:23:59
Also in: linux-fsdevel, linux-nfs
Subsystem: abi/api, filesystems (vfs and infrastructure), generic include/asm header files, the rest, x86 architecture (32-bit and 64-bit), x86 entry code · Maintainers: Alexander Viro, Christian Brauner, Arnd Bergmann, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Andy Lutomirski

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. If a bad fd leads to EBADF. And if the file
system doesn't implement destroy_creds, ENOSYS is returned.

Signed-off-by: Olga Kornievskaia <redacted>
---
 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(-)
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 448ac21..298e72b 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -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
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 5aef183..c8a7e38 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -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
diff --git a/fs/read_write.c b/fs/read_write.c
index 0cc7033..f2e169b 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -2041,3 +2041,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 -ENOSYS;
+}
+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 -EBADF;
+	return vfs_destroy_creds(f_in.file);
+}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d..882bd40 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1699,6 +1699,7 @@ struct file_operations {
 			u64);
 	ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
 			u64);
+	int (*destroy_creds)(struct file *);
 } __randomize_layout;
 
 struct inode_operations {
@@ -1773,6 +1774,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);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3cb15ea..3b7b749 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -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
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 061185a..0ad6a0d 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -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,
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 8acef85..cb9ee0b 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -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);
-- 
1.8.3.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help