Commit e30c7c3b306312c157d67eedd6a01920518b756c

Authored by Takuya Yoshikawa
Committed by Linus Torvalds
1 parent 293a7cfeed

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