diff options
| author | Michael Ellerman <mpe@ellerman.id.au> | 2017-07-31 20:20:29 +1000 | 
|---|---|---|
| committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-07-31 20:20:29 +1000 | 
| commit | bb272221e9db79f13d454e1f3fb6b05013be985e (patch) | |
| tree | 36f4acc50e3fabac71fadd34c720c0a6011db470 /fs/binfmt_flat.c | |
| parent | 253fd51e2f533552ae35a0c661705da6c4842c1b (diff) | |
| parent | 5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff) | |
Merge tag 'v4.13-rc1' into fixes
The fixes branch is based off a random pre-rc1 commit, because we had
some fixes that needed to go in before rc1 was released.
However we now need to fix some code that went in after that point, but
before rc1, so merge rc1 to get that code into fixes so we can fix it!
Diffstat (limited to 'fs/binfmt_flat.c')
| -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);  | 
