diff options
Diffstat (limited to 'arch/parisc/kernel/sys_parisc32.c')
-rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index b74869803081..e3b30bc36453 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user | |||
237 | 237 | ||
238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
239 | { | 239 | { |
240 | compat_ino_t ino; | ||
240 | int err; | 241 | int err; |
241 | 242 | ||
242 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | 243 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || |
243 | !new_valid_dev(stat->rdev)) | 244 | !new_valid_dev(stat->rdev)) |
244 | return -EOVERFLOW; | 245 | return -EOVERFLOW; |
245 | 246 | ||
247 | ino = stat->ino; | ||
248 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
249 | return -EOVERFLOW; | ||
250 | |||
246 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | 251 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); |
247 | err |= put_user(stat->ino, &statbuf->st_ino); | 252 | err |= put_user(ino, &statbuf->st_ino); |
248 | err |= put_user(stat->mode, &statbuf->st_mode); | 253 | err |= put_user(stat->mode, &statbuf->st_mode); |
249 | err |= put_user(stat->nlink, &statbuf->st_nlink); | 254 | err |= put_user(stat->nlink, &statbuf->st_nlink); |
250 | err |= put_user(0, &statbuf->st_reserved1); | 255 | err |= put_user(0, &statbuf->st_reserved1); |
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
312 | struct linux32_dirent __user * dirent; | 317 | struct linux32_dirent __user * dirent; |
313 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 318 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
314 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); | 319 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); |
320 | u32 d_ino; | ||
315 | 321 | ||
316 | buf->error = -EINVAL; /* only used if we fail.. */ | 322 | buf->error = -EINVAL; /* only used if we fail.. */ |
317 | if (reclen > buf->count) | 323 | if (reclen > buf->count) |
318 | return -EINVAL; | 324 | return -EINVAL; |
325 | d_ino = ino; | ||
326 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
327 | return -EOVERFLOW; | ||
319 | dirent = buf->previous; | 328 | dirent = buf->previous; |
320 | if (dirent) | 329 | if (dirent) |
321 | put_user(offset, &dirent->d_off); | 330 | put_user(offset, &dirent->d_off); |
322 | dirent = buf->current_dir; | 331 | dirent = buf->current_dir; |
323 | buf->previous = dirent; | 332 | buf->previous = dirent; |
324 | put_user(ino, &dirent->d_ino); | 333 | put_user(d_ino, &dirent->d_ino); |
325 | put_user(reclen, &dirent->d_reclen); | 334 | put_user(reclen, &dirent->d_reclen); |
326 | copy_to_user(dirent->d_name, name, namlen); | 335 | copy_to_user(dirent->d_name, name, namlen); |
327 | put_user(0, dirent->d_name + namlen); | 336 | put_user(0, dirent->d_name + namlen); |
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t | |||
371 | { | 380 | { |
372 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 381 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
373 | struct old_linux32_dirent __user * dirent; | 382 | struct old_linux32_dirent __user * dirent; |
383 | u32 d_ino; | ||
374 | 384 | ||
375 | if (buf->count) | 385 | if (buf->count) |
376 | return -EINVAL; | 386 | return -EINVAL; |
387 | d_ino = ino; | ||
388 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
389 | return -EOVERFLOW; | ||
377 | buf->count++; | 390 | buf->count++; |
378 | dirent = buf->dirent; | 391 | dirent = buf->dirent; |
379 | put_user(ino, &dirent->d_ino); | 392 | put_user(d_ino, &dirent->d_ino); |
380 | put_user(offset, &dirent->d_offset); | 393 | put_user(offset, &dirent->d_offset); |
381 | put_user(namlen, &dirent->d_namlen); | 394 | put_user(namlen, &dirent->d_namlen); |
382 | copy_to_user(dirent->d_name, name, namlen); | 395 | copy_to_user(dirent->d_name, name, namlen); |