running arbitrary commands
diff --git a/asn1c/webcgi/asn1c-suid-helper.c b/asn1c/webcgi/asn1c-suid-helper.c
index 6439098..9a878fe 100644
--- a/asn1c/webcgi/asn1c-suid-helper.c
+++ b/asn1c/webcgi/asn1c-suid-helper.c
@@ -12,16 +12,17 @@
*/
int
main(int ac, char **av) {
- char **argv;
+ char cmdPath[32];
char *envp[] = { NULL }; /* Empty environment */
int ret;
int i;
- if(ac < 3) {
+ if(ac < 4) {
setgid(getgid());
setuid(getuid());
fprintf(stderr,
- "Usage: %s <chroot-to> <chdir-to> [options]\n", av[0]);
+ "Usage: %s <chroot-to> <chdir-to> <command> [options]\n",
+ av[0]);
exit(EX_USAGE);
}
@@ -48,20 +49,34 @@
exit(EX_DATAERR);
}
- argv = calloc(ac + 1, sizeof(*argv));
- if(argv) {
- argv[0] = "asn1c";
- argv[1] = "-S/skeletons";
- memcpy(argv + 2, av + 3, (ac - 3) * sizeof(*argv));
+
+ /*
+ * Add an argument if this is an asn1c compiler.
+ */
+ if(strcmp(av[3], "asn1c") == 0) {
+ ac -= 2;
+ av += 2;
+ av[0] = "asn1c";
+ av[1] = "-S/skeletons";
+ i = 2;
+ strcpy(cmdPath, "/bin/asn1c");
} else {
- perror("malloc()");
- exit(EX_OSERR);
+ ac -= 3;
+ av += 3;
+ i = 0;
}
+ if(strlen(av[0]) > sizeof(cmdPath)/2) {
+ fprintf(stderr, "Insecure command name: %s\n", av[0]);
+ exit(EX_DATAERR);
+ }
+ memcpy(cmdPath, "/bin/", 5);
+ strcpy(cmdPath + 5, av[0]);
+
/*
* Check arguments for the permitted alphabet constraints.
*/
- for(i = 3; i < ac; i++) {
+ for(; i < ac; i++) {
char *p;
for(p = av[i];; p++) {
switch(*p) {
@@ -80,7 +95,8 @@
}
}
- execve("/bin/asn1c", argv, envp);
+ execve(cmdPath, av, envp);
+ perror(cmdPath);
exit(EX_UNAVAILABLE);
}