summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/sys_sparc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/sys_sparc32.c')
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c1090
1 files changed, 494 insertions, 596 deletions
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 59815b7a8..1f607da98 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.26 1997/06/04 13:05:21 jj Exp $
+/* $Id: sys_sparc32.c,v 1.43 1997/07/17 02:20:45 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -8,6 +8,7 @@
* environment.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/signal.h>
@@ -30,11 +31,13 @@
#include <linux/ncp_fs.h>
#include <linux/quota.h>
#include <linux/file.h>
+#include <linux/module.h>
#include <asm/types.h>
#include <asm/poll.h>
#include <asm/ipc.h>
#include <asm/uaccess.h>
+#include <asm/fpumacro.h>
/* As gcc will warn about casting u32 to some ptr, we have to cast it to
* unsigned long first, and that's what is A() for.
@@ -372,11 +375,12 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
switch (version) {
case 0: default: {
unsigned long raddr;
+ u32 *uptr = (u32 *) A(((u32)third));
err = sys_shmat (first, (char *)A(ptr), second, &raddr);
if (err)
goto out;
err = -EFAULT;
- if(put_user (raddr, ((u32 *)A(third))))
+ if(put_user (raddr, uptr))
goto out;
err = 0;
goto out;
@@ -469,32 +473,6 @@ out:
return err;
}
-extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long off);
-
-asmlinkage unsigned long sys32_mmap(u32 addr, u32 len, u32 prot,
- u32 flags, u32 fd, u32 off)
-{
- return sys_mmap((unsigned long)addr, (unsigned long)len,
- (unsigned long)prot, (unsigned long)flags,
- (unsigned long)fd, (unsigned long)off);
-}
-
-extern asmlinkage int sys_bdflush(int func, long data);
-
-asmlinkage int sys32_bdflush(int func, s32 data)
-{
- return sys_bdflush(func, (long)data);
-}
-
-extern asmlinkage int sys_uselib(const char * library);
-
-asmlinkage int sys32_uselib(u32 library)
-{
- return sys_uselib((const char *)A(library));
-}
-
static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
{
if(get_user(kfl->l_type, &ufl->l_type) ||
@@ -544,55 +522,6 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, u32 arg)
}
}
-extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
-
-asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev)
-{
- return sys_mknod((const char *)A(filename), mode, dev);
-}
-
-extern asmlinkage int sys_mkdir(const char * pathname, int mode);
-
-asmlinkage int sys32_mkdir(u32 pathname, int mode)
-{
- return sys_mkdir((const char *)A(pathname), mode);
-}
-
-extern asmlinkage int sys_rmdir(const char * pathname);
-
-asmlinkage int sys32_rmdir(u32 pathname)
-{
- return sys_rmdir((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_unlink(const char * pathname);
-
-asmlinkage int sys32_unlink(u32 pathname)
-{
- return sys_unlink((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_symlink(const char * oldname, const char * newname);
-
-asmlinkage int sys32_symlink(u32 oldname, u32 newname)
-{
- return sys_symlink((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_link(const char * oldname, const char * newname);
-
-asmlinkage int sys32_link(u32 oldname, u32 newname)
-{
- return sys_link((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_rename(const char * oldname, const char * newname);
-
-asmlinkage int sys32_rename(u32 oldname, u32 newname)
-{
- return sys_rename((const char *)A(oldname), (const char *)A(newname));
-}
-
struct dqblk32 {
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
@@ -701,20 +630,6 @@ asmlinkage int sys32_fstatfs(unsigned int fd, u32 buf)
return ret;
}
-extern asmlinkage int sys_truncate(const char * path, unsigned long length);
-
-asmlinkage int sys32_truncate(u32 path, u32 length)
-{
- return sys_truncate((const char *)A(path), (unsigned long)length);
-}
-
-extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
-
-asmlinkage int sys32_ftruncate(unsigned int fd, u32 length)
-{
- return sys_ftruncate(fd, (unsigned long)length);
-}
-
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
asmlinkage int sys32_utime(u32 filename, u32 times)
@@ -741,96 +656,6 @@ asmlinkage int sys32_utime(u32 filename, u32 times)
return ret;
}
-extern asmlinkage int sys_utimes(char * filename, struct timeval * utimes);
-
-asmlinkage int sys32_utimes(u32 filename, u32 utimes)
-{
- /* struct timeval is the same :)) */
- return sys_utimes((char *)A(filename), (struct timeval *)A(utimes));
-}
-
-extern asmlinkage int sys_access(const char * filename, int mode);
-
-asmlinkage int sys32_access(u32 filename, int mode)
-{
- return sys_access((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chdir(const char * filename);
-
-asmlinkage int sys32_chdir(u32 filename)
-{
- return sys_chdir((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chroot(const char * filename);
-
-asmlinkage int sys32_chroot(u32 filename)
-{
- return sys_chroot((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chmod(const char * filename, mode_t mode);
-
-asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode)
-{
- return sys_chmod((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group);
-
-asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group)
-{
- return sys_chown((const char *)A(filename), user, group);
-}
-
-extern asmlinkage int sys_open(const char * filename,int flags,int mode);
-
-asmlinkage int sys32_open(u32 filename, int flags, int mode)
-{
- return sys_open((const char *)A(filename), flags, mode);
-}
-
-extern asmlinkage int sys_creat(const char * pathname, int mode);
-
-asmlinkage int sys32_creat(u32 pathname, int mode)
-{
- return sys_creat((const char *)A(pathname), mode);
-}
-
-extern asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
-
-asmlinkage long sys32_lseek(unsigned int fd, s32 offset, unsigned int origin)
-{
- return sys_lseek(fd, (off_t)offset, origin);
-}
-
-extern asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
- unsigned long offset_low,
- loff_t *result, unsigned int origin);
-
-asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high,
- u32 offset_low, u32 result, unsigned int origin)
-{
- /* loff_t is the same :)) */
- return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low,
- (loff_t *)A(result), origin);
-}
-
-extern asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count);
-
-asmlinkage long sys32_read(unsigned int fd, u32 buf, u32 count)
-{
- return sys_read(fd, (char *)A(buf), (unsigned long)count);
-}
-
-extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count);
-
-asmlinkage long sys32_write(unsigned int fd, u32 buf, u32 count)
-{
- return sys_write(fd, (const char *)A(buf), (unsigned long)count);
-}
-
struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
typedef long (*IO_fn_t)(struct inode *, struct file *, char *, unsigned long);
@@ -934,14 +759,29 @@ static long do_readv_writev32(int type, struct inode *inode, struct file *file,
asmlinkage long sys32_readv(int fd, u32 vector, u32 count)
{
struct file *file;
+ struct dentry *dentry;
struct inode *inode;
long err = -EBADF;
lock_kernel();
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+ if(fd >= NR_OPEN)
+ goto out;
+
+ file = current->files->fd[fd];
+ if(!file)
+ goto out;
+
+ if(!(file->f_mode & 1))
+ goto out;
+
+ dentry = file->f_dentry;
+ if(!dentry)
goto out;
- if (!(file->f_mode & 1))
+
+ inode = dentry->d_inode;
+ if(!inode)
goto out;
+
err = do_readv_writev32(VERIFY_WRITE, inode, file,
(struct iovec32 *)A(vector), count);
out:
@@ -953,13 +793,28 @@ asmlinkage long sys32_writev(int fd, u32 vector, u32 count)
{
int error = -EBADF;
struct file *file;
+ struct dentry *dentry;
struct inode *inode;
lock_kernel();
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode=file->f_inode))
+ if(fd >= NR_OPEN)
+ goto out;
+
+ file = current->files->fd[fd];
+ if(!file)
+ goto out;
+
+ if(!(file->f_mode & 2))
+ goto out;
+
+ dentry = file->f_dentry;
+ if(!dentry)
goto out;
- if (!(file->f_mode & 2))
+
+ inode = dentry->d_inode;
+ if(!inode)
goto out;
+
down(&inode->i_sem);
error = do_readv_writev32(VERIFY_READ, inode, file,
(struct iovec32 *)A(vector), count);
@@ -1008,21 +863,34 @@ asmlinkage int old32_readdir(unsigned int fd, u32 dirent, unsigned int count)
{
int error = -EBADF;
struct file * file;
+ struct dentry * dentry;
+ struct inode * inode;
struct readdir_callback32 buf;
lock_kernel();
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if(fd >= NR_OPEN)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
+
+ file = current->files->fd[fd];
+ if(!file)
goto out;
- error = verify_area(VERIFY_WRITE, (void *)A(dirent),
- sizeof(struct old_linux_dirent32));
- if (error)
+
+ dentry = file->f_dentry;
+ if(!dentry)
+ goto out;
+
+ inode = dentry->d_inode;
+ if(!inode)
goto out;
+
buf.count = 0;
buf.dirent = (struct old_linux_dirent32 *)A(dirent);
- error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
+
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+
+ error = file->f_op->readdir(inode, file, &buf, fillonedir);
if (error < 0)
goto out;
error = buf.count;
@@ -1072,30 +940,43 @@ static int filldir(void * __buf, const char * name, int namlen, off_t offset, in
asmlinkage int sys32_getdents(unsigned int fd, u32 dirent, unsigned int count)
{
struct file * file;
+ struct dentry * dentry;
+ struct inode *inode;
struct linux_dirent32 * lastdirent;
struct getdents_callback32 buf;
int error = -EBADF;
lock_kernel();
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ if(fd >= NR_OPEN)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
+
+ file = current->files->fd[fd];
+ if(!file)
+ goto out;
+
+ dentry = file->f_dentry;
+ if(!dentry)
goto out;
- error = verify_area(VERIFY_WRITE, (void *)A(dirent), count);
- if (error)
+
+ inode = dentry->d_inode;
+ if(!inode)
goto out;
+
buf.current_dir = (struct linux_dirent32 *) A(dirent);
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
+
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+
+ error = file->f_op->readdir(inode, file, &buf, filldir);
if (error < 0)
goto out;
lastdirent = buf.previous;
- if (!lastdirent) {
- error = buf.error;
- } else {
+ error = buf.error;
+ if(lastdirent) {
put_user(file->f_pos, &lastdirent->d_off);
error = count - buf.count;
}
@@ -1196,13 +1077,6 @@ out:
return ret;
}
-extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout);
-
-asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout)
-{
- return sys_poll((struct pollfd *)A(ufds), nfds, timeout);
-}
-
static inline int putstat(struct stat32 *ubuf, struct stat *kbuf)
{
if (put_user (kbuf->st_dev, &ubuf->st_dev) ||
@@ -1280,13 +1154,6 @@ asmlinkage int sys32_newfstat(unsigned int fd, u32 statbuf)
return ret;
}
-extern asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz);
-
-asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz)
-{
- return sys_readlink((const char *)A(path), (char *)A(buf), bufsiz);
-}
-
extern asmlinkage int sys_sysfs(int option, ...);
asmlinkage int sys32_sysfs(int option, ...)
@@ -1312,42 +1179,162 @@ asmlinkage int sys32_sysfs(int option, ...)
return ret;
}
-extern asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf);
+struct ncp_mount_data32 {
+ int version;
+ unsigned int ncp_fd;
+ __kernel_uid_t32 mounted_uid;
+ __kernel_pid_t32 wdog_pid;
+ unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+ unsigned int time_out;
+ unsigned int retry_count;
+ unsigned int flags;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_mode_t32 file_mode;
+ __kernel_mode_t32 dir_mode;
+};
-asmlinkage int sys32_ustat(dev_t dev, u32 ubuf)
+static void *do_ncp_super_data_conv(void *raw_data)
{
- /* ustat is the same :)) */
- return sys_ustat(dev, (struct ustat *)A(ubuf));
+ 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;
}
-extern asmlinkage int sys_umount(char * name);
+struct smb_mount_data32 {
+ int version;
+ unsigned int fd;
+ __kernel_uid_t32 mounted_uid;
+ struct sockaddr_in addr;
+ char server_name[17];
+ char client_name[17];
+ char service[64];
+ char root_path[64];
+ char username[64];
+ char password[64];
+ char domain[64];
+ unsigned short max_xmit;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_mode_t32 file_mode;
+ __kernel_mode_t32 dir_mode;
+};
-asmlinkage int sys32_umount(u32 name)
+static void *do_smb_super_data_conv(void *raw_data)
{
- return sys_umount((char *)A(name));
-}
+ struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+ struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
-extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void *data);
+ s->dir_mode = s32->dir_mode;
+ s->file_mode = s32->file_mode;
+ s->gid = s32->gid;
+ s->uid = s32->uid;
+ memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
+ s->mounted_uid = s32->mounted_uid;
+ return raw_data;
+}
-asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
+static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
{
- return sys_mount((char *)A(dev_name), (char *)A(dir_name), (char *)A(type),
- (unsigned long)new_flags, (void *)A(data));
+ 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;
}
-extern asmlinkage int sys_syslog(int type, char * bug, int count);
+extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
+ unsigned long new_flags, void *data);
+
+#define SMBFS_NAME "smbfs"
+#define NCPFS_NAME "ncpfs"
-asmlinkage int sys32_syslog(int type, u32 bug, int count)
+asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
{
- return sys_syslog(type, (char *)A(bug), count);
-}
+ unsigned long type_page;
+ int err, is_smb, is_ncp;
-extern asmlinkage int sys_personality(unsigned long personality);
+ if(!suser())
+ return -EPERM;
+ is_smb = is_ncp = 0;
+ err = copy_mount_stuff_to_kernel((const void *)A(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((char *)A(dev_name), (char *)A(dir_name),
+ (char *)A(type), (unsigned long)new_flags,
+ (void *)A(data));
+ } else {
+ unsigned long dev_page, dir_page, data_page;
+ int old_fs;
-asmlinkage int sys32_personality(u32 personality)
-{
- return sys_personality((unsigned long)personality);
+ err = copy_mount_stuff_to_kernel((const void *)A(dev_name), &dev_page);
+ if(err)
+ goto out;
+ err = copy_mount_stuff_to_kernel((const void *)A(dir_name), &dir_page);
+ if(err)
+ goto dev_out;
+ err = copy_mount_stuff_to_kernel((const void *)A(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("Tell DaveM he fucked up...");
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_mount((char *)dev_page, (char *)dir_page,
+ (char *)type_page, (unsigned long)new_flags,
+ (void *)data_page);
+ set_fs(old_fs);
+
+ 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;
+ }
}
struct rusage32 {
@@ -1416,13 +1403,6 @@ asmlinkage int sys32_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32
}
}
-extern asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options);
-
-asmlinkage int sys32_waitpid(__kernel_pid_t32 pid, u32 stat_addr, int options)
-{
- return sys_waitpid(pid, (unsigned int *)A(stat_addr), options);
-}
-
struct sysinfo32 {
s32 uptime;
u32 loads[3];
@@ -1462,46 +1442,6 @@ asmlinkage int sys32_sysinfo(u32 info)
return ret;
}
-extern asmlinkage int sys_getitimer(int which, struct itimerval *value);
-
-asmlinkage int sys32_getitimer(int which, u32 value)
-{
- /* itimerval is the same :)) */
- return sys_getitimer(which, (struct itimerval *)A(value));
-}
-
-extern asmlinkage int sys_setitimer(int which, struct itimerval *value,
- struct itimerval *ovalue);
-
-asmlinkage int sys32_setitimer(int which, u32 value, u32 ovalue)
-{
- return sys_setitimer(which, (struct itimerval *)A(value),
- (struct itimerval *)A(ovalue));
-}
-
-extern asmlinkage int sys_sched_setscheduler(pid_t pid, int policy,
- struct sched_param *param);
-
-asmlinkage int sys32_sched_setscheduler(__kernel_pid_t32 pid, int policy, u32 param)
-{
- /* sched_param is the same :)) */
- return sys_sched_setscheduler(pid, policy, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_setparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_setparam(__kernel_pid_t32 pid, u32 param)
-{
- return sys_sched_setparam(pid, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_getparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_getparam(__kernel_pid_t32 pid, u32 param)
-{
- return sys_sched_getparam(pid, (struct sched_param *)A(param));
-}
-
struct timespec32 {
s32 tv_sec;
s32 tv_nsec;
@@ -1577,25 +1517,29 @@ asmlinkage int sys32_sigpending(u32 set)
return ret;
}
-extern asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler);
+extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
-asmlinkage unsigned long sys32_signal(int signum, u32 handler)
+asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
{
- return sys_signal(signum, (__sighandler_t)A(handler));
-}
-
-extern asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg);
+ uid_t sruid, seuid;
-asmlinkage int sys32_reboot(int magic1, int magic2, int cmd, u32 arg)
-{
- return sys_reboot(magic1, magic2, cmd, (void *)A(arg));
+ sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+ seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+ return sys_setreuid(sruid, seuid);
}
-extern asmlinkage int sys_acct(const char *name);
+extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
-asmlinkage int sys32_acct(u32 name)
+asmlinkage int sys32_setresuid(__kernel_uid_t32 ruid,
+ __kernel_uid_t32 euid,
+ __kernel_uid_t32 suid)
{
- return sys_acct((const char *)A(name));
+ uid_t sruid, seuid, ssuid;
+
+ sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+ seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+ ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
+ return sys_setresuid(sruid, seuid, ssuid);
}
extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
@@ -1654,7 +1598,7 @@ asmlinkage int sys32_getgroups(int gidsetsize, u32 grouplist)
set_fs (KERNEL_DS);
ret = sys_getgroups(gidsetsize, gl);
set_fs (old_fs);
- if (ret > 0 && ret <= NGROUPS)
+ if (gidsetsize && ret > 0 && ret <= NGROUPS)
for (i = 0; i < ret; i++, grouplist += sizeof(__kernel_gid_t32))
if (__put_user (gl[i], (__kernel_gid_t32 *)A(grouplist)))
return -EFAULT;
@@ -1680,41 +1624,8 @@ asmlinkage int sys32_setgroups(int gidsetsize, u32 grouplist)
return ret;
}
-extern asmlinkage int sys_newuname(struct new_utsname * name);
-
-asmlinkage int sys32_newuname(u32 name)
-{
- /* utsname is the same :)) */
- return sys_newuname((struct new_utsname *)A(name));
-}
-
-extern asmlinkage int sys_olduname(struct oldold_utsname * name);
-
-asmlinkage int sys32_olduname(u32 name)
-{
- return sys_olduname((struct oldold_utsname *)A(name));
-}
-
-extern asmlinkage int sys_sethostname(char *name, int len);
-
-asmlinkage int sys32_sethostname(u32 name, int len)
-{
- return sys_sethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_gethostname(char *name, int len);
-
-asmlinkage int sys32_gethostname(u32 name, int len)
-{
- return sys_gethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_setdomainname(char *name, int len);
-
-asmlinkage int sys32_setdomainname(u32 name, int len)
-{
- return sys_setdomainname((char *)A(name), len);
-}
+#define RLIM_INFINITY32 0x7fffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
struct rlimit32 {
s32 rlim_cur;
@@ -1733,8 +1644,8 @@ asmlinkage int sys32_getrlimit(unsigned int resource, u32 rlim)
ret = sys_getrlimit(resource, &r);
set_fs (old_fs);
if (!ret && (
- put_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
- __put_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max))))
+ put_user (RESOURCE32(r.rlim_cur), &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
+ __put_user (RESOURCE32(r.rlim_max), &(((struct rlimit32 *)A(rlim))->rlim_max))))
return -EFAULT;
return ret;
}
@@ -1751,6 +1662,10 @@ asmlinkage int sys32_setrlimit(unsigned int resource, u32 rlim)
if (get_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
__get_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max)))
return -EFAULT;
+ if (r.rlim_cur == RLIM_INFINITY32)
+ r.rlim_cur = RLIM_INFINITY;
+ if (r.rlim_max == RLIM_INFINITY32)
+ r.rlim_max = RLIM_INFINITY;
set_fs (KERNEL_DS);
ret = sys_setrlimit(resource, &r);
set_fs (old_fs);
@@ -1772,28 +1687,6 @@ asmlinkage int sys32_getrusage(int who, u32 ru)
return ret;
}
-extern asmlinkage int sys_time(int * tloc);
-
-asmlinkage int sys32_time(u32 tloc)
-{
- return sys_time((int *)A(tloc));
-}
-
-extern asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_gettimeofday(u32 tv, u32 tz)
-{
- /* both timeval and timezone are ok :)) */
- return sys_gettimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
-extern asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_settimeofday(u32 tv, u32 tz)
-{
- return sys_settimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
struct timex32 {
unsigned int modes;
s32 offset;
@@ -1865,170 +1758,6 @@ asmlinkage int sys32_adjtimex(u32 txc_p)
return ret;
}
-extern asmlinkage int sys_msync(unsigned long start, size_t len, int flags);
-
-asmlinkage int sys32_msync(u32 start, __kernel_size_t32 len, int flags)
-{
- return sys_msync((unsigned long)start, (size_t)len, flags);
-}
-
-extern asmlinkage int sys_mlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_mlock(u32 start, __kernel_size_t32 len)
-{
- return sys_mlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage int sys_munlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_munlock(u32 start, __kernel_size_t32 len)
-{
- return sys_munlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage unsigned long sys_brk(unsigned long brk);
-
-asmlinkage unsigned long sparc32_brk(u32 brk)
-{
- return sys_brk((unsigned long)brk);
-}
-
-extern asmlinkage int sys_munmap(unsigned long addr, size_t len);
-
-asmlinkage int sys32_munmap(u32 addr, __kernel_size_t32 len)
-{
- return sys_munmap((unsigned long)addr, (size_t)len);
-}
-
-extern asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot);
-
-asmlinkage int sys32_mprotect(u32 start, __kernel_size_t32 len, u32 prot)
-{
- return sys_mprotect((unsigned long)start, (size_t)len, (unsigned long)prot);
-}
-
-extern asmlinkage unsigned long sys_mremap(unsigned long addr, unsigned long old_len,
- unsigned long new_len, unsigned long flags);
-
-asmlinkage unsigned long sys32_mremap(u32 addr, u32 old_len, u32 new_len, u32 flags)
-{
- return sys_mremap((unsigned long)addr, (unsigned long)old_len,
- (unsigned long)new_len, (unsigned long)flags);
-}
-
-extern asmlinkage int sys_swapoff(const char * specialfile);
-
-asmlinkage int sys32_swapoff(u32 specialfile)
-{
- return sys_swapoff((const char *)A(specialfile));
-}
-
-extern asmlinkage int sys_swapon(const char * specialfile, int swap_flags);
-
-asmlinkage int sys32_swapon(u32 specialfile, int swap_flags)
-{
- return sys_swapon((const char *)A(specialfile), swap_flags);
-}
-
-extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-
-asmlinkage inline int sys32_bind(int fd, u32 umyaddr, int addrlen)
-{
- /* sockaddr is the same :)) */
- return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen);
-}
-
-extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr,
- int *upeer_addrlen);
-
-asmlinkage inline int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen)
-{
- return sys_accept(fd, (struct sockaddr *)A(upeer_sockaddr),
- (int *)A(upeer_addrlen));
-}
-
-extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
-
-asmlinkage inline int sys32_connect(int fd, u32 uservaddr, int addrlen)
-{
- return sys_connect(fd, (struct sockaddr *)A(uservaddr), addrlen);
-}
-
-extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-
-asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len)
-{
- return sys_getsockname(fd, (struct sockaddr *)A(usockaddr),
- (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-
-asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len)
-{
- return sys_getpeername(fd, (struct sockaddr *)A(usockaddr),
- (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_send(int fd, void * buff, size_t len, unsigned flags);
-
-asmlinkage inline int sys32_send(int fd, u32 buff,
- __kernel_size_t32 len, unsigned flags)
-{
- return sys_send(fd, (void *)A(buff), (size_t)len, flags);
-}
-
-extern asmlinkage int sys_sendto(int fd, void * buff, size_t len, unsigned flags,
- struct sockaddr *addr, int addr_len);
-
-asmlinkage inline int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
- unsigned flags, u32 addr, int addr_len)
-{
- return sys_sendto(fd, (void *)A(buff), (size_t)len, flags,
- (struct sockaddr *)A(addr), addr_len);
-}
-
-extern asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags);
-
-asmlinkage inline int sys32_recv(int fd, u32 ubuf,
- __kernel_size_t32 size, unsigned flags)
-{
- return sys_recv(fd, (void *)A(ubuf), (size_t)size, flags);
-}
-
-extern asmlinkage int sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
- struct sockaddr *addr, int *addr_len);
-
-asmlinkage inline int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
- unsigned flags, u32 addr, u32 addr_len)
-{
- return sys_recvfrom(fd, (void *)A(ubuf), (size_t)size, flags,
- (struct sockaddr *)A(addr), (int *)A(addr_len));
-}
-
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
- char *optval, int optlen);
-
-asmlinkage inline int sys32_setsockopt(int fd, int level, int optname,
- u32 optval, int optlen)
-{
- /* XXX handle ip_fw32->ip_fw conversion for IP firewalling and accounting.
- Do it using some macro in ip_sockglue.c
- Other optval arguments are mostly just ints or 32<->64bit transparent */
- return sys_setsockopt(fd, level, optname, (char *)A(optval), optlen);
-}
-
-extern asmlinkage int sys_getsockopt(int fd, int level, int optname,
- char *optval, int *optlen);
-
-asmlinkage inline int sys32_getsockopt(int fd, int level, int optname,
- u32 optval, u32 optlen)
-{
- return sys_getsockopt(fd, level, optname, (char *)A(optval), (int *)A(optlen));
-}
-
/* XXX This really belongs in some header file... -DaveM */
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
@@ -2052,11 +1781,11 @@ extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
return NULL;
}
- inode = file->f_inode;
+ inode = file->f_dentry->d_inode;
if (!inode || !inode->i_sock || !socki_lookup(inode))
{
*err = -ENOTSOCK;
- fput(file,inode);
+ fput(file);
return NULL;
}
@@ -2065,7 +1794,7 @@ extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
extern __inline__ void sockfd_put(struct socket *sock)
{
- fput(sock->file,sock->inode);
+ fput(sock->file);
}
struct msghdr32 {
@@ -2293,6 +2022,24 @@ static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
#undef AL
+extern asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen);
+extern asmlinkage int sys32_connect(int fd, u32 uservaddr, int addrlen);
+extern asmlinkage int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen);
+extern asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_send(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags);
+extern asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags, u32 addr, int addr_len);
+extern asmlinkage int sys32_recv(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags);
+extern asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags, u32 addr, u32 addr_len);
+extern asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+ u32 optval, int optlen);
+extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
+ u32 optval, u32 optlen);
+
extern asmlinkage int sys_socket(int family, int type, int protocol);
extern asmlinkage int sys_socketpair(int family, int type, int protocol,
int usockvec[2]);
@@ -2389,7 +2136,7 @@ asmlinkage int sparc32_sigaction (int signum, u32 action, u32 oldaction)
old_sa.sa_mask = (sigset_t32)(p->sa_mask);
old_sa.sa_flags = (unsigned)(p->sa_flags);
old_sa.sa_restorer = (unsigned)(u64)(p->sa_restorer);
- if (copy_to_user(A(oldaction), p, sizeof(struct sigaction32)))
+ if (copy_to_user(A(oldaction), &old_sa, sizeof(struct sigaction32)))
goto out;
}
@@ -2407,14 +2154,6 @@ out:
return err;
}
-extern asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp);
-
-asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp)
-{
- /* XXX handle argp and resp args */
- return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp));
-}
-
/*
* count32() counts the number of arguments/envelopes
*/
@@ -2485,25 +2224,33 @@ static inline int
do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
{
struct linux_binprm bprm;
+ struct dentry * dentry;
int retval;
int i;
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
bprm.page[i] = 0;
- retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
- if (retval)
+
+ dentry = open_namei(filename, 0, 0);
+ retval = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
return retval;
+
+ bprm.dentry = dentry;
bprm.filename = filename;
bprm.sh_bang = 0;
bprm.java = 0;
bprm.loader = 0;
bprm.exec = 0;
- bprm.dont_iput = 0;
- if ((bprm.argc = count32(argv)) < 0)
+ if ((bprm.argc = count32(argv)) < 0) {
+ dput(dentry);
return bprm.argc;
- if ((bprm.envc = count32(envp)) < 0)
+ }
+ if ((bprm.envc = count32(envp)) < 0) {
+ dput(dentry);
return bprm.envc;
+ }
retval = prepare_binprm(&bprm);
@@ -2523,8 +2270,9 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
return retval;
/* Something went wrong, return the inode and free the argument pages*/
- if(!bprm.dont_iput)
- iput(bprm.inode);
+ if(bprm.dentry)
+ dput(bprm.dentry);
+
for (i=0 ; i<MAX_ARG_PAGES ; i++)
free_page(bprm.page[i]);
return(retval);
@@ -2543,81 +2291,231 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
if((u32)regs->u_regs[UREG_G1] == 0)
base = 1;
- error = getname((char *)(unsigned long)(u32)regs->u_regs[base + UREG_I0], &filename);
- if(error)
- return error;
+ lock_kernel();
+ filename = getname((char *)(unsigned long)(u32)regs->u_regs[base + UREG_I0]);
+ error = PTR_ERR(filename);
+ if(IS_ERR(filename))
+ goto out;
error = do_execve32(filename,
(u32 *)A((u32)regs->u_regs[base + UREG_I1]),
(u32 *)A((u32)regs->u_regs[base + UREG_I2]), regs);
putname(filename);
+
+ if(!error) {
+ fprs_write(0);
+ regs->fprs = 0;
+ }
+out:
+ unlock_kernel();
return error;
}
-/* Modules will be supported with 64bit modutils only */
-asmlinkage int sys32_no_modules(void)
+#ifdef CONFIG_MODULES
+
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
+
+asmlinkage unsigned long sys32_create_module(u32 name_user, __kernel_size_t32 size)
{
- return -ENOSYS;
+ return sys_create_module((const char *)A(name_user), (size_t)size);
}
-struct ncp_mount_data32 {
- int version;
- unsigned int ncp_fd;
- __kernel_uid_t32 mounted_uid;
- __kernel_pid_t32 wdog_pid;
- unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
- unsigned int time_out;
- unsigned int retry_count;
- unsigned int flags;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_mode_t32 file_mode;
- __kernel_mode_t32 dir_mode;
-};
+extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
-void *do_ncp_super_data_conv(void *raw_data)
+/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
+ * module structure, even if from 32bit modutils... Why to pollute kernel... :))
+ */
+asmlinkage int sys32_init_module(u32 nameuser, u32 mod_user)
{
- struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
- struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+ return sys_init_module((const char *)A(nameuser), (struct module *)A(mod_user));
+}
- 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;
+extern asmlinkage int sys_delete_module(const char *name_user);
+
+asmlinkage int sys32_delete_module(u32 name_user)
+{
+ return sys_delete_module((const char *)A(name_user));
}
-struct smb_mount_data32 {
- int version;
- unsigned int fd;
- __kernel_uid_t32 mounted_uid;
- struct sockaddr_in addr;
- char server_name[17];
- char client_name[17];
- char service[64];
- char root_path[64];
- char username[64];
- char password[64];
- char domain[64];
- unsigned short max_xmit;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_mode_t32 file_mode;
- __kernel_mode_t32 dir_mode;
+struct module_info32 {
+ u32 addr;
+ u32 size;
+ u32 flags;
+ s32 usecount;
};
-void *do_smb_super_data_conv(void *raw_data)
+extern asmlinkage int sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret);
+
+asmlinkage int sys32_query_module(u32 name_user, int which, u32 buf, __kernel_size_t32 bufsize, u32 retv)
{
- struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
- struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
+ char *buff;
+ unsigned long old_fs = get_fs();
+ size_t val;
+ int ret, i, j;
+ unsigned long *p;
+ char *usernam = NULL;
+ int bufsiz = bufsize;
+ struct module_info mi;
+
+ switch (which) {
+ case 0: return sys_query_module ((const char *)A(name_user), which, (char *)A(buf), (size_t)bufsize, (size_t *)A(retv));
+ case QM_SYMBOLS:
+ bufsiz <<= 1;
+ case QM_MODULES:
+ case QM_REFS:
+ case QM_DEPS:
+ if (name_user && (ret = getname32 (name_user, &usernam)))
+ return ret;
+ buff = kmalloc (bufsiz, GFP_KERNEL);
+ if (!buff) {
+ if (name_user) putname32 (usernam);
+ return -ENOMEM;
+ }
+qmsym_toshort:
+ set_fs (KERNEL_DS);
+ ret = sys_query_module (usernam, which, buff, bufsiz, &val);
+ set_fs (old_fs);
+ if (which != QM_SYMBOLS) {
+ if (ret == -ENOSPC || !ret) {
+ if (put_user (val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ if (!ret) {
+ if (copy_to_user ((char *)A(buf), buff, bufsize))
+ ret = -EFAULT;
+ }
+ } else {
+ if (ret == -ENOSPC) {
+ if (put_user (2 * val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ p = (unsigned long *)buff;
+ if (!ret) {
+ if (put_user (val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ if (!ret) {
+ j = val * 8;
+ for (i = 0; i < val; i++, p += 2) {
+ if (bufsize < (2 * sizeof (u32))) {
+ bufsiz = 0;
+ goto qmsym_toshort;
+ }
+ if (put_user (p[0], (u32 *)A(buf)) ||
+ __put_user (p[1] - j, (((u32 *)A(buf))+1))) {
+ ret = -EFAULT;
+ break;
+ }
+ bufsize -= (2 * sizeof (u32));
+ buf += (2 * sizeof (u32));
+ }
+ }
+ if (!ret && val) {
+ char *strings = buff + ((unsigned long *)buff)[1];
+ j = *(p - 1) - ((unsigned long *)buff)[1];
+ j = j + strlen (buff + j) + 1;
+ if (bufsize < j) {
+ bufsiz = 0;
+ goto qmsym_toshort;
+ }
+ if (copy_to_user ((char *)A(buf), strings, j))
+ ret = -EFAULT;
+ }
+ }
+ kfree (buff);
+ if (name_user) putname32 (usernam);
+ return ret;
+ case QM_INFO:
+ if (name_user && (ret = getname32 (name_user, &usernam)))
+ return ret;
+ set_fs (KERNEL_DS);
+ ret = sys_query_module (usernam, which, (char *)&mi, sizeof (mi), &val);
+ set_fs (old_fs);
+ if (!ret) {
+ if (put_user (sizeof (struct module_info32), (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ else if (bufsize < sizeof (struct module_info32))
+ ret = -ENOSPC;
+ }
+ if (!ret) {
+ if (put_user (mi.addr, &(((struct module_info32 *)A(buf))->addr)) ||
+ __put_user (mi.size, &(((struct module_info32 *)A(buf))->size)) ||
+ __put_user (mi.flags, &(((struct module_info32 *)A(buf))->flags)) ||
+ __put_user (mi.usecount, &(((struct module_info32 *)A(buf))->usecount)))
+ ret = -EFAULT;
+ }
+ if (name_user) putname32 (usernam);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+}
- s->dir_mode = s32->dir_mode;
- s->file_mode = s32->file_mode;
- s->gid = s32->gid;
- s->uid = s32->uid;
- memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
- s->mounted_uid = s32->mounted_uid;
- return raw_data;
+struct kernel_sym32 {
+ u32 value;
+ char name[60];
+};
+
+extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage int sys32_get_kernel_syms(u32 table)
+{
+ int len, i;
+ struct kernel_sym *tbl;
+ unsigned long old_fs;
+
+ len = sys_get_kernel_syms(NULL);
+ if (!table) return len;
+ tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+ if (!tbl) return -ENOMEM;
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ sys_get_kernel_syms(tbl);
+ set_fs (old_fs);
+ for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
+ if (put_user (tbl[i].value, &(((struct kernel_sym32 *)A(table))->value)) ||
+ copy_to_user (((struct kernel_sym32 *)A(table))->name, tbl[i].name, 60))
+ break;
+ }
+ kfree (tbl);
+ return i;
+}
+
+#else /* CONFIG_MODULES */
+
+asmlinkage unsigned long
+sys_create_module(const char *name_user, size_t size)
+{
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_init_module(const char *name_user, struct module *mod_user)
+{
+ return -ENOSYS;
}
+
+asmlinkage int
+sys_delete_module(const char *name_user)
+{
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
+ size_t *ret)
+{
+ /* Let the program know about the new interface. Not that
+ it'll do them much good. */
+ if (which == 0)
+ return 0;
+
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_get_kernel_syms(struct kernel_sym *table)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_MODULES */