diff options
| author | Wu Fengguang <fengguang.wu@intel.com> | 2010-03-10 18:21:51 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 18:52:35 -0500 |
| commit | dcefafb6ac90ece8d68a6c203105f3d313e52da4 (patch) | |
| tree | c0aad5b135dc95f2aaa8d3c089a1ac44144ef424 | |
| parent | 2cb9a75d13676d75bcc6fbc6f885403795581913 (diff) | |
/dev/mem: dont allow seek to last page
So as to return a uniform error -EOVERFLOW instead of a random one:
# kmem-seek 0xfffffffffffffff0
seek /dev/kmem: Device or resource busy
# kmem-seek 0xfffffffffffffff1
seek /dev/kmem: Block device required
Suggested by OGAWA Hirofumi.
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/char/mem.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 48788db4e280..e3f5577cbce3 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
| @@ -708,16 +708,23 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | |||
| 708 | 708 | ||
| 709 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); | 709 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); |
| 710 | switch (orig) { | 710 | switch (orig) { |
| 711 | case 0: | 711 | case SEEK_CUR: |
| 712 | offset += file->f_pos; | ||
| 713 | if ((unsigned long long)offset < | ||
| 714 | (unsigned long long)file->f_pos) { | ||
| 715 | ret = -EOVERFLOW; | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | case SEEK_SET: | ||
| 719 | /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ | ||
| 720 | if ((unsigned long long)offset >= ~0xFFFULL) { | ||
| 721 | ret = -EOVERFLOW; | ||
| 722 | break; | ||
| 723 | } | ||
| 712 | file->f_pos = offset; | 724 | file->f_pos = offset; |
| 713 | ret = file->f_pos; | 725 | ret = file->f_pos; |
| 714 | force_successful_syscall_return(); | 726 | force_successful_syscall_return(); |
| 715 | break; | 727 | break; |
| 716 | case 1: | ||
| 717 | file->f_pos += offset; | ||
| 718 | ret = file->f_pos; | ||
| 719 | force_successful_syscall_return(); | ||
| 720 | break; | ||
| 721 | default: | 728 | default: |
| 722 | ret = -EINVAL; | 729 | ret = -EINVAL; |
| 723 | } | 730 | } |
