#include <linux/smb.h>
#include <linux/smb_mount.h>
#include <linux/ncp_mount.h>
+#include <linux/nfs4_mount.h>
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/ctype.h>
&& (kbuf->f_ffree & 0xffffffff00000000ULL))
return -EOVERFLOW;
}
- if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
+ if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
__put_user(kbuf->f_type, &ubuf->f_type) ||
__put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
__put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
&& (kbuf->f_ffree & 0xffffffff00000000ULL))
return -EOVERFLOW;
}
- if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
+ if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
__put_user(kbuf->f_type, &ubuf->f_type) ||
__put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
__put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
return raw_data;
}
+struct compat_nfs_string {
+ compat_uint_t len;
+ compat_uptr_t data;
+};
+
+static inline void compat_nfs_string(struct nfs_string *dst,
+ struct compat_nfs_string *src)
+{
+ dst->data = compat_ptr(src->data);
+ dst->len = src->len;
+}
+
+struct compat_nfs4_mount_data_v1 {
+ compat_int_t version;
+ compat_int_t flags;
+ compat_int_t rsize;
+ compat_int_t wsize;
+ compat_int_t timeo;
+ compat_int_t retrans;
+ compat_int_t acregmin;
+ compat_int_t acregmax;
+ compat_int_t acdirmin;
+ compat_int_t acdirmax;
+ struct compat_nfs_string client_addr;
+ struct compat_nfs_string mnt_path;
+ struct compat_nfs_string hostname;
+ compat_uint_t host_addrlen;
+ compat_uptr_t host_addr;
+ compat_int_t proto;
+ compat_int_t auth_flavourlen;
+ compat_uptr_t auth_flavours;
+};
+
+static int do_nfs4_super_data_conv(void *raw_data)
+{
+ int version = *(compat_uint_t *) raw_data;
+
+ if (version == 1) {
+ struct compat_nfs4_mount_data_v1 *raw = raw_data;
+ struct nfs4_mount_data *real = raw_data;
+
+ /* copy the fields backwards */
+ real->auth_flavours = compat_ptr(raw->auth_flavours);
+ real->auth_flavourlen = raw->auth_flavourlen;
+ real->proto = raw->proto;
+ real->host_addr = compat_ptr(raw->host_addr);
+ real->host_addrlen = raw->host_addrlen;
+ compat_nfs_string(&real->hostname, &raw->hostname);
+ compat_nfs_string(&real->mnt_path, &raw->mnt_path);
+ compat_nfs_string(&real->client_addr, &raw->client_addr);
+ real->acdirmax = raw->acdirmax;
+ real->acdirmin = raw->acdirmin;
+ real->acregmax = raw->acregmax;
+ real->acregmin = raw->acregmin;
+ real->retrans = raw->retrans;
+ real->timeo = raw->timeo;
+ real->wsize = raw->wsize;
+ real->rsize = raw->rsize;
+ real->flags = raw->flags;
+ real->version = raw->version;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
extern int copy_mount_options (const void __user *, unsigned long *);
#define SMBFS_NAME "smbfs"
#define NCPFS_NAME "ncpfs"
+#define NFS4_NAME "nfs4"
asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
char __user * type, unsigned long flags,
do_smb_super_data_conv((void *)data_page);
} else if (!strcmp((char *)type_page, NCPFS_NAME)) {
do_ncp_super_data_conv((void *)data_page);
+ } else if (!strcmp((char *)type_page, NFS4_NAME)) {
+ if (do_nfs4_super_data_conv((void *) data_page))
+ goto out4;
}
}
flags, (void*)data_page);
unlock_kernel();
+ out4:
free_page(data_page);
out3:
free_page(dev_page);
goto out;
}
ret = -EFAULT;
- if (verify_area(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+ if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
goto out;
/*
if (ufdset) {
unsigned long odd;
- if (verify_area(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
+ if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
return -EFAULT;
odd = nr & 1UL;
fd_set_bits fds;
char *bits;
long timeout;
- int ret, size, max_fdset;
+ int size, max_fdset, ret = -EINVAL;
timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
time_t sec, usec;
- if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
- || (ret = __get_user(sec, &tvp->tv_sec))
- || (ret = __get_user(usec, &tvp->tv_usec)))
+ if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
+ || __get_user(sec, &tvp->tv_sec)
+ || __get_user(usec, &tvp->tv_usec)) {
+ ret = -EFAULT;
goto out_nofds;
+ }
- ret = -EINVAL;
if (sec < 0 || usec < 0)
goto out_nofds;
}
}
- ret = -EINVAL;
if (n < 0)
goto out_nofds;