diff options
Diffstat (limited to 'arch/ia64/ia32/sys_ia32.c')
-rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index bddbd22706ed..9d6a3f210148 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use | |||
125 | 125 | ||
126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | 126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) |
127 | { | 127 | { |
128 | compat_ino_t ino; | ||
128 | int err; | 129 | int err; |
129 | 130 | ||
130 | if ((u64) stat->size > MAX_NON_LFS || | 131 | if ((u64) stat->size > MAX_NON_LFS || |
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | |||
132 | !old_valid_dev(stat->rdev)) | 133 | !old_valid_dev(stat->rdev)) |
133 | return -EOVERFLOW; | 134 | return -EOVERFLOW; |
134 | 135 | ||
136 | ino = stat->ino; | ||
137 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
138 | return -EOVERFLOW; | ||
139 | |||
135 | if (clear_user(ubuf, sizeof(*ubuf))) | 140 | if (clear_user(ubuf, sizeof(*ubuf))) |
136 | return -EFAULT; | 141 | return -EFAULT; |
137 | 142 | ||
138 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); | 143 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); |
139 | err |= __put_user(stat->ino, &ubuf->st_ino); | 144 | err |= __put_user(ino, &ubuf->st_ino); |
140 | err |= __put_user(stat->mode, &ubuf->st_mode); | 145 | err |= __put_user(stat->mode, &ubuf->st_mode); |
141 | err |= __put_user(stat->nlink, &ubuf->st_nlink); | 146 | err |= __put_user(stat->nlink, &ubuf->st_nlink); |
142 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); | 147 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); |
@@ -1222,16 +1227,20 @@ struct readdir32_callback { | |||
1222 | }; | 1227 | }; |
1223 | 1228 | ||
1224 | static int | 1229 | static int |
1225 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | 1230 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, |
1226 | unsigned int d_type) | 1231 | unsigned int d_type) |
1227 | { | 1232 | { |
1228 | struct compat_dirent __user * dirent; | 1233 | struct compat_dirent __user * dirent; |
1229 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 1234 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
1230 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); | 1235 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); |
1236 | u32 d_ino; | ||
1231 | 1237 | ||
1232 | buf->error = -EINVAL; /* only used if we fail.. */ | 1238 | buf->error = -EINVAL; /* only used if we fail.. */ |
1233 | if (reclen > buf->count) | 1239 | if (reclen > buf->count) |
1234 | return -EINVAL; | 1240 | return -EINVAL; |
1241 | d_ino = ino; | ||
1242 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1243 | return -EOVERFLOW; | ||
1235 | buf->error = -EFAULT; /* only used if we fail.. */ | 1244 | buf->error = -EFAULT; /* only used if we fail.. */ |
1236 | dirent = buf->previous; | 1245 | dirent = buf->previous; |
1237 | if (dirent) | 1246 | if (dirent) |
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
1239 | return -EFAULT; | 1248 | return -EFAULT; |
1240 | dirent = buf->current_dir; | 1249 | dirent = buf->current_dir; |
1241 | buf->previous = dirent; | 1250 | buf->previous = dirent; |
1242 | if (put_user(ino, &dirent->d_ino) | 1251 | if (put_user(d_ino, &dirent->d_ino) |
1243 | || put_user(reclen, &dirent->d_reclen) | 1252 | || put_user(reclen, &dirent->d_reclen) |
1244 | || copy_to_user(dirent->d_name, name, namlen) | 1253 | || copy_to_user(dirent->d_name, name, namlen) |
1245 | || put_user(0, dirent->d_name + namlen)) | 1254 | || put_user(0, dirent->d_name + namlen)) |
@@ -1287,17 +1296,21 @@ out: | |||
1287 | } | 1296 | } |
1288 | 1297 | ||
1289 | static int | 1298 | static int |
1290 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, | 1299 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino, |
1291 | unsigned int d_type) | 1300 | unsigned int d_type) |
1292 | { | 1301 | { |
1293 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 1302 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
1294 | struct old_linux32_dirent __user * dirent; | 1303 | struct old_linux32_dirent __user * dirent; |
1304 | u32 d_ino; | ||
1295 | 1305 | ||
1296 | if (buf->count) | 1306 | if (buf->count) |
1297 | return -EINVAL; | 1307 | return -EINVAL; |
1308 | d_ino = ino; | ||
1309 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1310 | return -EOVERFLOW; | ||
1298 | buf->count++; | 1311 | buf->count++; |
1299 | dirent = buf->dirent; | 1312 | dirent = buf->dirent; |
1300 | if (put_user(ino, &dirent->d_ino) | 1313 | if (put_user(d_ino, &dirent->d_ino) |
1301 | || put_user(offset, &dirent->d_offset) | 1314 | || put_user(offset, &dirent->d_offset) |
1302 | || put_user(namlen, &dirent->d_namlen) | 1315 | || put_user(namlen, &dirent->d_namlen) |
1303 | || copy_to_user(dirent->d_name, name, namlen) | 1316 | || copy_to_user(dirent->d_name, name, namlen) |