Pārlūkot izejas kodu

x86: Fix do_go_exec() - const argv[]

Commit 54841ab50c20d6fa6c9cc3eb826989da3a22d934 made the argv parameter
to do_go_exec() const but did not allow for the fact that argv[-1] is
set to point to the global data structure and relies on argv being non-
const.

With this patch, do_go_exec() creates a new copy of the argv array with
an extra element to store global data pointer rather than simply
clobbering an arbitrary memory location.
Graeme Russ 14 gadi atpakaļ
vecāks
revīzija
e69c0cba8f
1 mainītis faili ar 20 papildinājumiem un 5 dzēšanām
  1. 20 5
      arch/i386/lib/board.c

+ 20 - 5
arch/i386/lib/board.c

@@ -431,15 +431,30 @@ void hang (void)
 	for (;;);
 }
 
-unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char * const argv[])
+unsigned long do_go_exec (ulong (*entry)(int, char * const []), int argc, char * const argv[])
 {
+	unsigned long ret = 0;
+	char **argv_tmp;
+
 	/*
-	 * x86 does not use a dedicated register to pass the pointer
-	 * to the global_data
+	 * x86 does not use a dedicated register to pass the pointer to
+	 * the global_data, so it is instead passed as argv[-1]. By using
+	 * argv[-1], the called 'Application' can use the contents of
+	 * argv natively. However, to safely use argv[-1] a new copy of
+	 * argv is needed with the extra element
 	 */
-	argv[-1] = (char *)gd;
+	argv_tmp = malloc(sizeof(char *) * (argc + 1));
+
+	if (argv_tmp) {
+		argv_tmp[0] = (char *)gd;
+
+		memcpy(&argv_tmp[1], argv, (size_t)(sizeof(char *) * argc));
+
+		ret = (entry) (argc, &argv_tmp[1]);
+		free(argv_tmp);
+	}
 
-	return (entry) (argc, argv);
+	return ret;
 }
 
 void setup_pcat_compatibility(void)