diff options
-rw-r--r-- | fs/compat.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/compat.c b/fs/compat.c index 55ac0324aaf1..271b75d1597f 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -494,9 +494,21 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, | |||
494 | ret = sys_fcntl(fd, cmd, (unsigned long)&f); | 494 | ret = sys_fcntl(fd, cmd, (unsigned long)&f); |
495 | set_fs(old_fs); | 495 | set_fs(old_fs); |
496 | if (cmd == F_GETLK && ret == 0) { | 496 | if (cmd == F_GETLK && ret == 0) { |
497 | if ((f.l_start >= COMPAT_OFF_T_MAX) || | 497 | /* GETLK was successfule and we need to return the data... |
498 | ((f.l_start + f.l_len) > COMPAT_OFF_T_MAX)) | 498 | * but it needs to fit in the compat structure. |
499 | * l_start shouldn't be too big, unless the original | ||
500 | * start + end is greater than COMPAT_OFF_T_MAX, in which | ||
501 | * case the app was asking for trouble, so we return | ||
502 | * -EOVERFLOW in that case. | ||
503 | * l_len could be too big, in which case we just truncate it, | ||
504 | * and only allow the app to see that part of the conflicting | ||
505 | * lock that might make sense to it anyway | ||
506 | */ | ||
507 | |||
508 | if (f.l_start > COMPAT_OFF_T_MAX) | ||
499 | ret = -EOVERFLOW; | 509 | ret = -EOVERFLOW; |
510 | if (f.l_len > COMPAT_OFF_T_MAX) | ||
511 | f.l_len = COMPAT_OFF_T_MAX; | ||
500 | if (ret == 0) | 512 | if (ret == 0) |
501 | ret = put_compat_flock(&f, compat_ptr(arg)); | 513 | ret = put_compat_flock(&f, compat_ptr(arg)); |
502 | } | 514 | } |
@@ -515,9 +527,11 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, | |||
515 | (unsigned long)&f); | 527 | (unsigned long)&f); |
516 | set_fs(old_fs); | 528 | set_fs(old_fs); |
517 | if (cmd == F_GETLK64 && ret == 0) { | 529 | if (cmd == F_GETLK64 && ret == 0) { |
518 | if ((f.l_start >= COMPAT_LOFF_T_MAX) || | 530 | /* need to return lock information - see above for commentary */ |
519 | ((f.l_start + f.l_len) > COMPAT_LOFF_T_MAX)) | 531 | if (f.l_start > COMPAT_LOFF_T_MAX) |
520 | ret = -EOVERFLOW; | 532 | ret = -EOVERFLOW; |
533 | if (f.l_len > COMPAT_LOFF_T_MAX) | ||
534 | f.l_len = COMPAT_LOFF_T_MAX; | ||
521 | if (ret == 0) | 535 | if (ret == 0) |
522 | ret = put_compat_flock64(&f, compat_ptr(arg)); | 536 | ret = put_compat_flock64(&f, compat_ptr(arg)); |
523 | } | 537 | } |