Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932228AbbBDICW (ORCPT ); Wed, 4 Feb 2015 03:02:22 -0500 Received: from mail-oi0-f46.google.com ([209.85.218.46]:47382 "EHLO mail-oi0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932204AbbBDICT (ORCPT ); Wed, 4 Feb 2015 03:02:19 -0500 MIME-Version: 1.0 In-Reply-To: <1422896713-25367-2-git-send-email-holler@ahsoftware.de> References: <1422896713-25367-1-git-send-email-holler@ahsoftware.de> <1422896713-25367-2-git-send-email-holler@ahsoftware.de> From: Michael Kerrisk Date: Wed, 4 Feb 2015 09:01:57 +0100 X-Google-Sender-Auth: tGilCSzIsI_QfA3qh6NNkwFhXLU Message-ID: Subject: Re: [PATCH 1/5] WIP: Add syscall unlinkat_s (currently x86* only) To: Alexander Holler Cc: Linux-Fsdevel , Linux Kernel , Linux API Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7624 Lines: 185 [CC += linux-api@] On Mon, Feb 2, 2015 at 6:05 PM, Alexander Holler wrote: > Signed-off-by: Alexander Holler > --- > arch/x86/syscalls/syscall_32.tbl | 1 + > arch/x86/syscalls/syscall_64.tbl | 1 + > fs/namei.c | 38 ++++++++++++++++++++++++++++++----- > include/asm-generic/audit_dir_write.h | 1 + > include/linux/fs.h | 1 + > include/linux/syscalls.h | 1 + > include/uapi/asm-generic/unistd.h | 4 +++- > tools/perf/builtin-trace.c | 2 ++ > 8 files changed, 43 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl > index 9fe1b5d..7a3d530 100644 > --- a/arch/x86/syscalls/syscall_32.tbl > +++ b/arch/x86/syscalls/syscall_32.tbl > @@ -364,3 +364,4 @@ > 355 i386 getrandom sys_getrandom > 356 i386 memfd_create sys_memfd_create > 357 i386 bpf sys_bpf > +359 i386 unlinkat_s sys_unlinkat_s > diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl > index 281150b..97eaf01 100644 > --- a/arch/x86/syscalls/syscall_64.tbl > +++ b/arch/x86/syscalls/syscall_64.tbl > @@ -328,6 +328,7 @@ > 319 common memfd_create sys_memfd_create > 320 common kexec_file_load sys_kexec_file_load > 321 common bpf sys_bpf > +322 common unlinkat_s sys_unlinkat_s > > # > # x32-specific system call numbers start at 512 to avoid cache impact > diff --git a/fs/namei.c b/fs/namei.c > index db5fe86..1ad3724 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -3717,7 +3717,7 @@ EXPORT_SYMBOL(vfs_unlink); > * writeout happening, and we don't want to prevent access to the directory > * while waiting on the I/O. > */ > -static long do_unlinkat(int dfd, const char __user *pathname) > +static long do_unlinkat(int dfd, const char __user *pathname, bool secure) > { > int error; > struct filename *name; > @@ -3759,8 +3759,25 @@ exit2: > dput(dentry); > } > mutex_unlock(&nd.path.dentry->d_inode->i_mutex); > - if (inode) > - iput(inode); /* truncate the inode here */ > + if (inode) { > + // TODO: > + // if (inode is file and 's' flag is set) > + // secure = true; > + if (!secure) > + iput(inode); /* truncate the inode here */ > + else { > + struct super_block *sb = inode->i_sb; > + if (sb->s_op->set_secure_delete) > + sb->s_op->set_secure_delete(sb, true); > + // TODO: We should fail if secure isn't supported, > + // look up how that's possible here. > + iput(inode); /* truncate the inode here */ > + // TODO: check if sb is still valid after the inode is gone > + sync_filesystem(sb); > + if (sb->s_op->set_secure_delete) > + sb->s_op->set_secure_delete(sb, false); > + } > + } > inode = NULL; > if (delegated_inode) { > error = break_deleg_wait(&delegated_inode); > @@ -3796,12 +3813,23 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) > if (flag & AT_REMOVEDIR) > return do_rmdir(dfd, pathname); > > - return do_unlinkat(dfd, pathname); > + return do_unlinkat(dfd, pathname, false); > } > > SYSCALL_DEFINE1(unlink, const char __user *, pathname) > { > - return do_unlinkat(AT_FDCWD, pathname); > + return do_unlinkat(AT_FDCWD, pathname, false); > +} > + > +SYSCALL_DEFINE3(unlinkat_s, int, dfd, const char __user *, pathname, int, flag) > +{ > + if ((flag & ~AT_REMOVEDIR) != 0) > + return -EINVAL; > + > + if (flag & AT_REMOVEDIR) > + return do_rmdir(dfd, pathname); > + > + return do_unlinkat(dfd, pathname, true); > } > > int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) > diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h > index 7b61db4..5282aba 100644 > --- a/include/asm-generic/audit_dir_write.h > +++ b/include/asm-generic/audit_dir_write.h > @@ -29,4 +29,5 @@ __NR_unlinkat, > __NR_renameat, > __NR_linkat, > __NR_symlinkat, > +__NR_unlinkat_s, > #endif > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 9ab779e..039e969 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -1594,6 +1594,7 @@ struct super_operations { > int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); > long (*nr_cached_objects)(struct super_block *, int); > long (*free_cached_objects)(struct super_block *, long, int); > + void (*set_secure_delete) (struct super_block *, bool); > }; > > /* > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h > index bda9b81..b88019b 100644 > --- a/include/linux/syscalls.h > +++ b/include/linux/syscalls.h > @@ -877,4 +877,5 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags, > asmlinkage long sys_getrandom(char __user *buf, size_t count, > unsigned int flags); > asmlinkage long sys_bpf(int cmd, union bpf_attr *attr, unsigned int size); > +asmlinkage long sys_unlinkat_s(int dfd, const char __user * pathname, int flag); > #endif > diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h > index 22749c1..2ba072e 100644 > --- a/include/uapi/asm-generic/unistd.h > +++ b/include/uapi/asm-generic/unistd.h > @@ -707,9 +707,11 @@ __SYSCALL(__NR_getrandom, sys_getrandom) > __SYSCALL(__NR_memfd_create, sys_memfd_create) > #define __NR_bpf 280 > __SYSCALL(__NR_bpf, sys_bpf) > +#define __NR_unlinkat_s 281 > +__SYSCALL(__NR_unlinkat_s, sys_unlinkat_s) > > #undef __NR_syscalls > -#define __NR_syscalls 281 > +#define __NR_syscalls 282 > > /* > * All syscalls below here should go away really, > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c > index fb12645..1507335 100644 > --- a/tools/perf/builtin-trace.c > +++ b/tools/perf/builtin-trace.c > @@ -1110,6 +1110,8 @@ static struct syscall_fmt { > { .name = "uname", .errmsg = true, .alias = "newuname", }, > { .name = "unlinkat", .errmsg = true, > .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, > + { .name = "unlinkat_s", .errmsg = true, > + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, > { .name = "utimensat", .errmsg = true, > .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, }, > { .name = "write", .errmsg = true, > -- > 2.1.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface", http://blog.man7.org/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/