diff options
author | Linus Torvalds | 2017-07-15 11:17:52 -0700 |
---|---|---|
committer | Linus Torvalds | 2017-07-15 11:17:52 -0700 |
commit | 89cbec71fead552fdd1fa38c57186669dfbba734 (patch) | |
tree | 0e8e235b23b0fc1cd2d32bb28cafdee636e62d51 /fs | |
parent | 2173bd06315109ec73e7a6077c11469bd41d400b (diff) | |
parent | 3170d8d226c2053355f3946b4b5ded4c006fe6d4 (diff) |
Merge branch 'work.uaccess-unaligned' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull uacess-unaligned removal from Al Viro:
"That stuff had just one user, and an exotic one, at that - binfmt_flat
on arm and m68k"
* 'work.uaccess-unaligned' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
kill {__,}{get,put}_user_unaligned()
binfmt_flat: flat_{get,put}_addr_from_rp() should be able to fail
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_flat.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 2edcefc0a294..69ec23daa25e 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -422,9 +422,9 @@ static int load_flat_file(struct linux_binprm *bprm, { struct flat_hdr *hdr; unsigned long textpos, datapos, realdatastart; - unsigned long text_len, data_len, bss_len, stack_len, full_data, flags; + u32 text_len, data_len, bss_len, stack_len, full_data, flags; unsigned long len, memp, memp_size, extra, rlim; - unsigned long __user *reloc, *rp; + u32 __user *reloc, *rp; struct inode *inode; int i, rev, relocs; loff_t fpos; @@ -596,13 +596,13 @@ static int load_flat_file(struct linux_binprm *bprm, goto err; } - reloc = (unsigned long __user *) + reloc = (u32 __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = realdatastart; memp_size = len; } else { - len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); + len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(u32); len = PAGE_ALIGN(len); textpos = vm_mmap(NULL, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); @@ -618,10 +618,10 @@ static int load_flat_file(struct linux_binprm *bprm, realdatastart = textpos + ntohl(hdr->data_start); datapos = ALIGN(realdatastart + - MAX_SHARED_LIBS * sizeof(unsigned long), + MAX_SHARED_LIBS * sizeof(u32), FLAT_DATA_ALIGN); - reloc = (unsigned long __user *) + reloc = (u32 __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = textpos; memp_size = len; @@ -694,7 +694,7 @@ static int load_flat_file(struct linux_binprm *bprm, ret = result; pr_err("Unable to read code+data+bss, errno %d\n", ret); vm_munmap(textpos, text_len + data_len + extra + - MAX_SHARED_LIBS * sizeof(unsigned long)); + MAX_SHARED_LIBS * sizeof(u32)); goto err; } } @@ -754,8 +754,8 @@ static int load_flat_file(struct linux_binprm *bprm, * image. */ if (flags & FLAT_FLAG_GOTPIC) { - for (rp = (unsigned long __user *)datapos; ; rp++) { - unsigned long addr, rp_val; + for (rp = (u32 __user *)datapos; ; rp++) { + u32 addr, rp_val; if (get_user(rp_val, rp)) return -EFAULT; if (rp_val == 0xffffffff) @@ -784,9 +784,9 @@ static int load_flat_file(struct linux_binprm *bprm, * __start to address 4 so that is okay). */ if (rev > OLD_FLAT_VERSION) { - unsigned long __maybe_unused persistent = 0; + u32 __maybe_unused persistent = 0; for (i = 0; i < relocs; i++) { - unsigned long addr, relval; + u32 addr, relval; /* * Get the address of the pointer to be @@ -799,15 +799,18 @@ static int load_flat_file(struct linux_binprm *bprm, if (flat_set_persistent(relval, &persistent)) continue; addr = flat_get_relocate_addr(relval); - rp = (unsigned long __user *)calc_reloc(addr, libinfo, id, 1); - if (rp == (unsigned long __user *)RELOC_FAILED) { + rp = (u32 __user *)calc_reloc(addr, libinfo, id, 1); + if (rp == (u32 __user *)RELOC_FAILED) { ret = -ENOEXEC; goto err; } /* Get the pointer's value. */ - addr = flat_get_addr_from_rp(rp, relval, flags, - &persistent); + ret = flat_get_addr_from_rp(rp, relval, flags, + &addr, &persistent); + if (unlikely(ret)) + goto err; + if (addr != 0) { /* * Do the relocation. PIC relocs in the data section are @@ -822,12 +825,14 @@ static int load_flat_file(struct linux_binprm *bprm, } /* Write back the relocated pointer. */ - flat_put_addr_at_rp(rp, addr, relval); + ret = flat_put_addr_at_rp(rp, addr, relval); + if (unlikely(ret)) + goto err; } } } else { for (i = 0; i < relocs; i++) { - unsigned long relval; + u32 relval; if (get_user(relval, reloc + i)) return -EFAULT; relval = ntohl(relval); |