aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 075d0509970d..cb36245f9fe0 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -137,6 +137,45 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
137 return compat_sys_futimesat(AT_FDCWD, filename, t); 137 return compat_sys_futimesat(AT_FDCWD, filename, t);
138} 138}
139 139
140static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
141{
142 compat_ino_t ino = stat->ino;
143 typeof(ubuf->st_uid) uid = 0;
144 typeof(ubuf->st_gid) gid = 0;
145 int err;
146
147 SET_UID(uid, stat->uid);
148 SET_GID(gid, stat->gid);
149
150 if ((u64) stat->size > MAX_NON_LFS ||
151 !old_valid_dev(stat->dev) ||
152 !old_valid_dev(stat->rdev))
153 return -EOVERFLOW;
154 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
155 return -EOVERFLOW;
156
157 if (clear_user(ubuf, sizeof(*ubuf)))
158 return -EFAULT;
159
160 err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
161 err |= __put_user(ino, &ubuf->st_ino);
162 err |= __put_user(stat->mode, &ubuf->st_mode);
163 err |= __put_user(stat->nlink, &ubuf->st_nlink);
164 err |= __put_user(uid, &ubuf->st_uid);
165 err |= __put_user(gid, &ubuf->st_gid);
166 err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
167 err |= __put_user(stat->size, &ubuf->st_size);
168 err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
169 err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
170 err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
171 err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
172 err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
173 err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
174 err |= __put_user(stat->blksize, &ubuf->st_blksize);
175 err |= __put_user(stat->blocks, &ubuf->st_blocks);
176 return err;
177}
178
140asmlinkage long compat_sys_newstat(char __user * filename, 179asmlinkage long compat_sys_newstat(char __user * filename,
141 struct compat_stat __user *statbuf) 180 struct compat_stat __user *statbuf)
142{ 181{
@@ -830,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
830 buf.dirent = dirent; 869 buf.dirent = dirent;
831 870
832 error = vfs_readdir(file, compat_fillonedir, &buf); 871 error = vfs_readdir(file, compat_fillonedir, &buf);
833 if (error >= 0) 872 if (buf.result)
834 error = buf.result; 873 error = buf.result;
835 874
836 fput(file); 875 fput(file);
@@ -917,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
917 buf.error = 0; 956 buf.error = 0;
918 957
919 error = vfs_readdir(file, compat_filldir, &buf); 958 error = vfs_readdir(file, compat_filldir, &buf);
920 if (error < 0) 959 if (error >= 0)
921 goto out_putf; 960 error = buf.error;
922 error = buf.error;
923 lastdirent = buf.previous; 961 lastdirent = buf.previous;
924 if (lastdirent) { 962 if (lastdirent) {
925 if (put_user(file->f_pos, &lastdirent->d_off)) 963 if (put_user(file->f_pos, &lastdirent->d_off))
@@ -927,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
927 else 965 else
928 error = count - buf.count; 966 error = count - buf.count;
929 } 967 }
930
931out_putf:
932 fput(file); 968 fput(file);
933out: 969out:
934 return error; 970 return error;
@@ -1008,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
1008 buf.error = 0; 1044 buf.error = 0;
1009 1045
1010 error = vfs_readdir(file, compat_filldir64, &buf); 1046 error = vfs_readdir(file, compat_filldir64, &buf);
1011 if (error < 0) 1047 if (error >= 0)
1012 goto out_putf; 1048 error = buf.error;
1013 error = buf.error;
1014 lastdirent = buf.previous; 1049 lastdirent = buf.previous;
1015 if (lastdirent) { 1050 if (lastdirent) {
1016 typeof(lastdirent->d_off) d_off = file->f_pos; 1051 typeof(lastdirent->d_off) d_off = file->f_pos;
1017 error = -EFAULT;
1018 if (__put_user_unaligned(d_off, &lastdirent->d_off)) 1052 if (__put_user_unaligned(d_off, &lastdirent->d_off))
1019 goto out_putf; 1053 error = -EFAULT;
1020 error = count - buf.count; 1054 else
1055 error = count - buf.count;
1021 } 1056 }
1022
1023out_putf:
1024 fput(file); 1057 fput(file);
1025out: 1058out:
1026 return error; 1059 return error;
@@ -1239,7 +1272,7 @@ static int compat_count(compat_uptr_t __user *argv, int max)
1239 if (!p) 1272 if (!p)
1240 break; 1273 break;
1241 argv++; 1274 argv++;
1242 if(++i > max) 1275 if (i++ >= max)
1243 return -E2BIG; 1276 return -E2BIG;
1244 } 1277 }
1245 } 1278 }