Commit e30c7c3b306312c157d67eedd6a01920518b756c
Committed by
Linus Torvalds
1 parent
293a7cfeed
Exists in
master
and in
39 other branches
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>
Showing 1 changed file with 11 additions and 15 deletions Side-by-side Diff
fs/binfmt_elf_fdpic.c
... | ... | @@ -990,10 +990,9 @@ |
990 | 990 | |
991 | 991 | /* clear any space allocated but not loaded */ |
992 | 992 | if (phdr->p_filesz < phdr->p_memsz) { |
993 | - ret = clear_user((void *) (seg->addr + phdr->p_filesz), | |
994 | - phdr->p_memsz - phdr->p_filesz); | |
995 | - if (ret) | |
996 | - return ret; | |
993 | + if (clear_user((void *) (seg->addr + phdr->p_filesz), | |
994 | + phdr->p_memsz - phdr->p_filesz)) | |
995 | + return -EFAULT; | |
997 | 996 | } |
998 | 997 | |
999 | 998 | if (mm) { |
... | ... | @@ -1027,7 +1026,7 @@ |
1027 | 1026 | struct elf32_fdpic_loadseg *seg; |
1028 | 1027 | struct elf32_phdr *phdr; |
1029 | 1028 | unsigned long load_addr, delta_vaddr; |
1030 | - int loop, dvset, ret; | |
1029 | + int loop, dvset; | |
1031 | 1030 | |
1032 | 1031 | load_addr = params->load_addr; |
1033 | 1032 | delta_vaddr = 0; |
... | ... | @@ -1127,9 +1126,8 @@ |
1127 | 1126 | * PT_LOAD */ |
1128 | 1127 | if (prot & PROT_WRITE && disp > 0) { |
1129 | 1128 | kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); |
1130 | - ret = clear_user((void __user *) maddr, disp); | |
1131 | - if (ret) | |
1132 | - return ret; | |
1129 | + if (clear_user((void __user *) maddr, disp)) | |
1130 | + return -EFAULT; | |
1133 | 1131 | maddr += disp; |
1134 | 1132 | } |
1135 | 1133 | |
1136 | 1134 | |
... | ... | @@ -1164,19 +1162,17 @@ |
1164 | 1162 | if (prot & PROT_WRITE && excess1 > 0) { |
1165 | 1163 | kdebug("clear[%d] ad=%lx sz=%lx", |
1166 | 1164 | loop, maddr + phdr->p_filesz, excess1); |
1167 | - ret = clear_user((void __user *) maddr + phdr->p_filesz, | |
1168 | - excess1); | |
1169 | - if (ret) | |
1170 | - return ret; | |
1165 | + if (clear_user((void __user *) maddr + phdr->p_filesz, | |
1166 | + excess1)) | |
1167 | + return -EFAULT; | |
1171 | 1168 | } |
1172 | 1169 | |
1173 | 1170 | #else |
1174 | 1171 | if (excess > 0) { |
1175 | 1172 | kdebug("clear[%d] ad=%lx sz=%lx", |
1176 | 1173 | loop, maddr + phdr->p_filesz, excess); |
1177 | - ret = clear_user((void *) maddr + phdr->p_filesz, excess); | |
1178 | - if (ret) | |
1179 | - return ret; | |
1174 | + if (clear_user((void *) maddr + phdr->p_filesz, excess)) | |
1175 | + return -EFAULT; | |
1180 | 1176 | } |
1181 | 1177 | #endif |
1182 | 1178 |