aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/sys_parisc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/sys_parisc32.c')
-rw-r--r--arch/parisc/kernel/sys_parisc32.c19
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
238int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 238int 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);