As promised, here's the patch to avoid the aforementioned alloca bugs.
It's a bit of an overkill, imo, but it does support ridiculously long
command-line arguments =D
For most practical issues, the fix posted in
http://lists.gnu.org/archive/html/bug-hurd/2016-03/msg00086.html
should be enough.
diff --git a/kern/bootstrap.c b/kern/bootstrap.c
index 0836276..2269147 100644
--- a/kern/bootstrap.c
+++ b/kern/bootstrap.c
@@ -165,6 +165,8 @@ void bootstrap_create(void)
else
{
int i, losers;
+ void *bufp, *bufp2;
+ size_t cap, cap2, used;
/* Initialize boot script variables. We leak these send rights.
*/
losers = boot_script_set_variable
@@ -190,14 +192,25 @@ void bootstrap_create(void)
/* Set the same boot script variables that the old Hurd's
serverboot did, so an old Hurd and boot script previously
used with serverboot can be used directly with this kernel. */
+ cap = 2048;
+ cap2 = 0;
+ bufp = (void *)kalloc (cap);
+ if (bufp == NULL)
+ panic ("Could not allocate enough memory");
- char *flag_string = alloca(1024);
- char *root_string = alloca(1024);
+ char *flag_string = (char *)bufp;
+ char *root_string = flag_string + cap / 2;
/*
* Get the (compatibility) boot flags and root name strings.
*/
get_compat_strings(flag_string, root_string);
+ used = strlen (flag_string) + 1;
+ size_t aux_len = strlen (root_string) + 1;
+ /* Coalesce both strings to save space. */
+ memmove (&flag_string[used], root_string, aux_len);
+ root_string = flag_string + used;
+ used += aux_len;
losers = boot_script_set_variable ("boot-args", VAL_STR,
(long) flag_string);
@@ -220,16 +233,30 @@ void bootstrap_create(void)
extern char **environ;
char **ep;
+ size_t aux_len = 0;
for (ep = environ; *ep != 0; ++ep)
+ aux_len += strlen (*ep) + 1;
+
+ if (used + aux_len >= cap)
+ {
+ bufp2 = (void *)kalloc (cap2 = aux_len);
+ if (bufp2 == NULL)
+ panic ("Could not allocate enough memory");
+ }
+ else
+ bufp2 = (char *)bufp + used;
+
+ for (aux_len = 0, ep = environ; *ep != 0; ++ep)
{
size_t len = strlen (*ep) + 1;
- char *var = memcpy (alloca (len), *ep, len);
+ char *var = memcpy (bufp2 + aux_len, *ep, len);
char *val = strchr (var, '=');
*val++ = '\0';
losers = boot_script_set_variable (var, VAL_STR, (long) val);
if (losers)
panic ("cannot set boot-script variable %s: %s",
var, boot_script_error_string (losers));
+ aux_len += len;
}
}
#else /* GNUmach, not oskit-mach */
@@ -238,8 +265,17 @@ void bootstrap_create(void)
variable ${FOO} with value BAR. This matches what we get from
oskit's environ in the oskit-mach case (above). */
- int len = strlen (kernel_cmdline) + 1;
- char *s = memcpy (alloca (len), kernel_cmdline, len);
+ size_t len = strlen (kernel_cmdline) + 1;
+ if (len + used >= cap)
+ {
+ bufp2 = (void *)kalloc (cap2 = len);
+ if (bufp2 == NULL)
+ panic ("Could not allocate enough memory");
+ }
+ else
+ bufp2 = (char *)bufp + used;
+
+ char *s = memcpy (bufp2, kernel_cmdline, len);
char *word;
while ((word = strsep (&s, " \t")) != 0)
{
@@ -275,6 +311,9 @@ void bootstrap_create(void)
if (losers)
panic ("ERROR in executing boot script: %s",
boot_script_error_string (losers));
+
+ kfree ((vm_offset_t)bufp, cap);
+ kfree ((vm_offset_t)bufp2, cap2);
}
/* XXX we could free the memory used
by the boot loader's descriptors and such. */
@@ -282,6 +321,7 @@ void bootstrap_create(void)
free_bootstrap_pages(bmods[n].mod_start, bmods[n].mod_end);
}
+
static void
bootstrap_exec_compat(void *e)
{