binfmt_flat: update libraries' data segment pointer with userspace accessors
authorNicolas Pitre <nicolas.pitre@linaro.org>
Sun, 24 Jul 2016 15:30:24 +0000 (11:30 -0400)
committerGreg Ungerer <gerg@linux-m68k.org>
Thu, 28 Jul 2016 03:29:11 +0000 (13:29 +1000)
This is needed on systems with a MMU.  This also gets rid of the
strangest C code I've seen lateli i.e. an integer indexed with a
pointer value within square brackets. That really looked backwards.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Greg Ungerer <gerg@linux-m68k.org>
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
fs/binfmt_flat.c

index eb747a266537970633ca5bedac758574325831d3..83e5071371124c8406f5d72cacb9dc1910628bc2 100644 (file)
@@ -894,12 +894,19 @@ static int load_flat_binary(struct linux_binprm *bprm)
                return res;
 
        /* Update data segment pointers for all libraries */
-       for (i = 0; i < MAX_SHARED_LIBS; i++)
-               if (libinfo.lib_list[i].loaded)
-                       for (j = 0; j < MAX_SHARED_LIBS; j++)
-                               (-(j+1))[(unsigned long *)(libinfo.lib_list[i].start_data)] =
-                                       (libinfo.lib_list[j].loaded) ?
-                                               libinfo.lib_list[j].start_data : UNLOADED_LIB;
+       for (i = 0; i < MAX_SHARED_LIBS; i++) {
+               if (!libinfo.lib_list[i].loaded)
+                       continue;
+               for (j = 0; j < MAX_SHARED_LIBS; j++) {
+                       unsigned long val = libinfo.lib_list[j].loaded ?
+                               libinfo.lib_list[j].start_data : UNLOADED_LIB;
+                       unsigned long __user *p = (unsigned long __user *)
+                               libinfo.lib_list[i].start_data;
+                       p -= j + 1;
+                       if (put_user(val, p))
+                               return -EFAULT;
+               }
+       }
 
        install_exec_creds(bprm);