bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dangerous use of alloca


From: Agustina Arzille
Subject: Re: Dangerous use of alloca
Date: Tue, 15 Mar 2016 22:44:28 -0300

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)
 {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]