mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-22 13:54:57 +08: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
@ -5,12 +5,31 @@
|
|||||||
#ifndef __ARM_FLAT_H__
|
#ifndef __ARM_FLAT_H__
|
||||||
#define __ARM_FLAT_H__
|
#define __ARM_FLAT_H__
|
||||||
|
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 1
|
#define flat_argvp_envp_on_stack() 1
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#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; })
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
#define flat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp)
|
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_get_relocate_addr(rel) (rel)
|
||||||
#define flat_set_persistent(relval, p) 0
|
#define flat_set_persistent(relval, p) 0
|
||||||
|
|
||||||
|
@ -14,23 +14,28 @@
|
|||||||
#define flat_argvp_envp_on_stack() 0
|
#define flat_argvp_envp_on_stack() 0
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
|
|
||||||
extern unsigned long bfin_get_addr_from_rp (unsigned long *ptr,
|
extern unsigned long bfin_get_addr_from_rp (u32 *ptr, u32 relval,
|
||||||
unsigned long relval,
|
u32 flags, u32 *persistent);
|
||||||
unsigned long flags,
|
|
||||||
unsigned long *persistent);
|
|
||||||
|
|
||||||
extern void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
|
extern void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval);
|
||||||
unsigned long relval);
|
|
||||||
|
|
||||||
/* The amount by which a relocation can exceed the program image limits
|
/* The amount by which a relocation can exceed the program image limits
|
||||||
without being regarded as an error. */
|
without being regarded as an error. */
|
||||||
|
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
|
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
bfin_get_addr_from_rp(rp, relval, flags, persistent)
|
u32 *addr, u32 *persistent)
|
||||||
#define flat_put_addr_at_rp(rp, val, relval) \
|
{
|
||||||
bfin_put_addr_at_rp(rp, val, relval)
|
*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. */
|
/* Convert a relocation entry into an address. */
|
||||||
static inline unsigned long
|
static inline unsigned long
|
||||||
|
@ -13,14 +13,14 @@
|
|||||||
#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
|
#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
|
||||||
#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
|
#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
|
||||||
|
|
||||||
unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
|
unsigned long bfin_get_addr_from_rp(u32 *ptr,
|
||||||
unsigned long relval,
|
u32 relval,
|
||||||
unsigned long flags,
|
u32 flags,
|
||||||
unsigned long *persistent)
|
u32 *persistent)
|
||||||
{
|
{
|
||||||
unsigned short *usptr = (unsigned short *)ptr;
|
unsigned short *usptr = (unsigned short *)ptr;
|
||||||
int type = (relval >> 26) & 7;
|
int type = (relval >> 26) & 7;
|
||||||
unsigned long val;
|
u32 val;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FLAT_BFIN_RELOC_TYPE_16_BIT:
|
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;
|
* Insert the address ADDR into the symbol reference at RP;
|
||||||
* RELVAL is the raw relocation-table entry from which RP is derived
|
* RELVAL is the raw relocation-table entry from which RP is derived
|
||||||
*/
|
*/
|
||||||
void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
|
void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval)
|
||||||
unsigned long relval)
|
|
||||||
{
|
{
|
||||||
unsigned short *usptr = (unsigned short *)ptr;
|
unsigned short *usptr = (unsigned short *)ptr;
|
||||||
int type = (relval >> 26) & 7;
|
int type = (relval >> 26) & 7;
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
#ifndef __ASM_C6X_FLAT_H
|
#ifndef __ASM_C6X_FLAT_H
|
||||||
#define __ASM_C6X_FLAT_H
|
#define __ASM_C6X_FLAT_H
|
||||||
|
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 0
|
#define flat_argvp_envp_on_stack() 0
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val, rp)
|
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_get_relocate_addr(rel) (rel)
|
||||||
#define flat_set_persistent(relval, p) 0
|
#define flat_set_persistent(relval, p) 0
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef __H8300_FLAT_H__
|
#ifndef __H8300_FLAT_H__
|
||||||
#define __H8300_FLAT_H__
|
#define __H8300_FLAT_H__
|
||||||
|
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 1
|
#define flat_argvp_envp_on_stack() 1
|
||||||
#define flat_old_ram_flag(flags) 1
|
#define flat_old_ram_flag(flags) 1
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
@ -18,11 +20,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define flat_get_relocate_addr(rel) (rel & ~0x00000001)
|
#define flat_get_relocate_addr(rel) (rel & ~0x00000001)
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
({(void)persistent; \
|
u32 *addr, u32 *persistent)
|
||||||
get_unaligned(rp) & (((flags) & FLAT_FLAG_GOTPIC) ? \
|
{
|
||||||
0xffffffff : 0x00ffffff); })
|
u32 val = get_unaligned((__force u32 *)rp);
|
||||||
#define flat_put_addr_at_rp(rp, addr, rel) \
|
if (!(flags & FLAT_FLAG_GOTPIC)
|
||||||
put_unaligned(((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), (rp))
|
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__ */
|
#endif /* __H8300_FLAT_H__ */
|
||||||
|
@ -17,11 +17,6 @@
|
|||||||
#define flat_set_persistent(relval, p) 0
|
#define flat_set_persistent(relval, p) 0
|
||||||
#define flat_reloc_valid(reloc, size) \
|
#define flat_reloc_valid(reloc, size) \
|
||||||
(((reloc) - textlen_for_m32r_lo16_data) <= (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. */
|
/* Convert a relocation entry into an address. */
|
||||||
static inline unsigned long
|
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 unsigned long textlen_for_m32r_lo16_data = 0;
|
||||||
|
|
||||||
static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp,
|
static inline unsigned long m32r_flat_get_addr_from_rp (u32 *rp,
|
||||||
unsigned long relval,
|
u32 relval,
|
||||||
unsigned long textlen)
|
u32 textlen)
|
||||||
{
|
{
|
||||||
unsigned int reloc = flat_m32r_get_reloc_type (relval);
|
unsigned int reloc = flat_m32r_get_reloc_type (relval);
|
||||||
textlen_for_m32r_lo16_data = 0;
|
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 */
|
return ~0; /* bogus value */
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void m32r_flat_put_addr_at_rp (unsigned long *rp,
|
static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval)
|
||||||
unsigned long addr,
|
|
||||||
unsigned long relval)
|
|
||||||
{
|
{
|
||||||
unsigned int reloc = flat_m32r_get_reloc_type (relval);
|
unsigned int reloc = flat_m32r_get_reloc_type (relval);
|
||||||
if (reloc & 0xf0) {
|
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 */
|
#endif /* __ASM_M32R_FLAT_H */
|
||||||
|
@ -5,12 +5,29 @@
|
|||||||
#ifndef __M68KNOMMU_FLAT_H__
|
#ifndef __M68KNOMMU_FLAT_H__
|
||||||
#define __M68KNOMMU_FLAT_H__
|
#define __M68KNOMMU_FLAT_H__
|
||||||
|
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 1
|
#define flat_argvp_envp_on_stack() 1
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, p) \
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
|
u32 *addr, u32 *persistent)
|
||||||
#define flat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp)
|
{
|
||||||
|
#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)
|
#define flat_get_relocate_addr(rel) (rel)
|
||||||
|
|
||||||
static inline int flat_set_persistent(unsigned long relval,
|
static inline int flat_set_persistent(unsigned long relval,
|
||||||
|
@ -32,29 +32,27 @@
|
|||||||
* reference
|
* reference
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline unsigned long
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
|
u32 *addr, u32 *persistent)
|
||||||
unsigned long flags, unsigned long *persistent)
|
|
||||||
{
|
{
|
||||||
unsigned long addr;
|
u32 *p = (__force u32 *)rp;
|
||||||
(void)flags;
|
|
||||||
|
|
||||||
/* Is it a split 64/32 reference? */
|
/* Is it a split 64/32 reference? */
|
||||||
if (relval & 0x80000000) {
|
if (relval & 0x80000000) {
|
||||||
/* Grab the two halves of the reference */
|
/* Grab the two halves of the reference */
|
||||||
unsigned long val_hi, val_lo;
|
u32 val_hi, val_lo;
|
||||||
|
|
||||||
val_hi = get_unaligned(rp);
|
val_hi = get_unaligned(p);
|
||||||
val_lo = get_unaligned(rp+1);
|
val_lo = get_unaligned(p+1);
|
||||||
|
|
||||||
/* Crack the address out */
|
/* Crack the address out */
|
||||||
addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
|
*addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
|
||||||
} else {
|
} else {
|
||||||
/* Get the address straight out */
|
/* 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
|
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? */
|
/* Is this a split 64/32 reloc? */
|
||||||
if (relval & 0x80000000) {
|
if (relval & 0x80000000) {
|
||||||
/* Get the two "halves" */
|
/* Get the two "halves" */
|
||||||
unsigned long val_hi = get_unaligned(rp);
|
unsigned long val_hi = get_unaligned(p);
|
||||||
unsigned long val_lo = get_unaligned(rp + 1);
|
unsigned long val_lo = get_unaligned(p + 1);
|
||||||
|
|
||||||
/* insert the address */
|
/* insert the address */
|
||||||
val_hi = (val_hi & 0xffff0000) | addr >> 16;
|
val_hi = (val_hi & 0xffff0000) | addr >> 16;
|
||||||
val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
|
val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
|
||||||
|
|
||||||
/* store the two halves back into memory */
|
/* store the two halves back into memory */
|
||||||
put_unaligned(val_hi, rp);
|
put_unaligned(val_hi, p);
|
||||||
put_unaligned(val_lo, rp+1);
|
put_unaligned(val_lo, p+1);
|
||||||
} else {
|
} else {
|
||||||
/* Put it straight in, no messing around */
|
/* 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)
|
#define flat_get_relocate_addr(rel) (rel & 0x7fffffff)
|
||||||
|
@ -12,11 +12,22 @@
|
|||||||
#ifndef __ASM_SH_FLAT_H
|
#ifndef __ASM_SH_FLAT_H
|
||||||
#define __ASM_SH_FLAT_H
|
#define __ASM_SH_FLAT_H
|
||||||
|
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 0
|
#define flat_argvp_envp_on_stack() 0
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
|
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_get_relocate_addr(rel) (rel)
|
||||||
#define flat_set_persistent(relval, p) ({ (void)p; 0; })
|
#define flat_set_persistent(relval, p) ({ (void)p; 0; })
|
||||||
|
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
#ifndef __ASM_XTENSA_FLAT_H
|
#ifndef __ASM_XTENSA_FLAT_H
|
||||||
#define __ASM_XTENSA_FLAT_H
|
#define __ASM_XTENSA_FLAT_H
|
||||||
|
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#define flat_argvp_envp_on_stack() 0
|
#define flat_argvp_envp_on_stack() 0
|
||||||
#define flat_old_ram_flag(flags) (flags)
|
#define flat_old_ram_flag(flags) (flags)
|
||||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||||
#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
|
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||||
#define flat_put_addr_at_rp(rp, val, relval ) put_unaligned(val, rp)
|
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_get_relocate_addr(rel) (rel)
|
||||||
#define flat_set_persistent(relval, p) 0
|
#define flat_set_persistent(relval, p) 0
|
||||||
|
|
||||||
|
@ -422,9 +422,9 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||||||
{
|
{
|
||||||
struct flat_hdr *hdr;
|
struct flat_hdr *hdr;
|
||||||
unsigned long textpos, datapos, realdatastart;
|
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 len, memp, memp_size, extra, rlim;
|
||||||
unsigned long __user *reloc, *rp;
|
u32 __user *reloc, *rp;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int i, rev, relocs;
|
int i, rev, relocs;
|
||||||
loff_t fpos;
|
loff_t fpos;
|
||||||
@ -596,13 +596,13 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reloc = (unsigned long __user *)
|
reloc = (u32 __user *)
|
||||||
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
||||||
memp = realdatastart;
|
memp = realdatastart;
|
||||||
memp_size = len;
|
memp_size = len;
|
||||||
} else {
|
} 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);
|
len = PAGE_ALIGN(len);
|
||||||
textpos = vm_mmap(NULL, 0, len,
|
textpos = vm_mmap(NULL, 0, len,
|
||||||
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
|
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);
|
realdatastart = textpos + ntohl(hdr->data_start);
|
||||||
datapos = ALIGN(realdatastart +
|
datapos = ALIGN(realdatastart +
|
||||||
MAX_SHARED_LIBS * sizeof(unsigned long),
|
MAX_SHARED_LIBS * sizeof(u32),
|
||||||
FLAT_DATA_ALIGN);
|
FLAT_DATA_ALIGN);
|
||||||
|
|
||||||
reloc = (unsigned long __user *)
|
reloc = (u32 __user *)
|
||||||
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
||||||
memp = textpos;
|
memp = textpos;
|
||||||
memp_size = len;
|
memp_size = len;
|
||||||
@ -694,7 +694,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||||||
ret = result;
|
ret = result;
|
||||||
pr_err("Unable to read code+data+bss, errno %d\n", ret);
|
pr_err("Unable to read code+data+bss, errno %d\n", ret);
|
||||||
vm_munmap(textpos, text_len + data_len + extra +
|
vm_munmap(textpos, text_len + data_len + extra +
|
||||||
MAX_SHARED_LIBS * sizeof(unsigned long));
|
MAX_SHARED_LIBS * sizeof(u32));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -754,8 +754,8 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||||||
* image.
|
* image.
|
||||||
*/
|
*/
|
||||||
if (flags & FLAT_FLAG_GOTPIC) {
|
if (flags & FLAT_FLAG_GOTPIC) {
|
||||||
for (rp = (unsigned long __user *)datapos; ; rp++) {
|
for (rp = (u32 __user *)datapos; ; rp++) {
|
||||||
unsigned long addr, rp_val;
|
u32 addr, rp_val;
|
||||||
if (get_user(rp_val, rp))
|
if (get_user(rp_val, rp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (rp_val == 0xffffffff)
|
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).
|
* __start to address 4 so that is okay).
|
||||||
*/
|
*/
|
||||||
if (rev > OLD_FLAT_VERSION) {
|
if (rev > OLD_FLAT_VERSION) {
|
||||||
unsigned long __maybe_unused persistent = 0;
|
u32 __maybe_unused persistent = 0;
|
||||||
for (i = 0; i < relocs; i++) {
|
for (i = 0; i < relocs; i++) {
|
||||||
unsigned long addr, relval;
|
u32 addr, relval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the address of the pointer to be
|
* 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))
|
if (flat_set_persistent(relval, &persistent))
|
||||||
continue;
|
continue;
|
||||||
addr = flat_get_relocate_addr(relval);
|
addr = flat_get_relocate_addr(relval);
|
||||||
rp = (unsigned long __user *)calc_reloc(addr, libinfo, id, 1);
|
rp = (u32 __user *)calc_reloc(addr, libinfo, id, 1);
|
||||||
if (rp == (unsigned long __user *)RELOC_FAILED) {
|
if (rp == (u32 __user *)RELOC_FAILED) {
|
||||||
ret = -ENOEXEC;
|
ret = -ENOEXEC;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the pointer's value. */
|
/* Get the pointer's value. */
|
||||||
addr = flat_get_addr_from_rp(rp, relval, flags,
|
ret = flat_get_addr_from_rp(rp, relval, flags,
|
||||||
&persistent);
|
&addr, &persistent);
|
||||||
|
if (unlikely(ret))
|
||||||
|
goto err;
|
||||||
|
|
||||||
if (addr != 0) {
|
if (addr != 0) {
|
||||||
/*
|
/*
|
||||||
* Do the relocation. PIC relocs in the data section are
|
* 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. */
|
/* 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 {
|
} else {
|
||||||
for (i = 0; i < relocs; i++) {
|
for (i = 0; i < relocs; i++) {
|
||||||
unsigned long relval;
|
u32 relval;
|
||||||
if (get_user(relval, reloc + i))
|
if (get_user(relval, reloc + i))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
relval = ntohl(relval);
|
relval = ntohl(relval);
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#ifndef _LINUX_FLAT_H
|
#ifndef _LINUX_FLAT_H
|
||||||
#define _LINUX_FLAT_H
|
#define _LINUX_FLAT_H
|
||||||
|
|
||||||
#include <asm/flat.h>
|
|
||||||
#include <uapi/linux/flat.h>
|
#include <uapi/linux/flat.h>
|
||||||
|
#include <asm/flat.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* While it would be nice to keep this header clean, users of older
|
* While it would be nice to keep this header clean, users of older
|
||||||
|
Loading…
Reference in New Issue
Block a user