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

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to