]> git.hungrycats.org Git - linux/commitdiff
[PATCH] consolidate compat_sys_mount
authorMatthew Wilcox <willy@debian.org>
Sat, 27 Mar 2004 05:42:42 +0000 (21:42 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 27 Mar 2004 05:42:42 +0000 (21:42 -0800)
This replaces six duplicated implementations of various quality of
sys32_mount with a shiny new compat_sys_mount().

It's been tested on parisc64 and sparc64 and fixes a bug exposed by the
latest revision of Debian's initscripts.  Thanks to Arnd Bergmann and
Dave Miller for their suggestions, fixes and testing.  Please apply.

15 files changed:
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/sys_ia32.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall_table.S
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/sys_ppc32.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/x86_64/ia32/ia32entry.S
arch/x86_64/ia32/sys_ia32.c
fs/compat.c
fs/namespace.c
include/net/scm.h

index 91166d4ffecbab45ec62e922f3754ce448361371..89e3191d615c2dc15d68caa9c8e6df85e54638fd 100644 (file)
@@ -229,7 +229,7 @@ ia32_syscall_table:
        data8 sys_ni_syscall
        data8 sys32_lseek
        data8 sys_getpid          /* 20 */
-       data8 sys_mount
+       data8 compat_sys_mount
        data8 sys_oldumount
        data8 sys_setuid        /* 16-bit version */
        data8 sys_getuid        /* 16-bit version */
index bd539f25da827afc4771e712c8c22ce33ed7113a..38aaf7b08bbdef48a5e7bfcb79d578115f6bf8e8 100644 (file)
@@ -34,9 +34,6 @@
 #include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
 #include <linux/quota.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -2384,157 +2381,6 @@ long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
 
 #ifdef NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
 
-struct ncp_mount_data32 {
-       int version;
-       unsigned int ncp_fd;
-       compat_uid_t mounted_uid;
-       int wdog_pid;
-       unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-       unsigned int time_out;
-       unsigned int retry_count;
-       unsigned int flags;
-       compat_uid_t uid;
-       compat_gid_t gid;
-       compat_mode_t file_mode;
-       compat_mode_t dir_mode;
-};
-
-static void *
-do_ncp_super_data_conv(void *raw_data)
-{
-       struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
-       struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
-
-       n->dir_mode = n32->dir_mode;
-       n->file_mode = n32->file_mode;
-       n->gid = n32->gid;
-       n->uid = n32->uid;
-       memmove (n->mounted_vol, n32->mounted_vol,
-                (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
-       n->wdog_pid = n32->wdog_pid;
-       n->mounted_uid = n32->mounted_uid;
-       return raw_data;
-}
-
-struct smb_mount_data32 {
-       int version;
-       compat_uid_t mounted_uid;
-       compat_uid_t uid;
-       compat_gid_t gid;
-       compat_mode_t file_mode;
-       compat_mode_t dir_mode;
-};
-
-static void *
-do_smb_super_data_conv(void *raw_data)
-{
-       struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
-       struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
-
-       if (s32->version != SMB_MOUNT_OLDVERSION)
-               goto out;
-       s->version = s32->version;
-       s->mounted_uid = s32->mounted_uid;
-       s->uid = s32->uid;
-       s->gid = s32->gid;
-       s->file_mode = s32->file_mode;
-       s->dir_mode = s32->dir_mode;
-out:
-       return raw_data;
-}
-
-static int
-copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
-{
-       int i;
-       unsigned long page;
-       struct vm_area_struct *vma;
-
-       *kernel = 0;
-       if(!user)
-               return 0;
-       vma = find_vma(current->mm, (unsigned long)user);
-       if(!vma || (unsigned long)user < vma->vm_start)
-               return -EFAULT;
-       if(!(vma->vm_flags & VM_READ))
-               return -EFAULT;
-       i = vma->vm_end - (unsigned long) user;
-       if(PAGE_SIZE <= (unsigned long) i)
-               i = PAGE_SIZE - 1;
-       if(!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-       if(copy_from_user((void *) page, user, i)) {
-               free_page(page);
-               return -EFAULT;
-       }
-       *kernel = page;
-       return 0;
-}
-
-#define SMBFS_NAME     "smbfs"
-#define NCPFS_NAME     "ncpfs"
-
-asmlinkage long
-sys32_mount(char *dev_name, char *dir_name, char *type,
-           unsigned long new_flags, u32 data)
-{
-       unsigned long type_page;
-       int err, is_smb, is_ncp;
-
-       if(!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       is_smb = is_ncp = 0;
-       err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
-       if(err)
-               return err;
-       if(type_page) {
-               is_smb = !strcmp((char *)type_page, SMBFS_NAME);
-               is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
-       }
-       if(!is_smb && !is_ncp) {
-               if(type_page)
-                       free_page(type_page);
-               return sys_mount(dev_name, dir_name, type, new_flags,
-                                (void *)AA(data));
-       } else {
-               unsigned long dev_page, dir_page, data_page;
-
-               err = copy_mount_stuff_to_kernel((const void *)dev_name,
-                                                &dev_page);
-               if(err)
-                       goto out;
-               err = copy_mount_stuff_to_kernel((const void *)dir_name,
-                                                &dir_page);
-               if(err)
-                       goto dev_out;
-               err = copy_mount_stuff_to_kernel((const void *)AA(data),
-                                                &data_page);
-               if(err)
-                       goto dir_out;
-               if(is_ncp)
-                       do_ncp_super_data_conv((void *)data_page);
-               else if(is_smb)
-                       do_smb_super_data_conv((void *)data_page);
-               else
-                       panic("The problem is here...");
-               err = do_mount((char *)dev_page, (char *)dir_page,
-                               (char *)type_page, new_flags,
-                               (void *)data_page);
-               if(data_page)
-                       free_page(data_page);
-       dir_out:
-               if(dir_page)
-                       free_page(dir_page);
-       dev_out:
-               if(dev_page)
-                       free_page(dev_page);
-       out:
-               if(type_page)
-                       free_page(type_page);
-               return err;
-       }
-}
-
 asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
 {
        uid_t sruid, seuid;
index ce80f35e79ceb53fe602729e8014041071fa4163..d59c93baf0c2ff1cde57deffb0dd9e913b4a2255 100644 (file)
@@ -607,105 +607,6 @@ out:
        return error;
 }
 
-static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
-{
-       int i;
-       unsigned long page;
-       struct vm_area_struct *vma;
-
-       *kernel = 0;
-       if(!user)
-               return 0;
-       vma = find_vma(current->mm, (unsigned long)user);
-       if(!vma || (unsigned long)user < vma->vm_start)
-               return -EFAULT;
-       if(!(vma->vm_flags & VM_READ))
-               return -EFAULT;
-       i = vma->vm_end - (unsigned long) user;
-       if(PAGE_SIZE <= (unsigned long) i)
-               i = PAGE_SIZE - 1;
-       if(!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-       if(copy_from_user((void *) page, user, i)) {
-               free_page(page);
-               return -EFAULT;
-       }
-       *kernel = page;
-       return 0;
-}
-
-#define SMBFS_NAME     "smbfs"
-#define NCPFS_NAME     "ncpfs"
-
-asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
-{
-       unsigned long type_page = 0;
-       unsigned long data_page = 0;
-       unsigned long dev_page = 0;
-       unsigned long dir_page = 0;
-       int err, is_smb, is_ncp;
-
-       is_smb = is_ncp = 0;
-
-       err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
-       if (err)
-               goto out;
-
-       if (!type_page) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       is_smb = !strcmp((char *)type_page, SMBFS_NAME);
-       is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
-
-       err = copy_mount_stuff_to_kernel((const void *)(unsigned long)data, &data_page);
-       if (err)
-               goto type_out;
-
-       err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
-       if (err)
-               goto data_out;
-
-       err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
-       if (err)
-               goto dev_out;
-
-       if (!is_smb && !is_ncp) {
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       } else {
-               if (is_ncp)
-                       panic("NCP mounts not yet supported 32/64 parisc");
-                       /* do_ncp_super_data_conv((void *)data_page); */
-               else {
-                       panic("SMB mounts not yet supported 32/64 parisc");
-                       /* do_smb_super_data_conv((void *)data_page); */
-               }
-
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       }
-       free_page(dir_page);
-
-dev_out:
-       free_page(dev_page);
-
-data_out:
-       free_page(data_page);
-
-type_out:
-       free_page(type_page);
-
-out:
-       return err;
-}
-
-
 /* readv/writev stolen from mips64 */
 typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
 
index e418c25e1f494f4e0b527ea1a951ede68e139178..ce47ee803880b943c6ce42eb5d83a3bb2a4cc05c 100644 (file)
@@ -84,7 +84,7 @@
        ENTRY_DIFF(lseek)
        ENTRY_SAME(getpid)              /* 20 */
        /* the 'void * data' parameter may need re-packing in wide */
-       ENTRY_DIFF(mount)
+       ENTRY_COMP(mount)
        /* concerned about struct sockaddr in wide/narrow */
        /* ---> I think sockaddr is OK unless the compiler packs the struct */
        /*      differently to align the char array */
index 30de22c1188c652266cfefdbb1bc56e73e2f627c..a9a0a9953f7d55a235a00fdfaeff3d6c7b16cc91 100644 (file)
@@ -593,7 +593,7 @@ _GLOBAL(sys_call_table32)
        .llong .sys_ni_syscall          /* old stat syscall */
        .llong .ppc32_lseek
        .llong .sys_getpid              /* 20 */
-       .llong .sys32_mount
+       .llong .compat_sys_mount
        .llong .sys_oldumount
        .llong .sys_setuid
        .llong .sys_getuid
index b19b657831dce78b46e29705620259ade28cd191..836929859649b3c4e68e534db11e1b5b67d5b67b 100644 (file)
@@ -35,9 +35,6 @@
 #include <linux/uio.h>
 #include <linux/aio.h>
 #include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
 #include <linux/module.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -253,209 +250,6 @@ out:
        return ret;
 }
 
-struct ncp_mount_data32_v3 {
-        int version;
-        unsigned int ncp_fd;
-        compat_uid_t mounted_uid;
-        compat_pid_t wdog_pid;
-        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-        unsigned int time_out;
-        unsigned int retry_count;
-        unsigned int flags;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-struct ncp_mount_data32_v4 {
-       int version;
-       /* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
-       unsigned int flags;
-       unsigned int mounted_uid;
-       int wdog_pid;
-
-       unsigned int ncp_fd;
-       unsigned int time_out;
-       unsigned int retry_count;
-
-       unsigned int uid;
-       unsigned int gid;
-       unsigned int file_mode;
-       unsigned int dir_mode;
-};
-
-static void *do_ncp_super_data_conv(void *raw_data)
-{
-       switch (*(int*)raw_data) {
-               case NCP_MOUNT_VERSION:
-                       {
-                               struct ncp_mount_data news, *n = &news; 
-                               struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
-
-                               n->version = n32->version;
-                               n->ncp_fd = n32->ncp_fd;
-                               n->mounted_uid = n32->mounted_uid;
-                               n->wdog_pid = n32->wdog_pid;
-                               memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
-                               n->time_out = n32->time_out;
-                               n->retry_count = n32->retry_count;
-                               n->flags = n32->flags;
-                               n->uid = n32->uid;
-                               n->gid = n32->gid;
-                               n->file_mode = n32->file_mode;
-                               n->dir_mode = n32->dir_mode;
-                               memcpy(raw_data, n, sizeof(*n)); 
-                       }
-                       break;
-               case NCP_MOUNT_VERSION_V4:
-                       {
-                               struct ncp_mount_data_v4 news, *n = &news; 
-                               struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
-
-                               n->version = n32->version;
-                               n->flags = n32->flags;
-                               n->mounted_uid = n32->mounted_uid;
-                               n->wdog_pid = n32->wdog_pid;
-                               n->ncp_fd = n32->ncp_fd;
-                               n->time_out = n32->time_out;
-                               n->retry_count = n32->retry_count;
-                               n->uid = n32->uid;
-                               n->gid = n32->gid;
-                               n->file_mode = n32->file_mode;
-                               n->dir_mode = n32->dir_mode;
-                               memcpy(raw_data, n, sizeof(*n)); 
-                       }
-                       break;
-               default:
-                       /* do not touch unknown structures */
-                       break;
-       }
-       return raw_data;
-}
-
-struct smb_mount_data32 {
-        int version;
-        compat_uid_t mounted_uid;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-static void *do_smb_super_data_conv(void *raw_data)
-{
-       struct smb_mount_data news, *s = &news;
-       struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
-
-       if (s32->version != SMB_MOUNT_OLDVERSION)
-               goto out;
-       s->version = s32->version;
-       s->mounted_uid = s32->mounted_uid;
-       s->uid = s32->uid;
-       s->gid = s32->gid;
-       s->file_mode = s32->file_mode;
-       s->dir_mode = s32->dir_mode;
-       memcpy(raw_data, s, sizeof(struct smb_mount_data)); 
-out:
-       return raw_data;
-}
-
-static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
-{
-       int i;
-       unsigned long page;
-       struct vm_area_struct *vma;
-
-       *kernel = 0;
-       if(!user)
-               return 0;
-       vma = find_vma(current->mm, (unsigned long)user);
-       if(!vma || (unsigned long)user < vma->vm_start)
-               return -EFAULT;
-       if(!(vma->vm_flags & VM_READ))
-               return -EFAULT;
-       i = vma->vm_end - (unsigned long) user;
-       if(PAGE_SIZE <= (unsigned long) i)
-               i = PAGE_SIZE - 1;
-       if(!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-       if(copy_from_user((void *) page, user, i)) {
-               free_page(page);
-               return -EFAULT;
-       }
-       *kernel = page;
-       return 0;
-}
-
-#define SMBFS_NAME     "smbfs"
-#define NCPFS_NAME     "ncpfs"
-
-asmlinkage long sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
-{
-       unsigned long type_page = 0;
-       unsigned long data_page = 0;
-       unsigned long dev_page = 0;
-       unsigned long dir_page = 0;
-       int err, is_smb, is_ncp;
-       
-       is_smb = is_ncp = 0;
-
-       err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
-       if (err)
-               goto out;
-
-       if (!type_page) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       is_smb = !strcmp((char *)type_page, SMBFS_NAME);
-       is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
-
-       err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
-       if (err)
-               goto type_out;
-
-       err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
-       if (err)
-               goto data_out;
-
-       err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
-       if (err)
-               goto dev_out;
-
-       if (!is_smb && !is_ncp) {
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       } else {
-               if (is_ncp)
-                       do_ncp_super_data_conv((void *)data_page);
-               else
-                       do_smb_super_data_conv((void *)data_page);
-
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       }
-       free_page(dir_page);
-
-dev_out:
-       free_page(dev_page);
-
-data_out:
-       free_page(data_page);
-
-type_out:
-       free_page(type_page);
-
-out:
-       return err;
-}
-
 /* readdir & getdents */
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
index ea7e709246576197ee89ca74176bef005541c850..183c7c5f30b6ca76f2caefa27ce09cc653066357 100644 (file)
@@ -35,9 +35,6 @@
 #include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
 #include <linux/sunrpc/svc.h>
@@ -828,157 +825,6 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
        return err;
 }
 
-struct ncp_mount_data32 {
-        int version;
-        unsigned int ncp_fd;
-        compat_uid_t mounted_uid;
-        compat_pid_t wdog_pid;
-        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-        unsigned int time_out;
-        unsigned int retry_count;
-        unsigned int flags;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-static void *do_ncp_super_data_conv(void *raw_data)
-{
-       struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
-       struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
-
-       n->dir_mode = n32->dir_mode;
-       n->file_mode = n32->file_mode;
-       n->gid = low2highgid(n32->gid);
-       n->uid = low2highuid(n32->uid);
-       memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
-       n->wdog_pid = n32->wdog_pid;
-       n->mounted_uid = low2highuid(n32->mounted_uid);
-       return raw_data;
-}
-
-struct smb_mount_data32 {
-        int version;
-        compat_uid_t mounted_uid;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-static void *do_smb_super_data_conv(void *raw_data)
-{
-       struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
-       struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
-
-       if (s32->version != SMB_MOUNT_OLDVERSION)
-               goto out;
-       s->version = s32->version;
-       s->mounted_uid = low2highuid(s32->mounted_uid);
-       s->uid = low2highuid(s32->uid);
-       s->gid = low2highgid(s32->gid);
-       s->file_mode = s32->file_mode;
-       s->dir_mode = s32->dir_mode;
-out:
-       return raw_data;
-}
-
-static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
-{
-       int i;
-       unsigned long page;
-       struct vm_area_struct *vma;
-
-       *kernel = 0;
-       if(!user)
-               return 0;
-       vma = find_vma(current->mm, (unsigned long)user);
-       if(!vma || (unsigned long)user < vma->vm_start)
-               return -EFAULT;
-       if(!(vma->vm_flags & VM_READ))
-               return -EFAULT;
-       i = vma->vm_end - (unsigned long) user;
-       if(PAGE_SIZE <= (unsigned long) i)
-               i = PAGE_SIZE - 1;
-       if(!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-       if(copy_from_user((void *) page, user, i)) {
-               free_page(page);
-               return -EFAULT;
-       }
-       *kernel = page;
-       return 0;
-}
-
-#define SMBFS_NAME     "smbfs"
-#define NCPFS_NAME     "ncpfs"
-
-asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
-{
-       unsigned long type_page = 0;
-       unsigned long data_page = 0;
-       unsigned long dev_page = 0;
-       unsigned long dir_page = 0;
-       int err, is_smb, is_ncp;
-
-       is_smb = is_ncp = 0;
-
-       err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
-       if (err)
-               goto out;
-
-       if (!type_page) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       is_smb = !strcmp((char *)type_page, SMBFS_NAME);
-       is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
-
-       err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
-       if (err)
-               goto type_out;
-
-       err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
-       if (err)
-               goto data_out;
-
-       err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
-       if (err)
-               goto dev_out;
-
-       if (!is_smb && !is_ncp) {
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       } else {
-               if (is_ncp)
-                       do_ncp_super_data_conv((void *)data_page);
-               else
-                       do_smb_super_data_conv((void *)data_page);
-
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       }
-       free_page(dir_page);
-
-dev_out:
-       free_page(dev_page);
-
-data_out:
-       free_page(data_page);
-
-type_out:
-       free_page(type_page);
-
-out:
-       return err;
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
index c911dd4dd2700bf210782b8e7cad95c070213782..c2ed4ea4a763eb94c313457fbf6d331add911118 100644 (file)
@@ -102,7 +102,7 @@ sys32_mount_wrapper:
        llgtr   %r4,%r4                 # char *
        llgfr   %r5,%r5                 # unsigned long
        llgtr   %r6,%r6                 # void *
-       jg      sys32_mount             # branch to system call
+       jg      compat_sys_mount        # branch to system call
 
        .globl  sys32_oldumount_wrapper 
 sys32_oldumount_wrapper:
index d064b69d362383673596a1ff334acab82568a623..a0448a01413769a70457927403738bbb35b3e550 100644 (file)
@@ -27,9 +27,6 @@
 #include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
 #include <linux/sunrpc/svc.h>
@@ -1329,209 +1326,6 @@ asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
        return sys_sysfs(option, arg1, arg2);
 }
 
-struct ncp_mount_data32_v3 {
-        int version;
-        unsigned int ncp_fd;
-        compat_uid_t mounted_uid;
-        compat_pid_t wdog_pid;
-        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-        unsigned int time_out;
-        unsigned int retry_count;
-        unsigned int flags;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-struct ncp_mount_data32_v4 {
-       int version;
-       /* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
-       unsigned int flags;
-       unsigned int mounted_uid;
-       int wdog_pid;
-
-       unsigned int ncp_fd;
-       unsigned int time_out;
-       unsigned int retry_count;
-
-       unsigned int uid;
-       unsigned int gid;
-       unsigned int file_mode;
-       unsigned int dir_mode;
-};
-
-static void *do_ncp_super_data_conv(void *raw_data)
-{
-       switch (*(int*)raw_data) {
-               case NCP_MOUNT_VERSION:
-                       {
-                               struct ncp_mount_data news, *n = &news; 
-                               struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
-
-                               n->version = n32->version;
-                               n->ncp_fd = n32->ncp_fd;
-                               n->mounted_uid = low2highuid(n32->mounted_uid);
-                               n->wdog_pid = n32->wdog_pid;
-                               memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
-                               n->time_out = n32->time_out;
-                               n->retry_count = n32->retry_count;
-                               n->flags = n32->flags;
-                               n->uid = low2highuid(n32->uid);
-                               n->gid = low2highgid(n32->gid);
-                               n->file_mode = n32->file_mode;
-                               n->dir_mode = n32->dir_mode;
-                               memcpy(raw_data, n, sizeof(*n)); 
-                       }
-                       break;
-               case NCP_MOUNT_VERSION_V4:
-                       {
-                               struct ncp_mount_data_v4 news, *n = &news; 
-                               struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
-
-                               n->version = n32->version;
-                               n->flags = n32->flags;
-                               n->mounted_uid = n32->mounted_uid;
-                               n->wdog_pid = n32->wdog_pid;
-                               n->ncp_fd = n32->ncp_fd;
-                               n->time_out = n32->time_out;
-                               n->retry_count = n32->retry_count;
-                               n->uid = n32->uid;
-                               n->gid = n32->gid;
-                               n->file_mode = n32->file_mode;
-                               n->dir_mode = n32->dir_mode;
-                               memcpy(raw_data, n, sizeof(*n)); 
-                       }
-                       break;
-               default:
-                       /* do not touch unknown structures */
-                       break;
-       }
-       return raw_data;
-}
-
-struct smb_mount_data32 {
-        int version;
-        compat_uid_t mounted_uid;
-        compat_uid_t uid;
-        compat_gid_t gid;
-        compat_mode_t file_mode;
-        compat_mode_t dir_mode;
-};
-
-static void *do_smb_super_data_conv(void *raw_data)
-{
-       struct smb_mount_data news, *s = &news;
-       struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
-
-       if (s32->version != SMB_MOUNT_OLDVERSION)
-               goto out;
-       s->version = s32->version;
-       s->mounted_uid = low2highuid(s32->mounted_uid);
-       s->uid = low2highuid(s32->uid);
-       s->gid = low2highgid(s32->gid);
-       s->file_mode = s32->file_mode;
-       s->dir_mode = s32->dir_mode;
-       memcpy(raw_data, s, sizeof(struct smb_mount_data)); 
-out:
-       return raw_data;
-}
-
-static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
-{
-       int i;
-       unsigned long page;
-       struct vm_area_struct *vma;
-
-       *kernel = 0;
-       if(!user)
-               return 0;
-       vma = find_vma(current->mm, (unsigned long)user);
-       if(!vma || (unsigned long)user < vma->vm_start)
-               return -EFAULT;
-       if(!(vma->vm_flags & VM_READ))
-               return -EFAULT;
-       i = vma->vm_end - (unsigned long) user;
-       if(PAGE_SIZE <= (unsigned long) i)
-               i = PAGE_SIZE - 1;
-       if(!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-       if(copy_from_user((void *) page, user, i)) {
-               free_page(page);
-               return -EFAULT;
-       }
-       *kernel = page;
-       return 0;
-}
-
-#define SMBFS_NAME     "smbfs"
-#define NCPFS_NAME     "ncpfs"
-
-asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
-{
-       unsigned long type_page = 0;
-       unsigned long data_page = 0;
-       unsigned long dev_page = 0;
-       unsigned long dir_page = 0;
-       int err, is_smb, is_ncp;
-
-       is_smb = is_ncp = 0;
-
-       err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
-       if (err)
-               goto out;
-
-       if (!type_page) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       is_smb = !strcmp((char *)type_page, SMBFS_NAME);
-       is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
-
-       err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
-       if (err)
-               goto type_out;
-
-       err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
-       if (err)
-               goto data_out;
-
-       err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
-       if (err)
-               goto dev_out;
-
-       if (!is_smb && !is_ncp) {
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       } else {
-               if (is_ncp)
-                       do_ncp_super_data_conv((void *)data_page);
-               else
-                       do_smb_super_data_conv((void *)data_page);
-
-               lock_kernel();
-               err = do_mount((char*)dev_page, (char*)dir_page,
-                               (char*)type_page, new_flags, (char*)data_page);
-               unlock_kernel();
-       }
-       free_page(dir_page);
-
-dev_out:
-       free_page(dev_page);
-
-data_out:
-       free_page(data_page);
-
-type_out:
-       free_page(type_page);
-
-out:
-       return err;
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
index 3779bb833e4b8f6b7aecf31238917b93f88ee345..aec236a3179daf7520d963d486b1b0d1e8e7565f 100644 (file)
@@ -52,7 +52,7 @@ sys_call_table32:
 /*150*/        .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
        .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
 /*160*/        .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
-       .word sys_quotactl, sys_set_tid_address, sys32_mount, sys_ustat, sys_setxattr
+       .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys_setxattr
 /*170*/        .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
        .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/        .word sys_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
index 156373befe4bc0f5ea44a85a8e8e18a3d55b3fba..aea26e4a840563f52eab1366a1db998a8bc696e3 100644 (file)
@@ -326,7 +326,7 @@ ia32_sys_call_table:
        .quad sys_stat
        .quad sys32_lseek
        .quad sys_getpid                /* 20 */
-       .quad sys_mount /* mount  */
+       .quad compat_sys_mount  /* mount  */
        .quad sys_oldumount     /* old_umount  */
        .quad sys_setuid16
        .quad sys_getuid16
index d2c08a0a2bf5107e943838261c9c442b9445edc5..7df03764b1dde51fa16c7eb325e5c8a15d5d6a73 100644 (file)
@@ -40,9 +40,6 @@
 #include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
-#include <linux/smb_fs.h>
-#include <linux/smb_mount.h>
-#include <linux/ncp_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
 #include <linux/sunrpc/svc.h>
@@ -874,39 +871,6 @@ sys32_sysfs(int option, u32 arg1, u32 arg2)
        return sys_sysfs(option, arg1, arg2);
 }
 
-static char *badfs[] = {
-       "smbfs", "ncpfs", NULL
-};     
-
-static int checktype(char *user_type) 
-{ 
-       int err = 0; 
-       char **s,*kernel_type = getname(user_type); 
-       if (!kernel_type || IS_ERR(kernel_type)) 
-               return -EFAULT; 
-       for (s = badfs; *s; ++s) 
-               if (!strcmp(kernel_type, *s)) { 
-                       printk(KERN_ERR "mount32: unsupported fs `%s' -- use 64bit mount\n", *s); 
-                       err = -EINVAL; 
-                       break;
-               }       
-       putname(user_type); 
-       return err;
-} 
-
-asmlinkage long
-sys32_mount(char *dev_name, char *dir_name, char *type,
-           unsigned long new_flags, u32 data)
-{
-       int err;
-       if(!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       err = checktype(type);
-       if (err)
-               return err;
-       return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data));
-}
-
 struct sysinfo32 {
         s32 uptime;
         u32 loads[3];
index 2c6a61a457e94ef2e769947b1f15bb538a718cd9..40023e684520e53202227d4b72c758d48996778a 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/ioctl32.h>
 #include <linux/init.h>
 #include <linux/sockios.h>     /* for SIOCDEVPRIVATE */
+#include <linux/smb.h>
+#include <linux/smb_mount.h>
+#include <linux/ncp_mount.h>
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/ctype.h>
@@ -642,3 +645,152 @@ compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 *iocb)
                ret = sys_io_submit(ctx_id, nr, iocb64);
        return ret;
 }
+
+struct compat_ncp_mount_data {
+       compat_int_t version;
+       compat_uint_t ncp_fd;
+       compat_uid_t mounted_uid;
+       compat_pid_t wdog_pid;
+       unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+       compat_uint_t time_out;
+       compat_uint_t retry_count;
+       compat_uint_t flags;
+       compat_uid_t uid;
+       compat_gid_t gid;
+       compat_mode_t file_mode;
+       compat_mode_t dir_mode;
+};
+
+struct compat_ncp_mount_data_v4 {
+       compat_int_t version;
+       compat_ulong_t flags;
+       compat_ulong_t mounted_uid;
+       compat_long_t wdog_pid;
+       compat_uint_t ncp_fd;
+       compat_uint_t time_out;
+       compat_uint_t retry_count;
+       compat_ulong_t uid;
+       compat_ulong_t gid;
+       compat_ulong_t file_mode;
+       compat_ulong_t dir_mode;
+};
+
+static void *do_ncp_super_data_conv(void *raw_data)
+{
+       int version = *(unsigned int *)raw_data;
+
+       if (version == 3) {
+               struct compat_ncp_mount_data *c_n = raw_data;
+               struct ncp_mount_data *n = raw_data;
+
+               n->dir_mode = c_n->dir_mode;
+               n->file_mode = c_n->file_mode;
+               n->gid = c_n->gid;
+               n->uid = c_n->uid;
+               memmove (n->mounted_vol, c_n->mounted_vol, (sizeof (c_n->mounted_vol) + 3 * sizeof (unsigned int)));
+               n->wdog_pid = c_n->wdog_pid;
+               n->mounted_uid = c_n->mounted_uid;
+       } else if (version == 4) {
+               struct compat_ncp_mount_data_v4 *c_n = raw_data;
+               struct ncp_mount_data_v4 *n = raw_data;
+
+               n->dir_mode = c_n->dir_mode;
+               n->file_mode = c_n->file_mode;
+               n->gid = c_n->gid;
+               n->uid = c_n->uid;
+               n->retry_count = c_n->retry_count;
+               n->time_out = c_n->time_out;
+               n->ncp_fd = c_n->ncp_fd;
+               n->wdog_pid = c_n->wdog_pid;
+               n->mounted_uid = c_n->mounted_uid;
+               n->flags = c_n->flags;
+       } else if (version != 5) {
+               return NULL;
+       }
+
+       return raw_data;
+}
+
+struct compat_smb_mount_data {
+       compat_int_t version;
+       compat_uid_t mounted_uid;
+       compat_uid_t uid;
+       compat_gid_t gid;
+       compat_mode_t file_mode;
+       compat_mode_t dir_mode;
+};
+
+static void *do_smb_super_data_conv(void *raw_data)
+{
+       struct smb_mount_data *s = raw_data;
+       struct compat_smb_mount_data *c_s = raw_data;
+
+       if (c_s->version != SMB_MOUNT_OLDVERSION)
+               goto out;
+       s->dir_mode = c_s->dir_mode;
+       s->file_mode = c_s->file_mode;
+       s->gid = c_s->gid;
+       s->uid = c_s->uid;
+       s->mounted_uid = c_s->mounted_uid;
+ out:
+       return raw_data;
+}
+
+extern int copy_mount_options (const void __user *, unsigned long *);
+
+#define SMBFS_NAME      "smbfs"
+#define NCPFS_NAME      "ncpfs"
+
+asmlinkage int compat_sys_mount(char __user * dev_name, char __user * dir_name,
+                               char __user * type, unsigned long flags,
+                               void __user * data)
+{
+       unsigned long type_page;
+       unsigned long data_page;
+       unsigned long dev_page;
+       char *dir_page;
+       int retval;
+
+       retval = copy_mount_options (type, &type_page);
+       if (retval < 0)
+               goto out;
+
+       dir_page = getname(dir_name);
+       retval = PTR_ERR(dir_page);
+       if (IS_ERR(dir_page))
+               goto out1;
+
+       retval = copy_mount_options (dev_name, &dev_page);
+       if (retval < 0)
+               goto out2;
+
+       retval = copy_mount_options (data, &data_page);
+       if (retval < 0)
+               goto out3;
+
+       retval = -EINVAL;
+
+       if (type_page) {
+               if (!strcmp((char *)type_page, SMBFS_NAME)) {
+                       do_smb_super_data_conv((void *)data_page);
+               } else if (!strcmp((char *)type_page, NCPFS_NAME)) {
+                       do_ncp_super_data_conv((void *)data_page);
+               }
+       }
+
+       lock_kernel();
+       retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
+                       flags, (void*)data_page);
+       unlock_kernel();
+
+       free_page(data_page);
+ out3:
+       free_page(dev_page);
+ out2:
+       putname(dir_page);
+ out1:
+       free_page(type_page);
+ out:
+       return retval;
+}
+
index e29f147fa274c2d3c140d0070bfae95b7b4a3429..4584a684c685f4b2af928d17a4d81d47cbf248cf 100644 (file)
@@ -694,7 +694,7 @@ out:
        return err;
 }
 
-static int copy_mount_options (const void __user *data, unsigned long *where)
+int copy_mount_options (const void __user *data, unsigned long *where)
 {
        int i;
        unsigned long page;
index 732f80337ea062e3f191720a9a9906e3150043b0..b7ba74dbc3fdae07407628feb1731190510a0fce 100644 (file)
@@ -2,6 +2,7 @@
 #define __LINUX_NET_SCM_H
 
 #include <linux/limits.h>
+#include <linux/net.h>
 
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)