1 |
dpavlin |
1 |
#include <errno.h> |
2 |
|
|
#include <string.h> |
3 |
|
|
#include <sys/types.h> |
4 |
|
|
#include <sys/stat.h> |
5 |
|
|
#include <stdio.h> |
6 |
|
|
#include <unistd.h> |
7 |
|
|
|
8 |
|
|
int canonicalize(char *buf, int bufsize, char *cwd, char *fn) |
9 |
|
|
{ |
10 |
|
|
int cwdsize = strlen(cwd); |
11 |
|
|
int fnsize = strlen(fn); |
12 |
|
|
if (fn[0] == '/') { |
13 |
|
|
if (fnsize +1 > bufsize) return ERANGE; |
14 |
|
|
strcpy(buf, fn); |
15 |
|
|
return 0; |
16 |
|
|
} |
17 |
|
|
if (cwdsize + 1 + fnsize + 1 > bufsize) return ERANGE; |
18 |
|
|
strcpy(buf, cwd); |
19 |
|
|
strcat(buf, "/"); |
20 |
|
|
strcat(buf, fn); |
21 |
|
|
return 0; |
22 |
|
|
} |
23 |
|
|
|
24 |
|
|
int main(int argc, char *argv[]) |
25 |
|
|
{ |
26 |
|
|
setuid(0); |
27 |
|
|
char *relfilename = "ifppc_up"; |
28 |
|
|
int relfilenamesize = strlen(relfilename); |
29 |
|
|
char cwdbuf[2048]; |
30 |
|
|
if (!getcwd(cwdbuf, sizeof cwdbuf)) { |
31 |
|
|
printf("CWD name too long (>%d bytes). move to a higher level directory.\n", (int)sizeof cwdbuf); |
32 |
|
|
return 1; |
33 |
|
|
} |
34 |
|
|
char filename[2048+128]; |
35 |
|
|
if (canonicalize(filename, sizeof filename, cwdbuf, argv[0])) { |
36 |
|
|
printf("unable to determine absolute executable filename. " |
37 |
|
|
"probably absolute filename too long (>%d bytes). " |
38 |
|
|
"move to a higher level directory.\n", (int)sizeof cwdbuf); |
39 |
|
|
return 1; |
40 |
|
|
} |
41 |
|
|
char *bs = strrchr(filename, '/'); |
42 |
|
|
if (!bs) { |
43 |
|
|
printf("???\n"); |
44 |
|
|
return 1; |
45 |
|
|
} |
46 |
|
|
int pathsize = bs-filename; |
47 |
|
|
if (pathsize + 1 + relfilenamesize + 1 > sizeof filename) { |
48 |
|
|
printf("absolute pathname too long (>%d bytes). " |
49 |
|
|
"move to a higher level directory.\n", (int)sizeof cwdbuf); |
50 |
|
|
return 1; |
51 |
|
|
} |
52 |
|
|
strcpy(bs+1, relfilename); |
53 |
|
|
// printf("filename = %s, uid=%d, euid=%d\n", filename, getuid(), geteuid()); |
54 |
|
|
struct stat s; |
55 |
|
|
if (stat(filename, &s)) { |
56 |
|
|
printf("can't stat file '%s': %s\n", filename, strerror(errno)); |
57 |
|
|
return 1; |
58 |
|
|
} |
59 |
|
|
if (s.st_uid != 0) { |
60 |
|
|
printf("script '%s' must be owned by root (UID %d instead)\n", filename, s.st_uid); |
61 |
|
|
return 1; |
62 |
|
|
} |
63 |
|
|
if (s.st_mode & S_IWGRP) { |
64 |
|
|
printf("script '%s' must not be group-writable\n", filename); |
65 |
|
|
return 1; |
66 |
|
|
} |
67 |
|
|
if (s.st_mode & S_IWOTH) { |
68 |
|
|
printf("script '%s' must not be world-writable\n", filename); |
69 |
|
|
return 1; |
70 |
|
|
} |
71 |
|
|
execl("/bin/sh", "/bin/sh", filename, (char*)NULL); |
72 |
|
|
return 0; |
73 |
|
|
} |