diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2010-06-01 09:10:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-01 11:11:06 -0400 |
commit | e30c7c3b306312c157d67eedd6a01920518b756c (patch) | |
tree | 4eae3fe0331bd6ab4e72946574ddc619d7cc127e | |
parent | 293a7cfeedc2b2380a7c7274902323c3cf5f7575 (diff) |
binfmt_elf_fdpic: Fix clear_user() error handling
clear_user() returns the number of bytes that could not be copied rather than
an error code. So we should return -EFAULT rather than directly returning the
results.
Without this patch, positive values may be returned to elf_fdpic_map_file()
and the following error handlings do not function as expected.
1.
ret = elf_fdpic_map_file_constdisp_on_uclinux(params, file, mm);
if (ret < 0)
return ret;
2.
ret = elf_fdpic_map_file_by_direct_mmap(params, file, mm);
if (ret < 0)
return ret;
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mike Frysinger <vapier@gentoo.org>
CC: Alexander Viro <viro@zeniv.linux.org.uk>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Daisuke HATAYAMA <d.hatayama@jp.fujitsu.com>
CC: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 2c5f9a0e5d72..63039ed9576f 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -990,10 +990,9 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( | |||
990 | 990 | ||
991 | /* clear any space allocated but not loaded */ | 991 | /* clear any space allocated but not loaded */ |
992 | if (phdr->p_filesz < phdr->p_memsz) { | 992 | if (phdr->p_filesz < phdr->p_memsz) { |
993 | ret = clear_user((void *) (seg->addr + phdr->p_filesz), | 993 | if (clear_user((void *) (seg->addr + phdr->p_filesz), |
994 | phdr->p_memsz - phdr->p_filesz); | 994 | phdr->p_memsz - phdr->p_filesz)) |
995 | if (ret) | 995 | return -EFAULT; |
996 | return ret; | ||
997 | } | 996 | } |
998 | 997 | ||
999 | if (mm) { | 998 | if (mm) { |
@@ -1027,7 +1026,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1027 | struct elf32_fdpic_loadseg *seg; | 1026 | struct elf32_fdpic_loadseg *seg; |
1028 | struct elf32_phdr *phdr; | 1027 | struct elf32_phdr *phdr; |
1029 | unsigned long load_addr, delta_vaddr; | 1028 | unsigned long load_addr, delta_vaddr; |
1030 | int loop, dvset, ret; | 1029 | int loop, dvset; |
1031 | 1030 | ||
1032 | load_addr = params->load_addr; | 1031 | load_addr = params->load_addr; |
1033 | delta_vaddr = 0; | 1032 | delta_vaddr = 0; |
@@ -1127,9 +1126,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1127 | * PT_LOAD */ | 1126 | * PT_LOAD */ |
1128 | if (prot & PROT_WRITE && disp > 0) { | 1127 | if (prot & PROT_WRITE && disp > 0) { |
1129 | kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); | 1128 | kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); |
1130 | ret = clear_user((void __user *) maddr, disp); | 1129 | if (clear_user((void __user *) maddr, disp)) |
1131 | if (ret) | 1130 | return -EFAULT; |
1132 | return ret; | ||
1133 | maddr += disp; | 1131 | maddr += disp; |
1134 | } | 1132 | } |
1135 | 1133 | ||
@@ -1164,19 +1162,17 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1164 | if (prot & PROT_WRITE && excess1 > 0) { | 1162 | if (prot & PROT_WRITE && excess1 > 0) { |
1165 | kdebug("clear[%d] ad=%lx sz=%lx", | 1163 | kdebug("clear[%d] ad=%lx sz=%lx", |
1166 | loop, maddr + phdr->p_filesz, excess1); | 1164 | loop, maddr + phdr->p_filesz, excess1); |
1167 | ret = clear_user((void __user *) maddr + phdr->p_filesz, | 1165 | if (clear_user((void __user *) maddr + phdr->p_filesz, |
1168 | excess1); | 1166 | excess1)) |
1169 | if (ret) | 1167 | return -EFAULT; |
1170 | return ret; | ||
1171 | } | 1168 | } |
1172 | 1169 | ||
1173 | #else | 1170 | #else |
1174 | if (excess > 0) { | 1171 | if (excess > 0) { |
1175 | kdebug("clear[%d] ad=%lx sz=%lx", | 1172 | kdebug("clear[%d] ad=%lx sz=%lx", |
1176 | loop, maddr + phdr->p_filesz, excess); | 1173 | loop, maddr + phdr->p_filesz, excess); |
1177 | ret = clear_user((void *) maddr + phdr->p_filesz, excess); | 1174 | if (clear_user((void *) maddr + phdr->p_filesz, excess)) |
1178 | if (ret) | 1175 | return -EFAULT; |
1179 | return ret; | ||
1180 | } | 1176 | } |
1181 | #endif | 1177 | #endif |
1182 | 1178 | ||