diff mbox

[05/10] binfmt_flat: use proper user space accessors with relocs processing code

Message ID 1468358862-11799-6-git-send-email-nicolas.pitre@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Nicolas Pitre July 12, 2016, 9:27 p.m. UTC
Relocs are fixed up in place in user space memory.  The appropriate
accessors are required for this code to work with an active MMU.

Only those architectures with trivial architecture-specific handlers are
covered by this patch. Incidentally, those NOMMU architectures that can
also have a MMU are amongst the trivial ones so it should be fine.
---
 arch/arm/include/asm/flat.h    |  5 +++--
 arch/m68k/include/asm/flat.h   |  5 +++--
 arch/sh/include/asm/flat.h     |  5 +++--
 arch/xtensa/include/asm/flat.h |  5 +++--
 fs/binfmt_flat.c               | 31 +++++++++++++++++++------------
 5 files changed, 31 insertions(+), 20 deletions(-)

Comments

kernel test robot July 12, 2016, 10:21 p.m. UTC | #1
Hi,

[auto build test ERROR on arm/for-next]
[also build test ERROR on v4.7-rc7 next-20160712]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nicolas-Pitre/binfmt_flat-assorted-cleanups/20160713-055609
base:   http://repo.or.cz/linux-2.6/linux-2.6-arm.git for-next
config: sh-allyesconfig (attached as .config)
compiler: sh4-linux-gnu-gcc (Debian 5.3.1-8) 5.3.1 20160205
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sh 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/flat.h:12:0,
                    from fs/binfmt_flat.c:36:
   fs/binfmt_flat.c: In function 'load_flat_file':
>> arch/sh/include/asm/flat.h:19:26: error: implicit declaration of function '__get_user_unaligned' [-Werror=implicit-function-declaration]
     ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
                             ^
