diff options
-rw-r--r-- | fs/compat.c | 74 |
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 | ||
810 | struct compat_nfs_string { | ||
811 | compat_uint_t len; | ||
812 | compat_uptr_t __user data; | ||
813 | }; | ||
814 | |||
815 | static 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 | |||
822 | struct 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 | |||
843 | static 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 | |||
809 | extern int copy_mount_options (const void __user *, unsigned long *); | 878 | extern 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 | ||
814 | asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | 884 | asmlinkage 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); |