aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/compat.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/fs/compat.c b/fs/compat.c
index a912bdf691cf..67c0b94d1148 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -31,6 +31,7 @@
31#include <linux/smb.h> 31#include <linux/smb.h>
32#include <linux/smb_mount.h> 32#include <linux/smb_mount.h>
33#include <linux/ncp_mount.h> 33#include <linux/ncp_mount.h>
34#include <linux/nfs4_mount.h>
34#include <linux/smp_lock.h> 35#include <linux/smp_lock.h>
35#include <linux/syscalls.h> 36#include <linux/syscalls.h>
36#include <linux/ctype.h> 37#include <linux/ctype.h>
@@ -806,10 +807,79 @@ static void *do_smb_super_data_conv(void *raw_data)
806 return raw_data; 807 return raw_data;
807} 808}
808 809
810struct compat_nfs_string {
811 compat_uint_t len;
812 compat_uptr_t __user data;
813};
814
815static inline void compat_nfs_string(struct nfs_string *dst,
816 struct compat_nfs_string *src)
817{
818 dst->data = compat_ptr(src->data);
819 dst->len = src->len;
820}
821
822struct compat_nfs4_mount_data_v1 {
823 compat_int_t version;
824 compat_int_t flags;
825 compat_int_t rsize;
826 compat_int_t wsize;
827 compat_int_t timeo;
828 compat_int_t retrans;
829 compat_int_t acregmin;
830 compat_int_t acregmax;
831 compat_int_t acdirmin;
832 compat_int_t acdirmax;
833 struct compat_nfs_string client_addr;
834 struct compat_nfs_string mnt_path;
835 struct compat_nfs_string hostname;
836 compat_uint_t host_addrlen;
837 compat_uptr_t __user host_addr;
838 compat_int_t proto;
839 compat_int_t auth_flavourlen;
840 compat_uptr_t __user auth_flavours;
841};
842
843static int do_nfs4_super_data_conv(void *raw_data)
844{
845 int version = *(compat_uint_t *) raw_data;
846
847 if (version == 1) {
848 struct compat_nfs4_mount_data_v1 *raw = raw_data;
849 struct nfs4_mount_data *real = raw_data;
850
851 /* copy the fields backwards */
852 real->auth_flavours = compat_ptr(raw->auth_flavours);
853 real->auth_flavourlen = raw->auth_flavourlen;
854 real->proto = raw->proto;
855 real->host_addr = compat_ptr(raw->host_addr);
856 real->host_addrlen = raw->host_addrlen;
857 compat_nfs_string(&real->hostname, &raw->hostname);
858 compat_nfs_string(&real->mnt_path, &raw->mnt_path);
859 compat_nfs_string(&real->client_addr, &raw->client_addr);
860 real->acdirmax = raw->acdirmax;
861 real->acdirmin = raw->acdirmin;
862 real->acregmax = raw->acregmax;
863 real->acregmin = raw->acregmin;
864 real->retrans = raw->retrans;
865 real->timeo = raw->timeo;
866 real->wsize = raw->wsize;
867 real->rsize = raw->rsize;
868 real->flags = raw->flags;
869 real->version = raw->version;
870 }
871 else {
872 return -EINVAL;
873 }
874
875 return 0;
876}
877
809extern int copy_mount_options (const void __user *, unsigned long *); 878extern int copy_mount_options (const void __user *, unsigned long *);
810 879
811#define SMBFS_NAME "smbfs" 880#define SMBFS_NAME "smbfs"
812#define NCPFS_NAME "ncpfs" 881#define NCPFS_NAME "ncpfs"
882#define NFS4_NAME "nfs4"
813 883
814asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, 884asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
815 char __user * type, unsigned long flags, 885 char __user * type, unsigned long flags,
@@ -845,6 +915,9 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
845 do_smb_super_data_conv((void *)data_page); 915 do_smb_super_data_conv((void *)data_page);
846 } else if (!strcmp((char *)type_page, NCPFS_NAME)) { 916 } else if (!strcmp((char *)type_page, NCPFS_NAME)) {
847 do_ncp_super_data_conv((void *)data_page); 917 do_ncp_super_data_conv((void *)data_page);
918 } else if (!strcmp((char *)type_page, NFS4_NAME)) {
919 if (do_nfs4_super_data_conv((void *) data_page))
920 goto out4;
848 } 921 }
849 } 922 }
850 923
@@ -853,6 +926,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
853 flags, (void*)data_page); 926 flags, (void*)data_page);
854 unlock_kernel(); 927 unlock_kernel();
855 928
929 out4:
856 free_page(data_page); 930 free_page(data_page);
857 out3: 931 out3:
858 free_page(dev_page); 932 free_page(dev_page);