lkml.org 
[lkml]   [2004]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] compat_sys_mount

This patch replaces 6 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.

arch/ia64/ia32/ia32_entry.S | 2
arch/ia64/ia32/sys_ia32.c | 154 ---------------------------
arch/parisc/kernel/sys_parisc32.c | 99 -----------------
arch/parisc/kernel/syscall_table.S | 2
arch/ppc64/kernel/misc.S | 2
arch/ppc64/kernel/sys_ppc32.c | 206 -------------------------------------
arch/s390/kernel/compat_linux.c | 154 ---------------------------
arch/s390/kernel/compat_wrapper.S | 2
arch/sparc64/kernel/sys_sparc32.c | 206 -------------------------------------
arch/sparc64/kernel/systbls.S | 2
arch/x86_64/ia32/ia32entry.S | 2
arch/x86_64/ia32/sys_ia32.c | 36 ------
fs/compat.c | 152 +++++++++++++++++++++++++++
fs/namespace.c | 2
include/net/scm.h | 1
15 files changed, 160 insertions(+), 862 deletions(-)

Index: arch/ia64/ia32/ia32_entry.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/ia64/ia32/ia32_entry.S,v
retrieving revision 1.5
diff -u -p -r1.5 ia32_entry.S
--- a/arch/ia64/ia32/ia32_entry.S 7 Jan 2004 21:30:05 -0000 1.5
+++ b/arch/ia64/ia32/ia32_entry.S 26 Mar 2004 19:05:24 -0000
@@ -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: arch/ia64/ia32/sys_ia32.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/ia64/ia32/sys_ia32.c,v
retrieving revision 1.12
diff -u -p -r1.12 sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c 16 Mar 2004 15:39:51 -0000 1.12
+++ b/arch/ia64/ia32/sys_ia32.c 26 Mar 2004 19:05:24 -0000
@@ -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>
@@ -2383,157 +2380,6 @@ long sys32_fadvise64_64(int fd, __u32 of
}

#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)
{
Index: arch/parisc/kernel/sys_parisc32.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/sys_parisc32.c,v
retrieving revision 1.13
diff -u -p -r1.13 sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c 28 Feb 2004 01:50:19 -0000 1.13
+++ b/arch/parisc/kernel/sys_parisc32.c 26 Mar 2004 19:05:25 -0000
@@ -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: arch/parisc/kernel/syscall_table.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/syscall_table.S,v
retrieving revision 1.5
diff -u -p -r1.5 syscall_table.S
--- a/arch/parisc/kernel/syscall_table.S 19 Jan 2004 05:15:47 -0000 1.5
+++ b/arch/parisc/kernel/syscall_table.S 26 Mar 2004 19:05:25 -0000
@@ -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: arch/ppc64/kernel/misc.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/ppc64/kernel/misc.S,v
retrieving revision 1.8
diff -u -p -r1.8 misc.S
--- a/arch/ppc64/kernel/misc.S 20 Mar 2004 20:29:26 -0000 1.8
+++ b/arch/ppc64/kernel/misc.S 26 Mar 2004 19:05:26 -0000
@@ -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: arch/ppc64/kernel/sys_ppc32.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/ppc64/kernel/sys_ppc32.c,v
retrieving revision 1.9
diff -u -p -r1.9 sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c 20 Mar 2004 20:29:27 -0000 1.9
+++ b/arch/ppc64/kernel/sys_ppc32.c 26 Mar 2004 19:05:26 -0000
@@ -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>
@@ -251,209 +248,6 @@ out:
if (file)
fput(file);
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 */
Index: arch/s390/kernel/compat_linux.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/s390/kernel/compat_linux.c,v
retrieving revision 1.10
diff -u -p -r1.10 compat_linux.c
--- a/arch/s390/kernel/compat_linux.c 20 Mar 2004 20:29:28 -0000 1.10
+++ b/arch/s390/kernel/compat_linux.c 26 Mar 2004 19:05:26 -0000
@@ -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>
@@ -825,157 +822,6 @@ int cp_compat_stat(struct kstat *stat, s
err |= put_user(0, &statbuf->__unused4[0]);
err |= put_user(0, &statbuf->__unused4[1]);
*/
- 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;
}

Index: arch/s390/kernel/compat_wrapper.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/s390/kernel/compat_wrapper.S,v
retrieving revision 1.5
diff -u -p -r1.5 compat_wrapper.S
--- a/arch/s390/kernel/compat_wrapper.S 20 Mar 2004 20:29:28 -0000 1.5
+++ b/arch/s390/kernel/compat_wrapper.S 26 Mar 2004 19:05:26 -0000
@@ -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: arch/sparc64/kernel/sys_sparc32.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/sparc64/kernel/sys_sparc32.c,v
retrieving revision 1.10
diff -u -p -r1.10 sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c 16 Mar 2004 15:40:00 -0000 1.10
+++ b/arch/sparc64/kernel/sys_sparc32.c 26 Mar 2004 19:05:27 -0000
@@ -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>
@@ -1327,209 +1324,6 @@ int cp_compat_stat(struct kstat *stat, s
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 {
Index: arch/sparc64/kernel/systbls.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/sparc64/kernel/systbls.S,v
retrieving revision 1.6
diff -u -p -r1.6 systbls.S
--- a/arch/sparc64/kernel/systbls.S 7 Jan 2004 21:30:12 -0000 1.6
+++ b/arch/sparc64/kernel/systbls.S 26 Mar 2004 19:05:27 -0000
@@ -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: arch/x86_64/ia32/ia32entry.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/x86_64/ia32/ia32entry.S,v
retrieving revision 1.6
diff -u -p -r1.6 ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S 16 Mar 2004 15:40:01 -0000 1.6
+++ b/arch/x86_64/ia32/ia32entry.S 26 Mar 2004 19:05:27 -0000
@@ -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: arch/x86_64/ia32/sys_ia32.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/x86_64/ia32/sys_ia32.c,v
retrieving revision 1.11
diff -u -p -r1.11 sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c 16 Mar 2004 15:40:01 -0000 1.11
+++ b/arch/x86_64/ia32/sys_ia32.c 26 Mar 2004 19:05:28 -0000
@@ -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>
@@ -872,39 +869,6 @@ asmlinkage long
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 {
Index: fs/compat.c
===================================================================
RCS file: /var/cvs/linux-2.6/fs/compat.c,v
retrieving revision 1.7
diff -u -p -r1.7 compat.c
--- a/fs/compat.c 28 Feb 2004 01:51:06 -0000 1.7
+++ b/fs/compat.c 26 Mar 2004 19:05:31 -0000
@@ -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_i
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: fs/namespace.c
===================================================================
RCS file: /var/cvs/linux-2.6/fs/namespace.c,v
retrieving revision 1.5
diff -u -p -r1.5 namespace.c
--- a/fs/namespace.c 20 Mar 2004 20:29:48 -0000 1.5
+++ b/fs/namespace.c 26 Mar 2004 19:05:31 -0000
@@ -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: include/net/scm.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/net/scm.h,v
retrieving revision 1.2
diff -u -p -r1.2 scm.h
--- a/include/net/scm.h 8 Oct 2003 20:53:05 -0000 1.2
+++ b/include/net/scm.h 26 Mar 2004 19:05:31 -0000
@@ -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)
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:02    [W:0.710 / U:0.036 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site