X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fcompat.c;h=edc03610494206d595c4963deb6a53fbe2c641e5;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=b1f64786a613e598b5b5a06684f58d5cea8c0d5c;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/fs/compat.c b/fs/compat.c index b1f64786a..edc036104 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -114,7 +114,6 @@ asmlinkage long compat_sys_newlstat(char __user * filename, return error; } -#ifndef __ARCH_WANT_STAT64 asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, struct compat_stat __user *statbuf, int flag) { @@ -135,7 +134,6 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, out: return error; } -#endif asmlinkage long compat_sys_newfstat(unsigned int fd, struct compat_stat __user * statbuf) @@ -859,7 +857,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, retval = -EINVAL; - if (type_page) { + if (type_page && data_page) { if (!strcmp((char *)type_page, SMBFS_NAME)) { do_smb_super_data_conv((void *)data_page); } else if (!strcmp((char *)type_page, NCPFS_NAME)) { @@ -1317,26 +1315,6 @@ out: return ret; } -asmlinkage long -compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32, - unsigned int nr_segs, unsigned int flags) -{ - unsigned i; - struct iovec *iov; - if (nr_segs > UIO_MAXIOV) - return -EINVAL; - iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); - for (i = 0; i < nr_segs; i++) { - struct compat_iovec v; - if (get_user(v.iov_base, &iov32[i].iov_base) || - get_user(v.iov_len, &iov32[i].iov_len) || - put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || - put_user(v.iov_len, &iov[i].iov_len)) - return -EFAULT; - } - return sys_vmsplice(fd, iov, nr_segs, flags); -} - /* * Exactly like fs/open.c:sys_open(), except that it doesn't set the * O_LARGEFILE flag. @@ -1500,9 +1478,10 @@ int compat_do_execve(char * filename, int i; retval = -ENOMEM; - bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); + bprm = kmalloc(sizeof(*bprm), GFP_KERNEL); if (!bprm) goto out_ret; + memset(bprm, 0, sizeof(*bprm)); file = open_exec(filename); retval = PTR_ERR(file); @@ -1663,6 +1642,15 @@ void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, * This is a virtual copy of sys_select from fs/select.c and probably * should be compared to it from time to time */ +static void *select_bits_alloc(int size) +{ + return kmalloc(6 * size, GFP_KERNEL); +} + +static void select_bits_free(void *bits, int size) +{ + kfree(bits); +} /* * We can actually return ERESTARTSYS instead of EINTR, but I'd @@ -1701,7 +1689,7 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, */ ret = -ENOMEM; size = FDS_BYTES(n); - bits = kmalloc(6 * size, GFP_KERNEL); + bits = select_bits_alloc(size); if (!bits) goto out_nofds; fds.in = (unsigned long *) bits; @@ -1735,7 +1723,7 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, compat_set_fd_set(n, exp, fds.res_ex); out: - kfree(bits); + select_bits_free(bits, size); out_nofds: return ret; } @@ -2030,115 +2018,109 @@ union compat_nfsctl_res { struct knfsd_fh cr32_getfs; }; -static int compat_nfs_svc_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) +static int compat_nfs_svc_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) { - if (!access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)) || - get_user(karg->ca_version, &arg->ca32_version) || - __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port) || - __get_user(karg->ca_svc.svc_nthreads, - &arg->ca32_svc.svc32_nthreads)) - return -EFAULT; - return 0; + int err; + + err = access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port); + err |= __get_user(karg->ca_svc.svc_nthreads, &arg->ca32_svc.svc32_nthreads); + return (err) ? -EFAULT : 0; } -static int compat_nfs_clnt_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_client, - sizeof(arg->ca32_client)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_client.cl_ident[0], - &arg->ca32_client.cl32_ident[0], - NFSCLNT_IDMAX) || - __get_user(karg->ca_client.cl_naddr, - &arg->ca32_client.cl32_naddr) || - __copy_from_user(&karg->ca_client.cl_addrlist[0], - &arg->ca32_client.cl32_addrlist[0], - (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)) || - __get_user(karg->ca_client.cl_fhkeytype, - &arg->ca32_client.cl32_fhkeytype) || - __get_user(karg->ca_client.cl_fhkeylen, - &arg->ca32_client.cl32_fhkeylen) || - __copy_from_user(&karg->ca_client.cl_fhkey[0], - &arg->ca32_client.cl32_fhkey[0], - NFSCLNT_KEYMAX)) - return -EFAULT; +static int compat_nfs_clnt_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_client, sizeof(arg->ca32_client)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_client.cl_ident[0], + &arg->ca32_client.cl32_ident[0], + NFSCLNT_IDMAX); + err |= __get_user(karg->ca_client.cl_naddr, &arg->ca32_client.cl32_naddr); + err |= __copy_from_user(&karg->ca_client.cl_addrlist[0], + &arg->ca32_client.cl32_addrlist[0], + (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)); + err |= __get_user(karg->ca_client.cl_fhkeytype, + &arg->ca32_client.cl32_fhkeytype); + err |= __get_user(karg->ca_client.cl_fhkeylen, + &arg->ca32_client.cl32_fhkeylen); + err |= __copy_from_user(&karg->ca_client.cl_fhkey[0], + &arg->ca32_client.cl32_fhkey[0], + NFSCLNT_KEYMAX); + + return (err) ? -EFAULT : 0; } -static int compat_nfs_exp_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_export, - sizeof(arg->ca32_export)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_export.ex_client[0], - &arg->ca32_export.ex32_client[0], - NFSCLNT_IDMAX) || - __copy_from_user(&karg->ca_export.ex_path[0], - &arg->ca32_export.ex32_path[0], - NFS_MAXPATHLEN) || - __get_user(karg->ca_export.ex_dev, - &arg->ca32_export.ex32_dev) || - __get_user(karg->ca_export.ex_ino, - &arg->ca32_export.ex32_ino) || - __get_user(karg->ca_export.ex_flags, - &arg->ca32_export.ex32_flags) || - __get_user(karg->ca_export.ex_anon_uid, - &arg->ca32_export.ex32_anon_uid) || - __get_user(karg->ca_export.ex_anon_gid, - &arg->ca32_export.ex32_anon_gid)) - return -EFAULT; +static int compat_nfs_exp_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; + + err = access_ok(VERIFY_READ, &arg->ca32_export, sizeof(arg->ca32_export)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_export.ex_client[0], + &arg->ca32_export.ex32_client[0], + NFSCLNT_IDMAX); + err |= __copy_from_user(&karg->ca_export.ex_path[0], + &arg->ca32_export.ex32_path[0], + NFS_MAXPATHLEN); + err |= __get_user(karg->ca_export.ex_dev, + &arg->ca32_export.ex32_dev); + err |= __get_user(karg->ca_export.ex_ino, + &arg->ca32_export.ex32_ino); + err |= __get_user(karg->ca_export.ex_flags, + &arg->ca32_export.ex32_flags); + err |= __get_user(karg->ca_export.ex_anon_uid, + &arg->ca32_export.ex32_anon_uid); + err |= __get_user(karg->ca_export.ex_anon_gid, + &arg->ca32_export.ex32_anon_gid); SET_UID(karg->ca_export.ex_anon_uid, karg->ca_export.ex_anon_uid); SET_GID(karg->ca_export.ex_anon_gid, karg->ca_export.ex_anon_gid); - return 0; + return (err) ? -EFAULT : 0; } -static int compat_nfs_getfd_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) -{ - if (!access_ok(VERIFY_READ, &arg->ca32_getfd, - sizeof(arg->ca32_getfd)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_getfd.gd_addr, - &arg->ca32_getfd.gd32_addr, - (sizeof(struct sockaddr))) || - __copy_from_user(&karg->ca_getfd.gd_path, - &arg->ca32_getfd.gd32_path, - (NFS_MAXPATHLEN+1)) || - __get_user(karg->ca_getfd.gd_version, - &arg->ca32_getfd.gd32_version)) - return -EFAULT; +static int compat_nfs_getfd_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) +{ + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_getfd, sizeof(arg->ca32_getfd)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_getfd.gd_addr, + &arg->ca32_getfd.gd32_addr, + (sizeof(struct sockaddr))); + err |= __copy_from_user(&karg->ca_getfd.gd_path, + &arg->ca32_getfd.gd32_path, + (NFS_MAXPATHLEN+1)); + err |= __get_user(karg->ca_getfd.gd_version, + &arg->ca32_getfd.gd32_version); + + return (err) ? -EFAULT : 0; } -static int compat_nfs_getfs_trans(struct nfsctl_arg *karg, - struct compat_nfsctl_arg __user *arg) +static int compat_nfs_getfs_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg) { - if (!access_ok(VERIFY_READ,&arg->ca32_getfs,sizeof(arg->ca32_getfs)) || - get_user(karg->ca_version, &arg->ca32_version) || - __copy_from_user(&karg->ca_getfs.gd_addr, - &arg->ca32_getfs.gd32_addr, - (sizeof(struct sockaddr))) || - __copy_from_user(&karg->ca_getfs.gd_path, - &arg->ca32_getfs.gd32_path, - (NFS_MAXPATHLEN+1)) || - __get_user(karg->ca_getfs.gd_maxlen, - &arg->ca32_getfs.gd32_maxlen)) - return -EFAULT; + int err; - return 0; + err = access_ok(VERIFY_READ, &arg->ca32_getfs, sizeof(arg->ca32_getfs)); + err |= get_user(karg->ca_version, &arg->ca32_version); + err |= __copy_from_user(&karg->ca_getfs.gd_addr, + &arg->ca32_getfs.gd32_addr, + (sizeof(struct sockaddr))); + err |= __copy_from_user(&karg->ca_getfs.gd_path, + &arg->ca32_getfs.gd32_path, + (NFS_MAXPATHLEN+1)); + err |= __get_user(karg->ca_getfs.gd_maxlen, + &arg->ca32_getfs.gd32_maxlen); + + return (err) ? -EFAULT : 0; } /* This really doesn't need translations, we are only passing * back a union which contains opaque nfs file handle data. */ -static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, - union compat_nfsctl_res __user *res) +static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, union compat_nfsctl_res __user *res) { int err; @@ -2147,9 +2129,8 @@ static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, return (err) ? -EFAULT : 0; } -asmlinkage long compat_sys_nfsservctl(int cmd, - struct compat_nfsctl_arg __user *arg, - union compat_nfsctl_res __user *res) +asmlinkage long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg, + union compat_nfsctl_res __user *res) { struct nfsctl_arg *karg; union nfsctl_res *kres; @@ -2191,11 +2172,8 @@ asmlinkage long compat_sys_nfsservctl(int cmd, default: err = -EINVAL; - break; - } - - if (err) goto done; + } oldfs = get_fs(); set_fs(KERNEL_DS);