aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c85
1 files changed, 29 insertions, 56 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 6490d2134ff3..52cfeb61da77 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -8,13 +8,14 @@
8 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) 8 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
9 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) 9 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
10 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs 10 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
11 * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) 11 * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16 */ 16 */
17 17
18#include <linux/stddef.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/linkage.h> 20#include <linux/linkage.h>
20#include <linux/compat.h> 21#include <linux/compat.h>
@@ -28,8 +29,6 @@
28#include <linux/vfs.h> 29#include <linux/vfs.h>
29#include <linux/ioctl.h> 30#include <linux/ioctl.h>
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/smb.h>
32#include <linux/smb_mount.h>
33#include <linux/ncp_mount.h> 32#include <linux/ncp_mount.h>
34#include <linux/nfs4_mount.h> 33#include <linux/nfs4_mount.h>
35#include <linux/syscalls.h> 34#include <linux/syscalls.h>
@@ -76,7 +75,8 @@ int compat_printk(const char *fmt, ...)
76 * Not all architectures have sys_utime, so implement this in terms 75 * Not all architectures have sys_utime, so implement this in terms
77 * of sys_utimes. 76 * of sys_utimes.
78 */ 77 */
79asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) 78asmlinkage long compat_sys_utime(const char __user *filename,
79 struct compat_utimbuf __user *t)
80{ 80{
81 struct timespec tv[2]; 81 struct timespec tv[2];
82 82
@@ -90,7 +90,7 @@ asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __
90 return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); 90 return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
91} 91}
92 92
93asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags) 93asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename, struct compat_timespec __user *t, int flags)
94{ 94{
95 struct timespec tv[2]; 95 struct timespec tv[2];
96 96
@@ -105,7 +105,7 @@ asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, st
105 return do_utimes(dfd, filename, t ? tv : NULL, flags); 105 return do_utimes(dfd, filename, t ? tv : NULL, flags);
106} 106}
107 107
108asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) 108asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename, struct compat_timeval __user *t)
109{ 109{
110 struct timespec tv[2]; 110 struct timespec tv[2];
111 111
@@ -124,7 +124,7 @@ asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, st
124 return do_utimes(dfd, filename, t ? tv : NULL, 0); 124 return do_utimes(dfd, filename, t ? tv : NULL, 0);
125} 125}
126 126
127asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) 127asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_timeval __user *t)
128{ 128{
129 return compat_sys_futimesat(AT_FDCWD, filename, t); 129 return compat_sys_futimesat(AT_FDCWD, filename, t);
130} 130}
@@ -168,7 +168,7 @@ static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
168 return err; 168 return err;
169} 169}
170 170
171asmlinkage long compat_sys_newstat(char __user * filename, 171asmlinkage long compat_sys_newstat(const char __user * filename,
172 struct compat_stat __user *statbuf) 172 struct compat_stat __user *statbuf)
173{ 173{
174 struct kstat stat; 174 struct kstat stat;
@@ -180,7 +180,7 @@ asmlinkage long compat_sys_newstat(char __user * filename,
180 return cp_compat_stat(&stat, statbuf); 180 return cp_compat_stat(&stat, statbuf);
181} 181}
182 182
183asmlinkage long compat_sys_newlstat(char __user * filename, 183asmlinkage long compat_sys_newlstat(const char __user * filename,
184 struct compat_stat __user *statbuf) 184 struct compat_stat __user *statbuf)
185{ 185{
186 struct kstat stat; 186 struct kstat stat;
@@ -193,7 +193,8 @@ asmlinkage long compat_sys_newlstat(char __user * filename,
193} 193}
194 194
195#ifndef __ARCH_WANT_STAT64 195#ifndef __ARCH_WANT_STAT64
196asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, 196asmlinkage long compat_sys_newfstatat(unsigned int dfd,
197 const char __user *filename,
197 struct compat_stat __user *statbuf, int flag) 198 struct compat_stat __user *statbuf, int flag)
198{ 199{
199 struct kstat stat; 200 struct kstat stat;
@@ -266,7 +267,7 @@ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_sta
266 error = user_path(pathname, &path); 267 error = user_path(pathname, &path);
267 if (!error) { 268 if (!error) {
268 struct kstatfs tmp; 269 struct kstatfs tmp;
269 error = vfs_statfs(path.dentry, &tmp); 270 error = vfs_statfs(&path, &tmp);
270 if (!error) 271 if (!error)
271 error = put_compat_statfs(buf, &tmp); 272 error = put_compat_statfs(buf, &tmp);
272 path_put(&path); 273 path_put(&path);
@@ -284,7 +285,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
284 file = fget(fd); 285 file = fget(fd);
285 if (!file) 286 if (!file)
286 goto out; 287 goto out;
287 error = vfs_statfs(file->f_path.dentry, &tmp); 288 error = vfs_statfs(&file->f_path, &tmp);
288 if (!error) 289 if (!error)
289 error = put_compat_statfs(buf, &tmp); 290 error = put_compat_statfs(buf, &tmp);
290 fput(file); 291 fput(file);
@@ -334,7 +335,7 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t s
334 error = user_path(pathname, &path); 335 error = user_path(pathname, &path);
335 if (!error) { 336 if (!error) {
336 struct kstatfs tmp; 337 struct kstatfs tmp;
337 error = vfs_statfs(path.dentry, &tmp); 338 error = vfs_statfs(&path, &tmp);
338 if (!error) 339 if (!error)
339 error = put_compat_statfs64(buf, &tmp); 340 error = put_compat_statfs64(buf, &tmp);
340 path_put(&path); 341 path_put(&path);
@@ -355,7 +356,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
355 file = fget(fd); 356 file = fget(fd);
356 if (!file) 357 if (!file)
357 goto out; 358 goto out;
358 error = vfs_statfs(file->f_path.dentry, &tmp); 359 error = vfs_statfs(&file->f_path, &tmp);
359 if (!error) 360 if (!error)
360 error = put_compat_statfs64(buf, &tmp); 361 error = put_compat_statfs64(buf, &tmp);
361 fput(file); 362 fput(file);
@@ -378,7 +379,7 @@ asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u)
378 sb = user_get_super(new_decode_dev(dev)); 379 sb = user_get_super(new_decode_dev(dev));
379 if (!sb) 380 if (!sb)
380 return -EINVAL; 381 return -EINVAL;
381 err = vfs_statfs(sb->s_root, &sbuf); 382 err = statfs_by_dentry(sb->s_root, &sbuf);
382 drop_super(sb); 383 drop_super(sb);
383 if (err) 384 if (err)
384 return err; 385 return err;
@@ -742,30 +743,6 @@ static void *do_ncp_super_data_conv(void *raw_data)
742 return raw_data; 743 return raw_data;
743} 744}
744 745
745struct compat_smb_mount_data {
746 compat_int_t version;
747 __compat_uid_t mounted_uid;
748 __compat_uid_t uid;
749 __compat_gid_t gid;
750 compat_mode_t file_mode;
751 compat_mode_t dir_mode;
752};
753
754static void *do_smb_super_data_conv(void *raw_data)
755{
756 struct smb_mount_data *s = raw_data;
757 struct compat_smb_mount_data *c_s = raw_data;
758
759 if (c_s->version != SMB_MOUNT_OLDVERSION)
760 goto out;
761 s->dir_mode = c_s->dir_mode;
762 s->file_mode = c_s->file_mode;
763 s->gid = c_s->gid;
764 s->uid = c_s->uid;
765 s->mounted_uid = c_s->mounted_uid;
766 out:
767 return raw_data;
768}
769 746
770struct compat_nfs_string { 747struct compat_nfs_string {
771 compat_uint_t len; 748 compat_uint_t len;
@@ -832,13 +809,13 @@ static int do_nfs4_super_data_conv(void *raw_data)
832 return 0; 809 return 0;
833} 810}
834 811
835#define SMBFS_NAME "smbfs"
836#define NCPFS_NAME "ncpfs" 812#define NCPFS_NAME "ncpfs"
837#define NFS4_NAME "nfs4" 813#define NFS4_NAME "nfs4"
838 814
839asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, 815asmlinkage long compat_sys_mount(const char __user * dev_name,
840 char __user * type, unsigned long flags, 816 const char __user * dir_name,
841 void __user * data) 817 const char __user * type, unsigned long flags,
818 const void __user * data)
842{ 819{
843 char *kernel_type; 820 char *kernel_type;
844 unsigned long data_page; 821 unsigned long data_page;
@@ -866,9 +843,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
866 retval = -EINVAL; 843 retval = -EINVAL;
867 844
868 if (kernel_type && data_page) { 845 if (kernel_type && data_page) {
869 if (!strcmp(kernel_type, SMBFS_NAME)) { 846 if (!strcmp(kernel_type, NCPFS_NAME)) {
870 do_smb_super_data_conv((void *)data_page);
871 } else if (!strcmp(kernel_type, NCPFS_NAME)) {
872 do_ncp_super_data_conv((void *)data_page); 847 do_ncp_super_data_conv((void *)data_page);
873 } else if (!strcmp(kernel_type, NFS4_NAME)) { 848 } else if (!strcmp(kernel_type, NFS4_NAME)) {
874 if (do_nfs4_super_data_conv((void *) data_page)) 849 if (do_nfs4_super_data_conv((void *) data_page))
@@ -891,8 +866,6 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
891 return retval; 866 return retval;
892} 867}
893 868
894#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
895
896struct compat_old_linux_dirent { 869struct compat_old_linux_dirent {
897 compat_ulong_t d_ino; 870 compat_ulong_t d_ino;
898 compat_ulong_t d_offset; 871 compat_ulong_t d_offset;
@@ -981,7 +954,8 @@ static int compat_filldir(void *__buf, const char *name, int namlen,
981 struct compat_linux_dirent __user * dirent; 954 struct compat_linux_dirent __user * dirent;
982 struct compat_getdents_callback *buf = __buf; 955 struct compat_getdents_callback *buf = __buf;
983 compat_ulong_t d_ino; 956 compat_ulong_t d_ino;
984 int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t)); 957 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
958 namlen + 2, sizeof(compat_long_t));
985 959
986 buf->error = -EINVAL; /* only used if we fail.. */ 960 buf->error = -EINVAL; /* only used if we fail.. */
987 if (reclen > buf->count) 961 if (reclen > buf->count)
@@ -1068,8 +1042,8 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t
1068{ 1042{
1069 struct linux_dirent64 __user *dirent; 1043 struct linux_dirent64 __user *dirent;
1070 struct compat_getdents_callback64 *buf = __buf; 1044 struct compat_getdents_callback64 *buf = __buf;
1071 int jj = NAME_OFFSET(dirent); 1045 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
1072 int reclen = ALIGN(jj + namlen + 1, sizeof(u64)); 1046 sizeof(u64));
1073 u64 off; 1047 u64 off;
1074 1048
1075 buf->error = -EINVAL; /* only used if we fail.. */ 1049 buf->error = -EINVAL; /* only used if we fail.. */
@@ -1150,7 +1124,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1150{ 1124{
1151 compat_ssize_t tot_len; 1125 compat_ssize_t tot_len;
1152 struct iovec iovstack[UIO_FASTIOV]; 1126 struct iovec iovstack[UIO_FASTIOV];
1153 struct iovec *iov; 1127 struct iovec *iov = iovstack;
1154 ssize_t ret; 1128 ssize_t ret;
1155 io_fn_t fn; 1129 io_fn_t fn;
1156 iov_fn_t fnv; 1130 iov_fn_t fnv;
@@ -1193,11 +1167,10 @@ out:
1193 if (iov != iovstack) 1167 if (iov != iovstack)
1194 kfree(iov); 1168 kfree(iov);
1195 if ((ret + (type == READ)) > 0) { 1169 if ((ret + (type == READ)) > 0) {
1196 struct dentry *dentry = file->f_path.dentry;
1197 if (type == READ) 1170 if (type == READ)
1198 fsnotify_access(dentry); 1171 fsnotify_access(file);
1199 else 1172 else
1200 fsnotify_modify(dentry); 1173 fsnotify_modify(file);
1201 } 1174 }
1202 return ret; 1175 return ret;
1203} 1176}
@@ -1961,7 +1934,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1961} 1934}
1962#endif /* HAVE_SET_RESTORE_SIGMASK */ 1935#endif /* HAVE_SET_RESTORE_SIGMASK */
1963 1936
1964#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) 1937#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && !defined(CONFIG_NFSD_DEPRECATED)
1965/* Stuff for NFS server syscalls... */ 1938/* Stuff for NFS server syscalls... */
1966struct compat_nfsctl_svc { 1939struct compat_nfsctl_svc {
1967 u16 svc32_port; 1940 u16 svc32_port;