* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/capability.h>
+#include <linux/file.h>
#include <linux/fs.h>
+#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/vmalloc.h>
#include <linux/vfs.h>
+#include <linux/vmalloc.h>
+#include <linux/vs_cvirt.h>
#include <asm/errno.h>
#include <asm/pgalloc.h>
int hpux_setpgrp(void)
{
- extern int sys_setpgid(int, int);
return sys_setpgid(0,0);
}
* aid in porting forward if and when sys_ustat() is changed from
* its form in kernel 2.2.5.
*/
-static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf)
+static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
{
struct super_block *s;
struct hpux_ustat tmp; /* Changed to hpux_ustat */
s = user_get_super(dev);
if (s == NULL)
goto out;
- err = vfs_statfs(s, &sbuf);
+ err = vfs_statfs(s->s_root, &sbuf);
drop_super(s);
if (err)
goto out;
- memset(&tmp,0,sizeof(struct hpux_ustat)); /* Changed to hpux_ustat */
+ memset(&tmp,0,sizeof(tmp));
tmp.f_tfree = (int32_t)sbuf.f_bfree;
tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
tmp.f_blksize = (u_int32_t)sbuf.f_bsize; /* Added this line */
- /* Changed to hpux_ustat: */
- err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0;
+ err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
out:
return err;
}
int16_t f_pad;
};
-/* hpux statfs */
-int hpux_statfs(const char *path, struct hpux_statfs *buf)
+static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf)
{
- int error;
- int len;
- char *kpath;
-
- len = strlen_user((char *)path);
-
- kpath = (char *) kmalloc(len+1, GFP_KERNEL);
- if ( !kpath ) {
- printk(KERN_DEBUG "failed to kmalloc kpath\n");
- return 0;
- }
+ struct kstatfs st;
+ int retval;
+
+ retval = vfs_statfs(dentry, &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];
- if ( copy_from_user(kpath, (char *)path, len+1) ) {
- printk(KERN_DEBUG "failed to copy_from_user kpath\n");
- kfree(kpath);
return 0;
- }
-
- printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);
+}
- kfree(kpath);
+/* hpux statfs */
+asmlinkage long hpux_statfs(const char __user *path,
+ struct hpux_statfs __user *buf)
+{
+ struct nameidata nd;
+ int error;
- /* just fake it, beginning of structures match */
- error = sys_statfs(path, (struct statfs *) buf);
+ error = user_path_walk(path, &nd);
+ if (!error) {
+ struct hpux_statfs tmp;
+ error = vfs_statfs_hpux(nd.dentry, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+ error = -EFAULT;
+ path_release(&nd);
+ }
+ return error;
+}
- /* ignoring rest of statfs struct, but it should be zeros. Need to do
- something with f_fsid[1], which is the fstype for sysfs */
+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, &tmp);
+ if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+ error = -EFAULT;
+ fput(file);
+ out:
return error;
}
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
+ error = __copy_to_user(&name->sysname,vx_new_uts(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 |= __copy_to_user(&name->nodename,vx_new_uts(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 |= __copy_to_user(&name->release,vx_new_uts(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 |= __copy_to_user(&name->version,vx_new_uts(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 |= __copy_to_user(&name->machine,vx_new_uts(machine),HPUX_UTSLEN-1);
error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
up_read(&uts_sem);
/* 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(vx_new_uts(sysname), ubuf, len)) {
+ vx_new_uts(sysname)[len] = 0;
error = 0;
}
up_write(&uts_sem);
/* 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(vx_new_uts(release), ubuf, len)) {
+ vx_new_uts(release)[len] = 0;
error = 0;
}
up_write(&uts_sem);
down_read(&uts_sem);
- nlen = strlen(system_utsname.domainname) + 1;
+ nlen = strlen(vx_new_uts(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, vx_new_uts(domainname), len))
goto done;
err = 0;
done:
if ( opcode == 1 ) { /* GETFSIND */
len = strlen_user((char *)arg1);
printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
- fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+ if (len == 0)
+ return 0;
+ fsname = (char *) 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, (char *)arg1, 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;
"setdomainname",
"async_daemon",
"getdirentries", /* 195 */
- "statfs",
- "fstatfs",
+ NULL,
+ NULL,
"vfsmount",
NULL,
"waitpid", /* 200 */