mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	binfmt_flat: flat_{get,put}_addr_from_rp() should be able to fail
on MMU targets EFAULT is possible here. Make both return 0 or error, passing what used to be the return value of flat_get_addr_from_rp() by reference. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									2ea659a9ef
								
							
						
					
					
						commit
						468138d785
					
				
					 12 changed files with 168 additions and 81 deletions
				
			
		|  | @ -5,12 +5,31 @@ | |||
| #ifndef __ARM_FLAT_H__ | ||||
| #define __ARM_FLAT_H__ | ||||
| 
 | ||||
| #include <linux/uaccess.h> | ||||
| 
 | ||||
| #define	flat_argvp_envp_on_stack()		1 | ||||
| #define	flat_old_ram_flag(flags)		(flags) | ||||
| #define	flat_reloc_valid(reloc, size)		((reloc) <= (size)) | ||||
| #define	flat_get_addr_from_rp(rp, relval, flags, persistent) \ | ||||
| 	({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) | ||||
| #define	flat_put_addr_at_rp(rp, val, relval)	__put_user_unaligned(val, rp) | ||||
| 
 | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||||
| 	return copy_from_user(addr, rp, 4) ? -EFAULT : 0; | ||||
| #else | ||||
| 	return get_user(*addr, rp); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||||
| 	return copy_to_user(rp, &addr, 4) ? -EFAULT : 0; | ||||
| #else | ||||
| 	return put_user(addr, rp); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #define	flat_get_relocate_addr(rel)		(rel) | ||||
| #define	flat_set_persistent(relval, p)		0 | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,23 +14,28 @@ | |||
| #define	flat_argvp_envp_on_stack()		0 | ||||
| #define	flat_old_ram_flag(flags)		(flags) | ||||
| 
 | ||||
| extern unsigned long bfin_get_addr_from_rp (unsigned long *ptr, | ||||
| 					unsigned long relval, | ||||
| 					unsigned long flags, | ||||
| 					unsigned long *persistent); | ||||
| extern unsigned long bfin_get_addr_from_rp (u32 *ptr, u32 relval, | ||||
| 					u32 flags, u32 *persistent); | ||||
| 
 | ||||
| extern void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr, | ||||
| 		                unsigned long relval); | ||||
| extern void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval); | ||||
| 
 | ||||
| /* The amount by which a relocation can exceed the program image limits
 | ||||
|    without being regarded as an error.  */ | ||||
| 
 | ||||
| #define	flat_reloc_valid(reloc, size)	((reloc) <= (size)) | ||||
| 
 | ||||
