aboutsummaryrefslogtreecommitdiff
path: root/arch/parisc/hpux/sys_hpux.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/hpux/sys_hpux.c')
-rw-r--r--arch/parisc/hpux/sys_hpux.c161
1 files changed, 69 insertions, 92 deletions
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index 29b4d61898f..d9dc6cd3b7d 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -28,7 +28,6 @@
#include <linux/namei.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/utsname.h>
#include <linux/vfs.h>
@@ -61,7 +60,7 @@ int hpux_ptrace(void)
return -ENOSYS;
}
-int hpux_wait(int *stat_loc)
+int hpux_wait(int __user *stat_loc)
{
return sys_waitpid(-1, stat_loc, 0);
}
@@ -137,16 +136,9 @@ struct hpux_ustat {
*/
static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
{
- struct super_block *s;
struct hpux_ustat tmp; /* Changed to hpux_ustat */
struct kstatfs sbuf;
- int err = -EINVAL;
-
- s = user_get_super(dev);
- if (s == NULL)
- goto out;
- err = vfs_statfs(s, &sbuf);
- drop_super(s);
+ int err = vfs_ustat(dev, &sbuf);
if (err)
goto out;
@@ -186,62 +178,41 @@ struct hpux_statfs {
int16_t f_pad;
};
-static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf)
+static int do_statfs_hpux(struct kstatfs *st, struct hpux_statfs __user *p)
{
- struct kstatfs st;
- int retval;
-
- retval = vfs_statfs(sb, &st);
- if (retval)
- return retval;
-
- memset(buf, 0, sizeof(*buf));
- buf->f_type = st.f_type;
- buf->f_bsize = st.f_bsize;
- buf->f_blocks = st.f_blocks;
- buf->f_bfree = st.f_bfree;
- buf->f_bavail = st.f_bavail;
- buf->f_files = st.f_files;
- buf->f_ffree = st.f_ffree;
- buf->f_fsid[0] = st.f_fsid.val[0];
- buf->f_fsid[1] = st.f_fsid.val[1];
-
+ struct hpux_statfs buf;
+ memset(&buf, 0, sizeof(buf));
+ buf.f_type = st->f_type;
+ buf.f_bsize = st->f_bsize;
+ buf.f_blocks = st->f_blocks;
+ buf.f_bfree = st->f_bfree;
+ buf.f_bavail = st->f_bavail;
+ buf.f_files = st->f_files;
+ buf.f_ffree = st->f_ffree;
+ buf.f_fsid[0] = st->f_fsid.val[0];
+ buf.f_fsid[1] = st->f_fsid.val[1];
+ if (copy_to_user(p, &buf, sizeof(buf)))
+ return -EFAULT;
return 0;
}
/* hpux statfs */
-asmlinkage long hpux_statfs(const char __user *path,
+asmlinkage long hpux_statfs(const char __user *pathname,
struct hpux_statfs __user *buf)
{
- struct nameidata nd;
- int error;
-
- error = user_path_walk(path, &nd);
- if (!error) {
- struct hpux_statfs tmp;
- error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp);
- if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
- error = -EFAULT;
- path_release(&nd);
- }
+ struct kstatfs st;
+ int error = user_statfs(pathname, &st);
+ if (!error)
+ error = do_statfs_hpux(&st, buf);
return error;
}
asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
{
- struct file *file;
- struct hpux_statfs tmp;
- int error;
-
- error = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
- error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp);
- if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
- error = -EFAULT;
- fput(file);
- out:
+ struct kstatfs st;
+ int error = fd_statfs(fd, &st);
+ if (!error)
+ error = do_statfs_hpux(&st, buf);
return error;
}
@@ -255,7 +226,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
/* TODO: Are these put_user calls OK? Should they pass an int?
* (I copied it from sys_i386.c like this.)
*/
-static int hpux_uname(struct hpux_utsname *name)
+static int hpux_uname(struct hpux_utsname __user *name)
{
int error;
@@ -266,16 +237,21 @@ static int hpux_uname(struct hpux_utsname *name)
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
- error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
- error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
- error |= __put_user(0,name->release+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
- error |= __put_user(0,name->version+HPUX_UTSLEN-1);
- error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
- error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->release, &utsname()->release,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->version, &utsname()->version,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
+ HPUX_UTSLEN - 1);
+ error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
up_read(&uts_sem);
@@ -295,14 +271,14 @@ static int hpux_uname(struct hpux_utsname *name)
/* Note: HP-UX just uses the old suser() function to check perms
* in this system call. We'll use capable(CAP_SYS_ADMIN).
*/
-int hpux_utssys(char *ubuf, int n, int type)
+int hpux_utssys(char __user *ubuf, int n, int type)
{
int len;
int error;
switch( type ) {
case 0:
/* uname(): */
- return( hpux_uname( (struct hpux_utsname *)ubuf ) );
+ return hpux_uname((struct hpux_utsname __user *)ubuf);
break ;
case 1:
/* Obsolete (used to be umask().) */
@@ -310,8 +286,9 @@ int hpux_utssys(char *ubuf, int n, int type)
break ;
case 2:
/* ustat(): */
- return( hpux_ustat(new_decode_dev(n), (struct hpux_ustat *)ubuf) );
- break ;
+ return hpux_ustat(new_decode_dev(n),
+ (struct hpux_ustat __user *)ubuf);
+ break;
case 3:
/* setuname():
*
@@ -327,7 +304,7 @@ int hpux_utssys(char *ubuf, int n, int type)
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- return( sys_sethostname(ubuf, len) );
+ return sys_sethostname(ubuf, len);
break ;
case 4:
/* sethostname():
@@ -341,7 +318,7 @@ int hpux_utssys(char *ubuf, int n, int type)
return -EINVAL ;
/* Unlike Linux, HP-UX truncates it if n is too big: */
len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- return( sys_sethostname(ubuf, len) );
+ return sys_sethostname(ubuf, len);
break ;
case 5:
/* gethostname():
@@ -351,7 +328,7 @@ int hpux_utssys(char *ubuf, int n, int type)
/* Unlike Linux, HP-UX returns an error if n==0: */
if ( n <= 0 )
return -EINVAL ;
- return( sys_gethostname(ubuf, n) );
+ return sys_gethostname(ubuf, n);
break ;
case 6:
/* Supposedly called from setuname() in libc.
@@ -373,8 +350,8 @@ int hpux_utssys(char *ubuf, int n, int type)
/* TODO: print a warning about using this? */
down_write(&uts_sem);
error = -EFAULT;
- if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
- system_utsname.sysname[len] = 0;
+ if (!copy_from_user(utsname()->sysname, ubuf, len)) {
+ utsname()->sysname[len] = 0;
error = 0;
}
up_write(&uts_sem);
@@ -400,8 +377,8 @@ int hpux_utssys(char *ubuf, int n, int type)
/* TODO: print a warning about this? */
down_write(&uts_sem);
error = -EFAULT;
- if (!copy_from_user(system_utsname.release, ubuf, len)) {
- system_utsname.release[len] = 0;
+ if (!copy_from_user(utsname()->release, ubuf, len)) {
+ utsname()->release[len] = 0;
error = 0;
}
up_write(&uts_sem);
@@ -415,20 +392,20 @@ int hpux_utssys(char *ubuf, int n, int type)
}
}
-int hpux_getdomainname(char *name, int len)
+int hpux_getdomainname(char __user *name, int len)
{
int nlen;
int err = -EFAULT;
down_read(&uts_sem);
- nlen = strlen(system_utsname.domainname) + 1;
+ nlen = strlen(utsname()->domainname) + 1;
if (nlen < len)
len = nlen;
if(len > __NEW_UTS_LEN)
goto done;
- if(copy_to_user(name, system_utsname.domainname, len))
+ if(copy_to_user(name, utsname()->domainname, len))
goto done;
err = 0;
done:
@@ -439,12 +416,7 @@ done:
int hpux_pipe(int *kstack_fildes)
{
- int error;
-
- lock_kernel();
- error = do_pipe(kstack_fildes);
- unlock_kernel();
- return error;
+ return do_pipe_flags(kstack_fildes, 0);
}
/* lies - says it works, but it really didn't lock anything */
@@ -466,27 +438,32 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
if ( opcode == 1 ) { /* GETFSIND */
- len = strlen_user((char *)arg1);
+ char __user *user_fsname = (char __user *)arg1;
+ len = strlen_user(user_fsname);
printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
- fsname = (char *) kmalloc(len+1, GFP_KERNEL);
- if ( !fsname ) {
+ if (len == 0)
+ return 0;
+ fsname = kmalloc(len, GFP_KERNEL);
+ if (!fsname) {
printk(KERN_DEBUG "failed to kmalloc fsname\n");
return 0;
}
- if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+ if (copy_from_user(fsname, user_fsname, len)) {
printk(KERN_DEBUG "failed to copy_from_user fsname\n");
kfree(fsname);
return 0;
}
+ /* String could be altered by userspace after strlen_user() */
+ fsname[len] = '\0';
+
printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
if ( !strcmp(fsname, "hfs") ) {
fstype = 0;
} else {
fstype = 0;
- };
+ }
kfree(fsname);
@@ -500,7 +477,7 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
/* Table of syscall names and handle for unimplemented routines */
-static const char *syscall_names[] = {
+static const char * const syscall_names[] = {
"nosys", /* 0 */
"exit",
"fork",