diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-19 19:06:23 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-19 19:06:23 +0000 |
commit | d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4 (patch) | |
tree | 7bf3b75e143f2ba35a461604315ec93df8d0ecab /debianutils | |
parent | 6c10657c4a4cb54ed65d797250b9a73b565c10d6 (diff) | |
download | busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.tar.gz busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.tar.bz2 busybox-w32-d9c51e9fa78f7ee6adb37543f77b4f85e57cccc4.zip |
start-stop-daemon: make --exec follow symlinks
by Joakim Tjernlund <joakim.tjernlund AT transmode.se>
function old new delta
check 1591 1618 +27
start_stop_daemon_main 770 792 +22
Diffstat (limited to 'debianutils')
-rw-r--r-- | debianutils/start_stop_daemon.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 601fd72fa..2f8e04a78 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -32,6 +32,7 @@ struct globals { | |||
32 | int user_id; | 32 | int user_id; |
33 | smallint quiet; | 33 | smallint quiet; |
34 | smallint signal_nr; | 34 | smallint signal_nr; |
35 | struct stat execstat; | ||
35 | }; | 36 | }; |
36 | #define G (*(struct globals*)&bb_common_bufsiz1) | 37 | #define G (*(struct globals*)&bb_common_bufsiz1) |
37 | #define found (G.found ) | 38 | #define found (G.found ) |
@@ -42,6 +43,7 @@ struct globals { | |||
42 | #define user_id (G.user_id ) | 43 | #define user_id (G.user_id ) |
43 | #define quiet (G.quiet ) | 44 | #define quiet (G.quiet ) |
44 | #define signal_nr (G.signal_nr ) | 45 | #define signal_nr (G.signal_nr ) |
46 | #define execstat (G.execstat ) | ||
45 | #define INIT_G() \ | 47 | #define INIT_G() \ |
46 | do { \ | 48 | do { \ |
47 | user_id = -1; \ | 49 | user_id = -1; \ |
@@ -49,22 +51,18 @@ struct globals { | |||
49 | } while (0) | 51 | } while (0) |
50 | 52 | ||
51 | 53 | ||
52 | static int pid_is_exec(pid_t pid, const char *name) | 54 | static int pid_is_exec(pid_t pid) |
53 | { | 55 | { |
56 | struct stat st; | ||
54 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; | 57 | char buf[sizeof("/proc//exe") + sizeof(int)*3]; |
55 | char *execbuf; | ||
56 | int n; | ||
57 | 58 | ||
58 | sprintf(buf, "/proc/%u/exe", pid); | 59 | sprintf(buf, "/proc/%u/exe", pid); |
59 | n = strlen(name) + 1; | 60 | if (stat(buf, &st) < 0) |
60 | execbuf = xzalloc(n + 1); | 61 | return 0; |
61 | readlink(buf, execbuf, n); | 62 | if (st.st_dev == execstat.st_dev |
62 | /* if readlink fails because link target is longer than strlen(name), | 63 | && st.st_ino == execstat.st_ino) |
63 | * execbuf still contains "", and strcmp will return !0. */ | 64 | return 1; |
64 | n = strcmp(execbuf, name); | 65 | return 0; |
65 | if (ENABLE_FEATURE_CLEAN_UP) | ||
66 | free(execbuf); | ||
67 | return !n; /* nonzero (true) if execbuf == name */ | ||
68 | } | 66 | } |
69 | 67 | ||
70 | static int pid_is_user(int pid, int uid) | 68 | static int pid_is_user(int pid, int uid) |
@@ -104,7 +102,7 @@ static void check(int pid) | |||
104 | { | 102 | { |
105 | struct pid_list *p; | 103 | struct pid_list *p; |
106 | 104 | ||
107 | if (execname && !pid_is_exec(pid, execname)) { | 105 | if (execname && !pid_is_exec(pid)) { |
108 | return; | 106 | return; |
109 | } | 107 | } |
110 | if (userspec && !pid_is_user(pid, user_id)) { | 108 | if (userspec && !pid_is_user(pid, user_id)) { |
@@ -300,6 +298,8 @@ int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
300 | if (errno) | 298 | if (errno) |
301 | user_id = xuname2uid(userspec); | 299 | user_id = xuname2uid(userspec); |
302 | } | 300 | } |
301 | if (execname) | ||
302 | xstat(execname, &execstat); | ||
303 | 303 | ||
304 | if (opt & CTX_STOP) { | 304 | if (opt & CTX_STOP) { |
305 | int i = do_stop(); | 305 | int i = do_stop(); |