| #define	flat_get_addr_from_rp(rp, relval, flags, persistent)	\ | ||||
| 	bfin_get_addr_from_rp(rp, relval, flags, persistent) | ||||
| #define	flat_put_addr_at_rp(rp, val, relval)	\ | ||||
| 	bfin_put_addr_at_rp(rp, val, relval) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	*addr = bfin_get_addr_from_rp(rp, relval, flags, persistent); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 val, u32 relval) | ||||
| { | ||||
| 	bfin_put_addr_at_rp(rp, val, relval); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Convert a relocation entry into an address.  */ | ||||
| static inline unsigned long | ||||
|  |  | |||
|  | @ -13,14 +13,14 @@ | |||
| #define FLAT_BFIN_RELOC_TYPE_16H_BIT 1 | ||||
| #define FLAT_BFIN_RELOC_TYPE_32_BIT 2 | ||||
| 
 | ||||
| unsigned long bfin_get_addr_from_rp(unsigned long *ptr, | ||||
| 		unsigned long relval, | ||||
| 		unsigned long flags, | ||||
| 		unsigned long *persistent) | ||||
| unsigned long bfin_get_addr_from_rp(u32 *ptr, | ||||
| 		u32 relval, | ||||
| 		u32 flags, | ||||
| 		u32 *persistent) | ||||
| { | ||||
| 	unsigned short *usptr = (unsigned short *)ptr; | ||||
| 	int type = (relval >> 26) & 7; | ||||
| 	unsigned long val; | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	switch (type) { | ||||
| 	case FLAT_BFIN_RELOC_TYPE_16_BIT: | ||||
|  | @ -59,8 +59,7 @@ EXPORT_SYMBOL(bfin_get_addr_from_rp); | |||
|  * Insert the address ADDR into the symbol reference at RP; | ||||
|  * RELVAL is the raw relocation-table entry from which RP is derived | ||||
|  */ | ||||
| void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr, | ||||
| 		unsigned long relval) | ||||
| void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval) | ||||
| { | ||||
| 	unsigned short *usptr = (unsigned short *)ptr; | ||||
| 	int type = (relval >> 26) & 7; | ||||
|  |  | |||
|  | @ -1,11 +1,22 @@ | |||
| #ifndef __ASM_C6X_FLAT_H | ||||
| #define __ASM_C6X_FLAT_H | ||||
| 
 | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
| #define flat_argvp_envp_on_stack()			0 | ||||
| #define flat_old_ram_flag(flags)			(flags) | ||||
| #define flat_reloc_valid(reloc, size)			((reloc) <= (size)) | ||||
| #define flat_get_addr_from_rp(rp, relval, flags, p)	get_unaligned(rp) | ||||
| #define flat_put_addr_at_rp(rp, val, relval)		put_unaligned(val, rp) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	*addr = get_unaligned((__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| 	put_unaligned(addr, (__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| #define flat_get_relocate_addr(rel)			(rel) | ||||
| #define flat_set_persistent(relval, p)			0 | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,6 +5,8 @@ | |||
| #ifndef __H8300_FLAT_H__ | ||||
| #define __H8300_FLAT_H__ | ||||
| 
 | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
| #define	flat_argvp_envp_on_stack()		1 | ||||
| #define	flat_old_ram_flag(flags)		1 | ||||
| #define	flat_reloc_valid(reloc, size)		((reloc) <= (size)) | ||||
|  | @ -18,11 +20,21 @@ | |||
|  */ | ||||
| 
 | ||||
| #define	flat_get_relocate_addr(rel)		(rel & ~0x00000001) | ||||
| #define flat_get_addr_from_rp(rp, relval, flags, persistent) \ | ||||
| 	({(void)persistent; \ | ||||
| 		get_unaligned(rp) & (((flags) & FLAT_FLAG_GOTPIC) ?	\ | ||||
| 				     0xffffffff : 0x00ffffff); }) | ||||
| #define flat_put_addr_at_rp(rp, addr, rel) \ | ||||
| 	put_unaligned(((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), (rp)) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	u32 val = get_unaligned((__force u32 *)rp); | ||||
| 	if (!(flags & FLAT_FLAG_GOTPIC) | ||||
| 		val &= 0x00ffffff; | ||||
| 	*addr = val; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| 	u32 *p = (__force u32 *)rp; | ||||
| 	put_unaligned((addr & 0x00ffffff) | (*(char *)p << 24), p); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #endif /* __H8300_FLAT_H__ */ | ||||
|  |  | |||
|  | @ -17,11 +17,6 @@ | |||
| #define	flat_set_persistent(relval, p)		0 | ||||
| #define	flat_reloc_valid(reloc, size)		\ | ||||
| 	(((reloc) - textlen_for_m32r_lo16_data) <= (size)) | ||||
| #define flat_get_addr_from_rp(rp, relval, flags, persistent) \ | ||||
| 	m32r_flat_get_addr_from_rp(rp, relval, (text_len) ) | ||||
| 
 | ||||
| #define flat_put_addr_at_rp(rp, addr, relval) \ | ||||
| 	m32r_flat_put_addr_at_rp(rp, addr, relval) | ||||
| 
 | ||||
| /* Convert a relocation entry into an address.  */ | ||||
| static inline unsigned long | ||||
|  | @ -57,9 +52,9 @@ flat_get_relocate_addr (unsigned long relval) | |||
| 
 | ||||
| static unsigned long textlen_for_m32r_lo16_data = 0; | ||||
| 
 | ||||
| static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp, | ||||
|                                                         unsigned long relval, | ||||
| 						        unsigned long textlen) | ||||
| static inline unsigned long m32r_flat_get_addr_from_rp (u32 *rp, | ||||
|                                                         u32 relval, | ||||
| 						        u32 textlen) | ||||
| { | ||||
|         unsigned int reloc = flat_m32r_get_reloc_type (relval); | ||||
| 	textlen_for_m32r_lo16_data = 0; | ||||
|  | @ -100,9 +95,7 @@ static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp, | |||
| 	return ~0;      /* bogus value */ | ||||
| } | ||||
| 
 | ||||
| static inline void m32r_flat_put_addr_at_rp (unsigned long *rp, | ||||
| 					     unsigned long addr, | ||||
|                                              unsigned long relval) | ||||
| static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) | ||||
| { | ||||
|         unsigned int reloc = flat_m32r_get_reloc_type (relval); | ||||
| 	if (reloc & 0xf0) { | ||||
|  | @ -142,4 +135,8 @@ static inline void m32r_flat_put_addr_at_rp (unsigned long *rp, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // kludge - text_len is a local variable in the only user.
 | ||||
| #define flat_get_addr_from_rp(rp, relval, flags, addr, persistent) \ | ||||
| 	(m32r_flat_get_addr_from_rp(rp, relval, text_len), 0) | ||||
| 
 | ||||
| #endif /* __ASM_M32R_FLAT_H */ | ||||
|  |  | |||
|  | @ -5,12 +5,29 @@ | |||
| #ifndef __M68KNOMMU_FLAT_H__ | ||||
| #define __M68KNOMMU_FLAT_H__ | ||||
| 
 | ||||
| #include <linux/uaccess.h> | ||||
| 
 | ||||
| #define	flat_argvp_envp_on_stack()		1 | ||||
| #define	flat_old_ram_flag(flags)		(flags) | ||||
| #define	flat_reloc_valid(reloc, size)		((reloc) <= (size)) | ||||
| #define	flat_get_addr_from_rp(rp, relval, flags, p) \ | ||||
| 	({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) | ||||
| #define	flat_put_addr_at_rp(rp, val, relval)	__put_user_unaligned(val, rp) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| #ifdef CONFIG_CPU_HAS_NO_UNALIGNED | ||||
| 	return copy_from_user(addr, rp, 4) ? -EFAULT : 0; | ||||
| #else | ||||
| 	return get_user(*addr, rp); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| #ifdef CONFIG_CPU_HAS_NO_UNALIGNED | ||||
| 	return copy_to_user(rp, &addr, 4) ? -EFAULT : 0; | ||||
| #else | ||||
| 	return put_user(addr, rp); | ||||
| #endif | ||||
| } | ||||
| #define	flat_get_relocate_addr(rel)		(rel) | ||||
| 
 | ||||
| static inline int flat_set_persistent(unsigned long relval, | ||||
|  |  | |||
|  | @ -32,29 +32,27 @@ | |||
|  * reference | ||||
|  */ | ||||
| 
 | ||||
| static inline unsigned long | ||||
| flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, | ||||
| 			unsigned long flags, unsigned long *persistent) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	unsigned long addr; | ||||
| 	(void)flags; | ||||
| 	u32 *p = (__force u32 *)rp; | ||||
| 
 | ||||
| 	/* Is it a split 64/32 reference? */ | ||||
| 	if (relval & 0x80000000) { | ||||
| 		/* Grab the two halves of the reference */ | ||||
| 		unsigned long val_hi, val_lo; | ||||
| 		u32 val_hi, val_lo; | ||||
| 
 | ||||
| 		val_hi = get_unaligned(rp); | ||||
| 		val_lo = get_unaligned(rp+1); | ||||
| 		val_hi = get_unaligned(p); | ||||
| 		val_lo = get_unaligned(p+1); | ||||
| 
 | ||||
| 		/* Crack the address out */ | ||||
| 		addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff); | ||||
| 		*addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff); | ||||
| 	} else { | ||||
| 		/* Get the address straight out */ | ||||
| 		addr = get_unaligned(rp); | ||||
| 		*addr = get_unaligned(p); | ||||
| 	} | ||||
| 
 | ||||
| 	return addr; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -63,25 +61,27 @@ flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, | |||
|  */ | ||||
| 
 | ||||
| static inline void | ||||
| flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval) | ||||
| flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 relval) | ||||
| { | ||||
| 	u32 *p = (__force u32 *)rp; | ||||
| 	/* Is this a split 64/32 reloc? */ | ||||
| 	if (relval & 0x80000000) { | ||||
| 		/* Get the two "halves" */ | ||||
| 		unsigned long val_hi = get_unaligned(rp); | ||||
| 		unsigned long val_lo = get_unaligned(rp + 1); | ||||
| 		unsigned long val_hi = get_unaligned(p); | ||||
| 		unsigned long val_lo = get_unaligned(p + 1); | ||||
| 
 | ||||
| 		/* insert the address */ | ||||
| 		val_hi = (val_hi & 0xffff0000) | addr >> 16; | ||||
| 		val_lo = (val_lo & 0xffff0000) | (addr & 0xffff); | ||||
| 
 | ||||
| 		/* store the two halves back into memory */ | ||||
| 		put_unaligned(val_hi, rp); | ||||
| 		put_unaligned(val_lo, rp+1); | ||||
| 		put_unaligned(val_hi, p); | ||||
| 		put_unaligned(val_lo, p+1); | ||||
| 	} else { | ||||
| 		/* Put it straight in, no messing around */ | ||||
| 		put_unaligned(addr, rp); | ||||
| 		put_unaligned(addr, p); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #define	flat_get_relocate_addr(rel)	(rel & 0x7fffffff) | ||||
|  |  | |||
|  | @ -12,11 +12,22 @@ | |||
| #ifndef __ASM_SH_FLAT_H | ||||
| #define __ASM_SH_FLAT_H | ||||
| 
 | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
| #define	flat_argvp_envp_on_stack()		0 | ||||
| #define	flat_old_ram_flag(flags)		(flags) | ||||
| #define	flat_reloc_valid(reloc, size)		((reloc) <= (size)) | ||||
| #define	flat_get_addr_from_rp(rp, relval, flags, p)	get_unaligned(rp) | ||||
| #define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	*addr = get_unaligned((__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| 	put_unaligned(addr, (__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| #define	flat_get_relocate_addr(rel)		(rel) | ||||
| #define	flat_set_persistent(relval, p)		({ (void)p; 0; }) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,22 @@ | |||
| #ifndef __ASM_XTENSA_FLAT_H | ||||
| #define __ASM_XTENSA_FLAT_H | ||||
| 
 | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
| #define flat_argvp_envp_on_stack()			0 | ||||
| #define flat_old_ram_flag(flags)			(flags) | ||||
| #define flat_reloc_valid(reloc, size)			((reloc) <= (size)) | ||||
| #define flat_get_addr_from_rp(rp, relval, flags, p)	get_unaligned(rp) | ||||
| #define flat_put_addr_at_rp(rp, val, relval	)	put_unaligned(val, rp) | ||||
| static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, | ||||
| 					u32 *addr, u32 *persistent) | ||||
| { | ||||
| 	*addr = get_unaligned((__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel) | ||||
| { | ||||
| 	put_unaligned(addr, (__force u32 *)rp); | ||||
| 	return 0; | ||||
| } | ||||
| #define flat_get_relocate_addr(rel)			(rel) | ||||
| #define flat_set_persistent(relval, p)			0 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -9,8 +9,8 @@ | |||
| #ifndef _LINUX_FLAT_H | ||||
| #define _LINUX_FLAT_H | ||||
| 
 | ||||
| #include <asm/flat.h> | ||||
| #include <uapi/linux/flat.h> | ||||
| #include <asm/flat.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * While it would be nice to keep this header clean,  users of older | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro