From bd354c01cb175c50533899743e0e5736e3e36ab0 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 8 Jun 2021 10:12:21 -0700 Subject: proc: Track /proc/$pid/attr/ opener mm_struct commit 591a22c14d3f45cc38bd1931c593c221df2f1881 upstream. Commit bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener") tried to make sure that there could not be a confusion between the opener of a /proc/$pid/attr/ file and the writer. It used struct cred to make sure the privileges didn't change. However, there were existing cases where a more privileged thread was passing the opened fd to a differently privileged thread (during container setup). Instead, use mm_struct to track whether the opener and writer are still the same process. (This is what several other proc files already do, though for different reasons.) Reported-by: Christian Brauner Reported-by: Andrea Righi Tested-by: Andrea Righi Fixes: bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/proc/base.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index 2166f24af37e..d2428d20d5a9 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2384,6 +2384,11 @@ out: } #ifdef CONFIG_SECURITY +static int proc_pid_attr_open(struct inode *inode, struct file *file) +{ + return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS); +} + static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -2414,7 +2419,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, struct task_struct *task = get_proc_task(inode); /* A task may only write when it was the opener. */ - if (file->f_cred != current_real_cred()) + if (file->private_data != current->mm) return -EPERM; length = -ESRCH; @@ -2455,9 +2460,11 @@ out_no_task: } static const struct file_operations proc_pid_attr_operations = { + .open = proc_pid_attr_open, .read = proc_pid_attr_read, .write = proc_pid_attr_write, .llseek = generic_file_llseek, + .release = mem_release, }; static const struct pid_entry attr_dir_stuff[] = { -- cgit v1.2.3 From 39b6d3368d30048123d963543b64452c0ac63afb Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Sun, 30 May 2021 20:24:05 +0530 Subject: btrfs: return value from btrfs_mark_extent_written() in case of error commit e7b2ec3d3d4ebeb4cff7ae45cf430182fa6a49fb upstream. We always return 0 even in case of an error in btrfs_mark_extent_written(). Fix it to return proper error value in case of a failure. All callers handle it. CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Ritesh Harjani Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 73b547f88bfc..2426dc56426f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1089,7 +1089,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, int del_nr = 0; int del_slot = 0; int recow; - int ret; + int ret = 0; u64 ino = btrfs_ino(inode); path = btrfs_alloc_path(); @@ -1284,7 +1284,7 @@ again: } out: btrfs_free_path(path); - return 0; + return ret; } /* -- cgit v1.2.3 From fab8bfdfb4aac9e4e8363666333adfdf21e89106 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Jun 2021 15:37:53 +0300 Subject: NFS: Fix a potential NULL dereference in nfs_get_client() [ Upstream commit 09226e8303beeec10f2ff844d2e46d1371dc58e0 ] None of the callers are expecting NULL returns from nfs_get_client() so this code will lead to an Oops. It's better to return an error pointer. I expect that this is dead code so hopefully no one is affected. Fixes: 31434f496abb ("nfs: check hostname in nfs_get_client") Signed-off-by: Dan Carpenter Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/nfs/client.c b/fs/nfs/client.c index d6d5d2a48e83..ba2cd0bd3894 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -377,7 +377,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init, if (cl_init->hostname == NULL) { WARN_ON(1); - return NULL; + return ERR_PTR(-EINVAL); } dprintk("--> nfs_get_client(%s,v%u)\n", -- cgit v1.2.3 From 4ec682250dc20574792ba85f030fdbe6a0dd1af7 Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Wed, 19 May 2021 17:15:10 -0400 Subject: NFSv4: nfs4_proc_set_acl needs to restore NFS_CAP_UIDGID_NOMAP on error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f8849e206ef52b584cd9227255f4724f0cc900bb upstream. Currently if __nfs4_proc_set_acl fails with NFS4ERR_BADOWNER it re-enables the idmapper by clearing NFS_CAP_UIDGID_NOMAP before retrying again. The NFS_CAP_UIDGID_NOMAP remains cleared even if the retry fails. This causes problem for subsequent setattr requests for v4 server that does not have idmapping configured. This patch modifies nfs4_proc_set_acl to detect NFS4ERR_BADOWNER and NFS4ERR_BADNAME and skips the retry, since the kernel isn't involved in encoding the ACEs, and return -EINVAL. Steps to reproduce the problem: # mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt # touch /tmp/mnt/file1 # chown 99 /tmp/mnt/file1 # nfs4_setfacl -a A::unknown.user@xyz.com:wrtncy /tmp/mnt/file1 Failed setxattr operation: Invalid argument # chown 99 /tmp/mnt/file1 chown: changing ownership of ‘/tmp/mnt/file1’: Invalid argument # umount /tmp/mnt # mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt # chown 99 /tmp/mnt/file1 # v2: detect NFS4ERR_BADOWNER and NFS4ERR_BADNAME and skip retry in nfs4_proc_set_acl. Signed-off-by: Dai Ngo Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- fs/nfs/nfs4proc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'fs') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92ca753723b5..e10bada12361 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4887,6 +4887,14 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen do { err = __nfs4_proc_set_acl(inode, buf, buflen); trace_nfs4_set_acl(inode, err); + if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) { + /* + * no need to retry since the kernel + * isn't involved in encoding the ACEs. + */ + err = -EINVAL; + break; + } err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); } while (exception.retry); -- cgit v1.2.3 From 0646b0f9f31cce61823ef9fcdcee4a3b9c6117b8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Jun 2021 09:26:19 -0700 Subject: proc: only require mm_struct for writing commit 94f0b2d4a1d0c52035aef425da5e022bd2cb1c71 upstream. Commit 591a22c14d3f ("proc: Track /proc/$pid/attr/ opener mm_struct") we started using __mem_open() to track the mm_struct at open-time, so that we could then check it for writes. But that also ended up making the permission checks at open time much stricter - and not just for writes, but for reads too. And that in turn caused a regression for at least Fedora 29, where NIC interfaces fail to start when using NetworkManager. Since only the write side wanted the mm_struct test, ignore any failures by __mem_open() at open time, leaving reads unaffected. The write() time verification of the mm_struct pointer will then catch the failure case because a NULL pointer will not match a valid 'current->mm'. Link: https://lore.kernel.org/netdev/YMjTlp2FSJYvoyFa@unreal/ Fixes: 591a22c14d3f ("proc: Track /proc/$pid/attr/ opener mm_struct") Reported-and-tested-by: Leon Romanovsky Cc: Kees Cook Cc: Christian Brauner Cc: Andrea Righi Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/proc/base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index d2428d20d5a9..b1ff8eb61802 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2386,7 +2386,9 @@ out: #ifdef CONFIG_SECURITY static int proc_pid_attr_open(struct inode *inode, struct file *file) { - return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS); + file->private_data = NULL; + __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS); + return 0; } static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, -- cgit v1.2.3