Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fget updates from Al Viro:
"fget() to fdget() conversions"

* tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fuse_dev_ioctl(): switch to fdget()
cgroup_get_from_fd(): switch to fdget_raw()
bpf: switch to fdget_raw()
build_mount_idmapped(): switch to fdget()
kill the last remaining user of proc_ns_fget()
SVM-SEV: convert the rest of fget() uses to fdget() in there
convert sgx_set_attribute() to fdget()/fdput()
convert setns(2) to fdget()/fdput()

+82 -111
+5 -6
arch/x86/kernel/cpu/sgx/main.c
··· 892 892 int sgx_set_attribute(unsigned long *allowed_attributes, 893 893 unsigned int attribute_fd) 894 894 { 895 - struct file *file; 895 + struct fd f = fdget(attribute_fd); 896 896 897 - file = fget(attribute_fd); 898 - if (!file) 897 + if (!f.file) 899 898 return -EINVAL; 900 899 901 - if (file->f_op != &sgx_provision_fops) { 902 - fput(file); 900 + if (f.file->f_op != &sgx_provision_fops) { 901 + fdput(f); 903 902 return -EINVAL; 904 903 } 905 904 906 905 *allowed_attributes |= SGX_ATTR_PROVISIONKEY; 907 906 908 - fput(file); 907 + fdput(f); 909 908 return 0; 910 909 } 911 910 EXPORT_SYMBOL_GPL(sgx_set_attribute);
+14 -12
arch/x86/kvm/svm/sev.c
··· 1767 1767 { 1768 1768 struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info; 1769 1769 struct kvm_sev_info *src_sev, *cg_cleanup_sev; 1770 - struct file *source_kvm_file; 1770 + struct fd f = fdget(source_fd); 1771 1771 struct kvm *source_kvm; 1772 1772 bool charged = false; 1773 1773 int ret; 1774 1774 1775 - source_kvm_file = fget(source_fd); 1776 - if (!file_is_kvm(source_kvm_file)) { 1775 + if (!f.file) 1776 + return -EBADF; 1777 + 1778 + if (!file_is_kvm(f.file)) { 1777 1779 ret = -EBADF; 1778 1780 goto out_fput; 1779 1781 } 1780 1782 1781 - source_kvm = source_kvm_file->private_data; 1783 + source_kvm = f.file->private_data; 1782 1784 ret = sev_lock_two_vms(kvm, source_kvm); 1783 1785 if (ret) 1784 1786 goto out_fput; ··· 1830 1828 out_unlock: 1831 1829 sev_unlock_two_vms(kvm, source_kvm); 1832 1830 out_fput: 1833 - if (source_kvm_file) 1834 - fput(source_kvm_file); 1831 + fdput(f); 1835 1832 return ret; 1836 1833 } 1837 1834 ··· 2047 2046 2048 2047 int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd) 2049 2048 { 2050 - struct file *source_kvm_file; 2049 + struct fd f = fdget(source_fd); 2051 2050 struct kvm *source_kvm; 2052 2051 struct kvm_sev_info *source_sev, *mirror_sev; 2053 2052 int ret; 2054 2053 2055 - source_kvm_file = fget(source_fd); 2056 - if (!file_is_kvm(source_kvm_file)) { 2054 + if (!f.file) 2055 + return -EBADF; 2056 + 2057 + if (!file_is_kvm(f.file)) { 2057 2058 ret = -EBADF; 2058 2059 goto e_source_fput; 2059 2060 } 2060 2061 2061 - source_kvm = source_kvm_file->private_data; 2062 + source_kvm = f.file->private_data; 2062 2063 ret = sev_lock_two_vms(kvm, source_kvm); 2063 2064 if (ret) 2064 2065 goto e_source_fput; ··· 2106 2103 e_unlock: 2107 2104 sev_unlock_two_vms(kvm, source_kvm); 2108 2105 e_source_fput: 2109 - if (source_kvm_file) 2110 - fput(source_kvm_file); 2106 + fdput(f); 2111 2107 return ret; 2112 2108 } 2113 2109
+19 -18
fs/fuse/dev.c
··· 2257 2257 int res; 2258 2258 int oldfd; 2259 2259 struct fuse_dev *fud = NULL; 2260 + struct fd f; 2260 2261 2261 2262 switch (cmd) { 2262 2263 case FUSE_DEV_IOC_CLONE: 2263 - res = -EFAULT; 2264 - if (!get_user(oldfd, (__u32 __user *)arg)) { 2265 - struct file *old = fget(oldfd); 2264 + if (get_user(oldfd, (__u32 __user *)arg)) 2265 + return -EFAULT; 2266 2266 2267 - res = -EINVAL; 2268 - if (old) { 2269 - /* 2270 - * Check against file->f_op because CUSE 2271 - * uses the same ioctl handler. 2272 - */ 2273 - if (old->f_op == file->f_op) 2274 - fud = fuse_get_dev(old); 2267 + f = fdget(oldfd); 2268 + if (!f.file) 2269 + return -EINVAL; 2275 2270 2276 - if (fud) { 2277 - mutex_lock(&fuse_mutex); 2278 - res = fuse_device_clone(fud->fc, file); 2279 - mutex_unlock(&fuse_mutex); 2280 - } 2281 - fput(old); 2282 - } 2271 + /* 2272 + * Check against file->f_op because CUSE 2273 + * uses the same ioctl handler. 2274 + */ 2275 + if (f.file->f_op == file->f_op) 2276 + fud = fuse_get_dev(f.file); 2277 + 2278 + res = -EINVAL; 2279 + if (fud) { 2280 + mutex_lock(&fuse_mutex); 2281 + res = fuse_device_clone(fud->fc, file); 2282 + mutex_unlock(&fuse_mutex); 2283 2283 } 2284 + fdput(f); 2284 2285 break; 2285 2286 default: 2286 2287 res = -ENOTTY;
+6 -6
fs/namespace.c
··· 4194 4194 int err = 0; 4195 4195 struct ns_common *ns; 4196 4196 struct user_namespace *mnt_userns; 4197 - struct file *file; 4197 + struct fd f; 4198 4198 4199 4199 if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP)) 4200 4200 return 0; ··· 4210 4210 if (attr->userns_fd > INT_MAX) 4211 4211 return -EINVAL; 4212 4212 4213 - file = fget(attr->userns_fd); 4214 - if (!file) 4213 + f = fdget(attr->userns_fd); 4214 + if (!f.file) 4215 4215 return -EBADF; 4216 4216 4217 - if (!proc_ns_file(file)) { 4217 + if (!proc_ns_file(f.file)) { 4218 4218 err = -EINVAL; 4219 4219 goto out_fput; 4220 4220 } 4221 4221 4222 - ns = get_proc_ns(file_inode(file)); 4222 + ns = get_proc_ns(file_inode(f.file)); 4223 4223 if (ns->ops->type != CLONE_NEWUSER) { 4224 4224 err = -EINVAL; 4225 4225 goto out_fput; ··· 4248 4248 kattr->mnt_userns = get_user_ns(mnt_userns); 4249 4249 4250 4250 out_fput: 4251 - fput(file); 4251 + fdput(f); 4252 4252 return err; 4253 4253 } 4254 4254
-18
fs/nsfs.c
··· 235 235 return file->f_op == &ns_file_operations; 236 236 } 237 237 238 - struct file *proc_ns_fget(int fd) 239 - { 240 - struct file *file; 241 - 242 - file = fget(fd); 243 - if (!file) 244 - return ERR_PTR(-EBADF); 245 - 246 - if (file->f_op != &ns_file_operations) 247 - goto out_invalid; 248 - 249 - return file; 250 - 251 - out_invalid: 252 - fput(file); 253 - return ERR_PTR(-EINVAL); 254 - } 255 - 256 238 /** 257 239 * ns_match() - Returns true if current namespace matches dev/ino provided. 258 240 * @ns: current namespace
-1
include/linux/proc_ns.h
··· 72 72 73 73 #define ns_free_inum(ns) proc_free_inum((ns)->inum) 74 74 75 - extern struct file *proc_ns_fget(int fd); 76 75 #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private) 77 76 extern int ns_get_path(struct path *path, struct task_struct *task, 78 77 const struct proc_ns_operations *ns_ops);
+15 -23
kernel/bpf/bpf_inode_storage.c
··· 84 84 static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key) 85 85 { 86 86 struct bpf_local_storage_data *sdata; 87 - struct file *f; 88 - int fd; 87 + struct fd f = fdget_raw(*(int *)key); 89 88 90 - fd = *(int *)key; 91 - f = fget_raw(fd); 92 - if (!f) 89 + if (!f.file) 93 90 return ERR_PTR(-EBADF); 94 91 95 - sdata = inode_storage_lookup(f->f_inode, map, true); 96 - fput(f); 92 + sdata = inode_storage_lookup(file_inode(f.file), map, true); 93 + fdput(f); 97 94 return sdata ? sdata->data : NULL; 98 95 } 99 96 ··· 98 101 void *value, u64 map_flags) 99 102 { 100 103 struct bpf_local_storage_data *sdata; 101 - struct file *f; 102 - int fd; 104 + struct fd f = fdget_raw(*(int *)key); 103 105 104 - fd = *(int *)key; 105 - f = fget_raw(fd); 106 - if (!f) 106 + if (!f.file) 107 107 return -EBADF; 108 - if (!inode_storage_ptr(f->f_inode)) { 109 - fput(f); 108 + if (!inode_storage_ptr(file_inode(f.file))) { 109 + fdput(f); 110 110 return -EBADF; 111 111 } 112 112 113 - sdata = bpf_local_storage_update(f->f_inode, 113 + sdata = bpf_local_storage_update(file_inode(f.file), 114 114 (struct bpf_local_storage_map *)map, 115 115 value, map_flags, GFP_ATOMIC); 116 - fput(f); 116 + fdput(f); 117 117 return PTR_ERR_OR_ZERO(sdata); 118 118 } 119 119 ··· 129 135 130 136 static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key) 131 137 { 132 - struct file *f; 133 - int fd, err; 138 + struct fd f = fdget_raw(*(int *)key); 139 + int err; 134 140 135 - fd = *(int *)key; 136 - f = fget_raw(fd); 137 - if (!f) 141 + if (!f.file) 138 142 return -EBADF; 139 143 140 - err = inode_storage_delete(f->f_inode, map); 141 - fput(f); 144 + err = inode_storage_delete(file_inode(f.file), map); 145 + fdput(f); 142 146 return err; 143 147 } 144 148
+4 -6
kernel/cgroup/cgroup.c
··· 6856 6856 struct cgroup *cgroup_v1v2_get_from_fd(int fd) 6857 6857 { 6858 6858 struct cgroup *cgrp; 6859 - struct file *f; 6860 - 6861 - f = fget_raw(fd); 6862 - if (!f) 6859 + struct fd f = fdget_raw(fd); 6860 + if (!f.file) 6863 6861 return ERR_PTR(-EBADF); 6864 6862 6865 - cgrp = cgroup_v1v2_get_from_file(f); 6866 - fput(f); 6863 + cgrp = cgroup_v1v2_get_from_file(f.file); 6864 + fdput(f); 6867 6865 return cgrp; 6868 6866 } 6869 6867
+8 -9
kernel/nsproxy.c
··· 545 545 546 546 SYSCALL_DEFINE2(setns, int, fd, int, flags) 547 547 { 548 - struct file *file; 548 + struct fd f = fdget(fd); 549 549 struct ns_common *ns = NULL; 550 550 struct nsset nsset = {}; 551 551 int err = 0; 552 552 553 - file = fget(fd); 554 - if (!file) 553 + if (!f.file) 555 554 return -EBADF; 556 555 557 - if (proc_ns_file(file)) { 558 - ns = get_proc_ns(file_inode(file)); 556 + if (proc_ns_file(f.file)) { 557 + ns = get_proc_ns(file_inode(f.file)); 559 558 if (flags && (ns->ops->type != flags)) 560 559 err = -EINVAL; 561 560 flags = ns->ops->type; 562 - } else if (!IS_ERR(pidfd_pid(file))) { 561 + } else if (!IS_ERR(pidfd_pid(f.file))) { 563 562 err = check_setns_flags(flags); 564 563 } else { 565 564 err = -EINVAL; ··· 570 571 if (err) 571 572 goto out; 572 573 573 - if (proc_ns_file(file)) 574 + if (proc_ns_file(f.file)) 574 575 err = validate_ns(&nsset, ns); 575 576 else 576 - err = validate_nsset(&nsset, file->private_data); 577 + err = validate_nsset(&nsset, f.file->private_data); 577 578 if (!err) { 578 579 commit_nsset(&nsset); 579 580 perf_event_namespaces(current); 580 581 } 581 582 put_nsset(&nsset); 582 583 out: 583 - fput(file); 584 + fdput(f); 584 585 return err; 585 586 } 586 587
+11 -12
net/core/net_namespace.c
··· 20 20 #include <linux/sched/task.h> 21 21 #include <linux/uidgid.h> 22 22 #include <linux/cookie.h> 23 + #include <linux/proc_fs.h> 23 24 24 25 #include <net/sock.h> 25 26 #include <net/netlink.h> ··· 677 676 678 677 struct net *get_net_ns_by_fd(int fd) 679 678 { 680 - struct file *file; 681 - struct ns_common *ns; 682 - struct net *net; 679 + struct fd f = fdget(fd); 680 + struct net *net = ERR_PTR(-EINVAL); 683 681 684 - file = proc_ns_fget(fd); 685 - if (IS_ERR(file)) 686 - return ERR_CAST(file); 682 + if (!f.file) 683 + return ERR_PTR(-EBADF); 687 684 688 - ns = get_proc_ns(file_inode(file)); 689 - if (ns->ops == &netns_operations) 690 - net = get_net(container_of(ns, struct net, ns)); 691 - else 692 - net = ERR_PTR(-EINVAL); 685 + if (proc_ns_file(f.file)) { 686 + struct ns_common *ns = get_proc_ns(file_inode(f.file)); 687 + if (ns->ops == &netns_operations) 688 + net = get_net(container_of(ns, struct net, ns)); 689 + } 690 + fdput(f); 693 691 694 - fput(file); 695 692 return net; 696 693 } 697 694 EXPORT_SYMBOL_GPL(get_net_ns_by_fd);