Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 468138d7 authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2ea659a9
Loading
Loading
Loading
Loading
+22 −3
Original line number Original line Diff line number Diff line
@@ -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


+15 −10
Original line number Original line Diff line number Diff line
@@ -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
+6 −7
Original line number Original line Diff line number Diff line
@@ -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;
+13 −2
Original line number Original line Diff line number Diff line
#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


+18 −6
Original line number Original line Diff line number Diff line
@@ -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__ */
Loading