>> fs/binfmt_flat.c:771:11: note: in expansion of macro 'flat_get_addr_from_rp'
       addr = flat_get_addr_from_rp(rp, relval, flags,
              ^
>> arch/sh/include/asm/flat.h:20:46: error: implicit declaration of function '__put_user_unaligned' [-Werror=implicit-function-declaration]
    #define flat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp)
                                                 ^
>> fs/binfmt_flat.c:787:5: note: in expansion of macro 'flat_put_addr_at_rp'
        flat_put_addr_at_rp(rp, addr, relval);
        ^
>> arch/sh/include/asm/flat.h:19:26: warning: '__val' may be used uninitialized in this function [-Wmaybe-uninitialized]
     ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
                             ^
   arch/sh/include/asm/flat.h:19:19: note: '__val' was declared here
     ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
                      ^
>> fs/binfmt_flat.c:771:11: note: in expansion of macro 'flat_get_addr_from_rp'
       addr = flat_get_addr_from_rp(rp, relval, flags,
              ^
   cc1: some warnings being treated as errors

vim +/__get_user_unaligned +19 arch/sh/include/asm/flat.h

    13	#define __ASM_SH_FLAT_H
    14	
    15	#define	flat_argvp_envp_on_stack()		0
    16	#define	flat_old_ram_flag(flags)		(flags)
    17	#define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
    18	#define	flat_get_addr_from_rp(rp, relval, flags, p) \
  > 19		({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
  > 20	#define	flat_put_addr_at_rp(rp, val, relval)	__put_user_unaligned(val, rp)
    21	#define	flat_get_relocate_addr(rel)		(rel)
    22	#define	flat_set_persistent(relval, p)		({ (void)p; 0; })
    23	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index e847d23351..acf1d14b89 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -8,8 +8,9 @@ 
 #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) ((void)persistent,get_unaligned(rp))
-#define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
+#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)
 #define	flat_get_relocate_addr(rel)		(rel)
 #define	flat_set_persistent(relval, p)		0
 
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index f9454b89a5..f3f592d03e 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -8,8 +8,9 @@ 
 #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)	get_unaligned(rp)
-#define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
+#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)
 #define	flat_get_relocate_addr(rel)		(rel)
 
 static inline int flat_set_persistent(unsigned long relval,
diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
index 5d84df5e27..0f4f49ed6b 100644
--- a/arch/sh/include/asm/flat.h
+++ b/arch/sh/include/asm/flat.h
@@ -15,8 +15,9 @@ 
 #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)
+#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)
 #define	flat_get_relocate_addr(rel)		(rel)
 #define	flat_set_persistent(relval, p)		({ (void)p; 0; })
 
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
index 94c44abf15..fffad219af 100644
--- a/arch/xtensa/include/asm/flat.h
+++ b/arch/xtensa/include/asm/flat.h
@@ -4,8 +4,9 @@ 
 #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)
+#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)
 #define flat_get_relocate_addr(rel)			(rel)
 #define flat_set_persistent(relval, p)			0
 
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 9538901fe8..fc0ee3ed5d 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -438,7 +438,7 @@  static int load_flat_file(struct linux_binprm * bprm,
 	unsigned long textpos, datapos, realdatastart;
 	unsigned long text_len, data_len, bss_len, stack_len, full_data, flags;
 	unsigned long len, memp, memp_size, extra, rlim;
-	unsigned long *reloc, *rp;
+	unsigned long __user *reloc, *rp;
 	struct inode *inode;
 	int i, rev, relocs;
 	loff_t fpos;
@@ -600,7 +600,7 @@  static int load_flat_file(struct linux_binprm * bprm,
 			goto err;
 		}
 
-		reloc = (unsigned long *)
+		reloc = (unsigned long __user *)
 			(datapos + (ntohl(hdr->reloc_start) - text_len));
 		memp = realdatastart;
 		memp_size = len;
@@ -625,7 +625,7 @@  static int load_flat_file(struct linux_binprm * bprm,
 				MAX_SHARED_LIBS * sizeof(unsigned long),
 				FLAT_DATA_ALIGN);
 
-		reloc = (unsigned long *)
+		reloc = (unsigned long __user *)
 			(datapos + (ntohl(hdr->reloc_start) - text_len));
 		memp = textpos;
 		memp_size = len;
@@ -718,15 +718,20 @@  static int load_flat_file(struct linux_binprm * bprm,
 	 * image.
 	 */
 	if (flags & FLAT_FLAG_GOTPIC) {
-		for (rp = (unsigned long *)datapos; *rp != 0xffffffff; rp++) {
-			unsigned long addr;
-			if (*rp) {
-				addr = calc_reloc(*rp, libinfo, id, 0);
+		for (rp = (unsigned long __user *)datapos; ; rp++) {
+			unsigned long addr, rp_val;
+			if (get_user(rp_val, rp))
+				return -EFAULT;
+			if (rp_val == 0xffffffff)
+				break;
+			if (rp_val) {
+				addr = calc_reloc(rp_val, libinfo, id, 0);
 				if (addr == RELOC_FAILED) {
 					ret = -ENOEXEC;
 					goto err;
 				}
-				*rp = addr;
+				if (put_user(addr, rp))
+					return -EFAULT;
 			}
 		}
 	}
@@ -743,19 +748,21 @@  static int load_flat_file(struct linux_binprm * bprm,
 	 * __start to address 4 so that is okay).
 	 */
 	if (rev > OLD_FLAT_VERSION) {
-		unsigned long persistent = 0;
+		unsigned long __maybe_unused persistent = 0;
 		for (i=0; i < relocs; i++) {
 			unsigned long addr, relval;
 
 			/* Get the address of the pointer to be
 			   relocated (of course, the address has to be
 			   relocated first).  */
-			relval = ntohl(reloc[i]);
+			if (get_user(relval, reloc + i))
+				return -EFAULT;
+			relval = ntohl(relval);
 			if (flat_set_persistent (relval, &persistent))
 				continue;
 			addr = flat_get_relocate_addr(relval);
-			rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
-			if (rp == (unsigned long *)RELOC_FAILED) {
+			rp = (unsigned long __user *)calc_reloc(addr, libinfo, id, 1);
+			if (rp == (unsigned long __user *)RELOC_FAILED) {
 				ret = -ENOEXEC;
 				goto err;
 			}