[PATCH] ping: try SOCK_DGRAM if no root privileges

Laurent Bercot ska-dietlibc at skarnet.org
Fri Jan 10 05:37:22 UTC 2014


  You're performing too much work copying your argument list. :P
  The wrapper should be entirely transparent: busybox shouldn't
even notice it has been run through it, so it should be called
with the exact same argv. Here's what I do.

  Notes:
   * untested, please check carefully. The actual code I use depends
on skalibs; I modified it to remove the dependency to post it here.
(Which increased both the source code size and binary code size: yes,
the standard libc APIs suck that much and I wrote skalibs for a reason.)
   * BUSYBOX and LIST should be auto-generated to match the final path
to the busybox binary and the list of authorized privileged applets.
   * It is necessary to copy argv[0] because basename() can modify its
argument. (Have I ever mentioned that the standard libc APIs suck ?)
I'm doing it with a VLA to avoid pulling in malloc. The VLA can't smash
the stack, because the kernel limits argv.
   * No, Rich, I won't do a dichotomic search on a list that size. ;)

-----
#include <string.h>
#include <libgen.h>
#include <stdio.h>
#include <unistd.h>

#define BUSYBOX "/bin/busybox"

static char const *LIST[] =
{
   "passwd",
   "ping",
   "ping6",
   "su",
   0
} ;

static int okay (char const *s)
{
   register char const **p = LIST ;
   for (; *p ; p++) if (!strcmp(s, *p)) return 1 ;
   return 0 ;
}

int main (int argc, char const *const *argv, char const *const *envp)
{
   {
     char tmp[strlen(argv[0]) + 1] ;
     strcpy(tmp, argv[0]) ;
     if (!okay(basename(tmp)))
     {
       fprintf(stderr, "busybox-setuid: unable to run %s: unauthorized applet\n", argv[0]) ;
       return 1 ;
     }
   }

   execve(BUSYBOX, argv, envp) ;
   perror("busybox-setuid: unable to exec " BUSYBOX) ;
   return 2 ;
}

-----

-- 
  Laurent



More information about the busybox mailing list