diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-30 21:23:26 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-30 21:23:26 +0000 |
commit | b35714986721a6f36ecb87034e6024138f6c0b6e (patch) | |
tree | d715bf54d18c2d72b883af8053b363db347aeebd | |
parent | c90e1be01b76aed12ef1cd77c789c842bda26ba6 (diff) | |
download | busybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.tar.gz busybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.tar.bz2 busybox-w32-b35714986721a6f36ecb87034e6024138f6c0b6e.zip |
chpst: large code shrink by Vladimir
function old new delta
chpst_main 1058 1357 +299
euidgid 56 - -56
suidgid 59 - -59
slimit 208 - -208
packed_usage 24638 24420 -218
edir 375 - -375
------------------------------------------------------------------------------
(add/remove: 0/4 grow/shrink: 1/1 up/down: 299/-916) Total: -617 bytes
-rw-r--r-- | include/usage.h | 67 | ||||
-rw-r--r-- | runit/chpst.c | 373 |
2 files changed, 209 insertions, 231 deletions
diff --git a/include/usage.h b/include/usage.h index 110fbf641..466dfac11 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -365,27 +365,26 @@ | |||
365 | "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n" | 365 | "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n" |
366 | 366 | ||
367 | #define chpst_trivial_usage \ | 367 | #define chpst_trivial_usage \ |
368 | "[-vP012] [-u user[:group]] [-U user[:group]] [-e dir] " \ | 368 | "[-vP012] [-u USER[:GRP]] [-U USER[:GRP]] [-e DIR]\n" \ |
369 | "[-/ dir] [-n nice] [-m bytes] [-d bytes] [-o files] " \ | 369 | " [-/ DIR] [-n NICE] [-m BYTES] [-d BYTES] [-o N]\n" \ |
370 | "[-p processes] [-f bytes] [-c bytes] prog args" | 370 | " [-p N] [-f BYTES] [-c BYTES] PROG ARGS" |
371 | #define chpst_full_usage "\n\n" \ | 371 | #define chpst_full_usage "\n\n" \ |
372 | "Change the process state and run specified program\n" \ | 372 | "Change the process state and run PROG\n" \ |
373 | "\nOptions:" \ | 373 | "\nOptions:" \ |
374 | "\n -u USER[:GRP] Set uid and gid" \ | 374 | "\n -u USER[:GRP] Set uid and gid" \ |
375 | "\n -U USER[:GRP] Set $UID and $GID in environment" \ | 375 | "\n -U USER[:GRP] Set $UID and $GID in environment" \ |
376 | "\n -e DIR Set environment variables as specified by files" \ | 376 | "\n -e DIR Set environment variables as specified by files" \ |
377 | "\n in DIR: file=1st_line_of_file" \ | 377 | "\n in DIR: file=1st_line_of_file" \ |
378 | "\n -/ DIR Chroot to DIR" \ | 378 | "\n -/ DIR Chroot to DIR" \ |
379 | "\n -n INC Add INC to nice value" \ | 379 | "\n -n NICE Add NICE to nice value" \ |
380 | "\n -m BYTES Limit data segment, stack segment, locked physical pages," \ | 380 | "\n -m BYTES Same as -d BYTES -s BYTES -l BYTES" \ |
381 | "\n and total of all segment per process to BYTES each" \ | ||
382 | "\n -d BYTES Limit data segment" \ | 381 | "\n -d BYTES Limit data segment" \ |
383 | "\n -o N Limit the number of open file descriptors per process to N" \ | 382 | "\n -o N Limit number of open files per process" \ |
384 | "\n -p N Limit number of processes per uid to N" \ | 383 | "\n -p N Limit number of processes per uid" \ |
385 | "\n -f BYTES Limit output file size to BYTES" \ | 384 | "\n -f BYTES Limit output file sizes" \ |
386 | "\n -c BYTES Limit core file size to BYTES" \ | 385 | "\n -c BYTES Limit core file size" \ |
387 | "\n -v Verbose" \ | 386 | "\n -v Verbose" \ |
388 | "\n -P Run prog in a new process group" \ | 387 | "\n -P Create new process group" \ |
389 | "\n -0 Close standard input" \ | 388 | "\n -0 Close standard input" \ |
390 | "\n -1 Close standard output" \ | 389 | "\n -1 Close standard output" \ |
391 | "\n -2 Close standard error" \ | 390 | "\n -2 Close standard error" \ |
@@ -394,41 +393,37 @@ | |||
394 | "account prog args" | 393 | "account prog args" |
395 | #define setuidgid_full_usage "\n\n" \ | 394 | #define setuidgid_full_usage "\n\n" \ |
396 | "Set uid and gid to account's uid and gid, removing all supplementary\n" \ | 395 | "Set uid and gid to account's uid and gid, removing all supplementary\n" \ |
397 | "groups, then run prog" | 396 | "groups and run PROG" |
398 | #define envuidgid_trivial_usage \ | 397 | #define envuidgid_trivial_usage \ |
399 | "account prog args" | 398 | "account prog args" |
400 | #define envuidgid_full_usage "\n\n" \ | 399 | #define envuidgid_full_usage "\n\n" \ |
401 | "Set $UID to account's uid and $GID to account's gid, then run prog" | 400 | "Set $UID to account's uid and $GID to account's gid and run PROG" |
402 | #define envdir_trivial_usage \ | 401 | #define envdir_trivial_usage \ |
403 | "dir prog args" | 402 | "dir prog args" |
404 | #define envdir_full_usage "\n\n" \ | 403 | #define envdir_full_usage "\n\n" \ |
405 | "Set various environment variables as specified by files\n" \ | 404 | "Set various environment variables as specified by files\n" \ |
406 | "in the directory dir, then run prog" | 405 | "in the directory dir and run PROG" |
407 | #define softlimit_trivial_usage \ | 406 | #define softlimit_trivial_usage \ |
408 | "[-a allbytes] [-c corebytes] [-d databytes] [-f filebytes] " \ | 407 | "[-a BYTES] [-m BYTES] [-d BYTES] [-s BYTES] [-l BYTES]\n" \ |
409 | "[-l lockbytes] [-m membytes] [-o openfiles] [-p processes] " \ | 408 | " [-f BYTES] [-c BYTES] [-r BYTES] [-o N] [-p N] [-t N]\n" \ |
410 | "[-r residentbytes] [-s stackbytes] [-t cpusecs] prog args" | 409 | " PROG ARGS" |
411 | #define softlimit_full_usage "\n\n" \ | 410 | #define softlimit_full_usage "\n\n" \ |
412 | "Set soft resource limits, then run prog\n" \ | 411 | "Set soft resource limits, then run PROG\n" \ |
413 | "\nOptions:" \ | 412 | "\nOptions:" \ |
414 | "\n -m n Same as -d n -s n -l n -a n" \ | 413 | "\n -a BYTES Limit total size of all segments" \ |
415 | "\n -d n Limit the data segment per process to n bytes" \ | 414 | "\n -m BYTES Same as -d BYTES -s BYTES -l BYTES -a BYTES" \ |
416 | "\n -s n Limit the stack segment per process to n bytes" \ | 415 | "\n -d BYTES Limit data segment" \ |
417 | "\n -l n Limit the locked physical pages per process to n bytes" \ | 416 | "\n -s BYTES Limit stack segment" \ |
418 | "\n -a n Limit the total of all segments per process to n bytes" \ | 417 | "\n -l BYTES Limit locked memory size" \ |
419 | "\n -o n Limit the number of open file descriptors per process to n" \ | 418 | "\n -o N Limit number of open files per process" \ |
420 | "\n -p n Limit the number of processes per uid to n" \ | 419 | "\n -p N Limit number of processes per uid" \ |
421 | "\nOptions controlling file sizes:" \ | 420 | "\nOptions controlling file sizes:" \ |
422 | "\n -f n Limit output file sizes to n bytes" \ | 421 | "\n -f BYTES Limit output file sizes" \ |
423 | "\n -c n Limit core file sizes to n bytes" \ | 422 | "\n -c BYTES Limit core file size" \ |
424 | "\nEfficiency opts:" \ | 423 | "\nEfficiency opts:" \ |
425 | "\n -r n Limit the resident set size to n bytes. This limit is not" \ | 424 | "\n -r BYTES Limit resident set size" \ |
426 | "\n enforced unless physical memory is full" \ | 425 | "\n -t N Limit CPU time, process receives" \ |
427 | "\n -t n Limit the CPU time to n seconds. This limit is not enforced" \ | 426 | "\n a SIGXCPU after N seconds" \ |
428 | "\n except that the process receives a SIGXCPU signal after n seconds" \ | ||
429 | "\n" \ | ||
430 | "\nSome options may have no effect on some operating systems" \ | ||
431 | "\nn may be =, indicating that soft limit should be set equal to hard limit" \ | ||
432 | 427 | ||
433 | #define chroot_trivial_usage \ | 428 | #define chroot_trivial_usage \ |
434 | "NEWROOT [COMMAND...]" | 429 | "NEWROOT [COMMAND...]" |
diff --git a/runit/chpst.c b/runit/chpst.c index 3c841ddbb..24d1d6e2c 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -29,73 +29,68 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
29 | /* Dependencies on runit_lib.c removed */ | 29 | /* Dependencies on runit_lib.c removed */ |
30 | 30 | ||
31 | #include "libbb.h" | 31 | #include "libbb.h" |
32 | |||
33 | #include <dirent.h> | 32 | #include <dirent.h> |
34 | 33 | ||
35 | // Must match constants in chpst_main! | 34 | /* |
36 | #define OPT_verbose (option_mask32 & 0x2000) | 35 | Five applets here: chpst, envdir, envuidgid, setuidgid, softlimit. |
37 | #define OPT_pgrp (option_mask32 & 0x4000) | ||
38 | #define OPT_nostdin (option_mask32 & 0x8000) | ||
39 | #define OPT_nostdout (option_mask32 & 0x10000) | ||
40 | #define OPT_nostderr (option_mask32 & 0x20000) | ||
41 | 36 | ||
42 | struct globals { | 37 | Only softlimit and chpst are taking options: |
43 | char *set_user; | ||
44 | char *env_user; | ||
45 | const char *env_dir; | ||
46 | const char *root; | ||
47 | long limitd; /* limitX are initialized to -2 */ | ||
48 | long limits; | ||
49 | long limitl; | ||
50 | long limita; | ||
51 | long limito; | ||
52 | long limitp; | ||
53 | long limitf; | ||
54 | long limitc; | ||
55 | long limitr; | ||
56 | long limitt; | ||
57 | int nicelvl; | ||
58 | }; | ||
59 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
60 | #define set_user (G.set_user) | ||
61 | #define env_user (G.env_user) | ||
62 | #define env_dir (G.env_dir ) | ||
63 | #define root (G.root ) | ||
64 | #define limitd (G.limitd ) | ||
65 | #define limits (G.limits ) | ||
66 | #define limitl (G.limitl ) | ||
67 | #define limita (G.limita ) | ||
68 | #define limito (G.limito ) | ||
69 | #define limitp (G.limitp ) | ||
70 | #define limitf (G.limitf ) | ||
71 | #define limitc (G.limitc ) | ||
72 | #define limitr (G.limitr ) | ||
73 | #define limitt (G.limitt ) | ||
74 | #define nicelvl (G.nicelvl ) | ||
75 | #define INIT_G() do { \ | ||
76 | long *p = &limitd; \ | ||
77 | do *p++ = -2; while (p <= &limitt); \ | ||
78 | } while (0) | ||
79 | |||
80 | static void suidgid(char *user) | ||
81 | { | ||
82 | struct bb_uidgid_t ugid; | ||
83 | 38 | ||
84 | xget_uidgid(&ugid, user); | 39 | # common |
85 | if (setgroups(1, &ugid.gid) == -1) | 40 | -o N Limit number of open files per process |
86 | bb_perror_msg_and_die("setgroups"); | 41 | -p N Limit number of processes per uid |
87 | xsetgid(ugid.gid); | 42 | -m BYTES Same as -d BYTES -s BYTES -l BYTES [-a BYTES] |
88 | xsetuid(ugid.uid); | 43 | -d BYTES Limit data segment |
89 | } | 44 | -f BYTES Limit output file sizes |
45 | -c BYTES Limit core file size | ||
46 | # softlimit | ||
47 | -a BYTES Limit total size of all segments | ||
48 | -s BYTES Limit stack segment | ||
49 | -l BYTES Limit locked memory size | ||
50 | -r BYTES Limit resident set size | ||
51 | -t N Limit CPU time | ||
52 | # chpst | ||
53 | -u USER[:GRP] Set uid and gid | ||
54 | -U USER[:GRP] Set $UID and $GID in environment | ||
55 | -e DIR Set environment variables as specified by files in DIR | ||
56 | -/ DIR Chroot to DIR | ||
57 | -n NICE Add NICE to nice value | ||
58 | -v Verbose | ||
59 | -P Create new process group | ||
60 | -0 -1 -2 Close fd 0,1,2 | ||
90 | 61 | ||
91 | static void euidgid(char *user) | 62 | Even though we accept all these options for both softlimit and chpst, |
92 | { | 63 | they are not to be advertised on their help texts. |
93 | struct bb_uidgid_t ugid; | 64 | We have enough problems with feature creep in other people's |
65 | software, don't want to add our own. | ||
94 | 66 | ||
95 | xget_uidgid(&ugid, user); | 67 | envdir, envuidgid, setuidgid take no options, but they reuse code which |
96 | xsetenv("GID", utoa(ugid.gid)); | 68 | handles -e, -U and -u. |
97 | xsetenv("UID", utoa(ugid.uid)); | 69 | */ |
98 | } | 70 | |
71 | enum { | ||
72 | OPT_a = (1 << 0) * ENABLE_SOFTLIMIT, | ||
73 | OPT_c = (1 << 1) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
74 | OPT_d = (1 << 2) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
75 | OPT_f = (1 << 3) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
76 | OPT_l = (1 << 4) * ENABLE_SOFTLIMIT, | ||
77 | OPT_m = (1 << 5) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
78 | OPT_o = (1 << 6) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
79 | OPT_p = (1 << 7) * (ENABLE_SOFTLIMIT || ENABLE_CHPST), | ||
80 | OPT_r = (1 << 8) * ENABLE_SOFTLIMIT, | ||
81 | OPT_s = (1 << 9) * ENABLE_SOFTLIMIT, | ||
82 | OPT_t = (1 << 10) * ENABLE_SOFTLIMIT, | ||
83 | OPT_u = (1 << 11) * (ENABLE_CHPST || ENABLE_SETUIDGID), | ||
84 | OPT_U = (1 << 12) * (ENABLE_CHPST || ENABLE_ENVUIDGID), | ||
85 | OPT_e = (1 << 13) * (ENABLE_CHPST || ENABLE_ENVDIR), | ||
86 | OPT_root = (1 << 14) * ENABLE_CHPST, | ||
87 | OPT_n = (1 << 15) * ENABLE_CHPST, | ||
88 | OPT_v = (1 << 16) * ENABLE_CHPST, | ||
89 | OPT_P = (1 << 17) * ENABLE_CHPST, | ||
90 | OPT_0 = (1 << 18) * ENABLE_CHPST, | ||
91 | OPT_1 = (1 << 19) * ENABLE_CHPST, | ||
92 | OPT_2 = (1 << 20) * ENABLE_CHPST, | ||
93 | }; | ||
99 | 94 | ||
100 | static void edir(const char *directory_name) | 95 | static void edir(const char *directory_name) |
101 | { | 96 | { |
@@ -126,8 +121,8 @@ static void edir(const char *directory_name) | |||
126 | continue; | 121 | continue; |
127 | fd = open(d->d_name, O_RDONLY | O_NDELAY); | 122 | fd = open(d->d_name, O_RDONLY | O_NDELAY); |
128 | if (fd < 0) { | 123 | if (fd < 0) { |
129 | if ((errno == EISDIR) && env_dir) { | 124 | if ((errno == EISDIR) && directory_name) { |
130 | if (OPT_verbose) | 125 | if (option_mask32 & OPT_v) |
131 | bb_perror_msg("warning: %s/%s is a directory", | 126 | bb_perror_msg("warning: %s/%s is a directory", |
132 | directory_name, d->d_name); | 127 | directory_name, d->d_name); |
133 | continue; | 128 | continue; |
@@ -175,229 +170,217 @@ static void limit(int what, long l) | |||
175 | bb_perror_msg_and_die("setrlimit"); | 170 | bb_perror_msg_and_die("setrlimit"); |
176 | } | 171 | } |
177 | 172 | ||
178 | static void slimit(void) | 173 | int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
174 | int chpst_main(int argc UNUSED_PARAM, char **argv) | ||
179 | { | 175 | { |
180 | if (limitd >= -1) { | 176 | struct bb_uidgid_t ugid; |
177 | char *set_user; | ||
178 | char *env_user; | ||
179 | char *env_dir; | ||
180 | char *root; | ||
181 | char *nicestr; | ||
182 | unsigned limita; | ||
183 | unsigned limitc; | ||
184 | unsigned limitd; | ||
185 | unsigned limitf; | ||
186 | unsigned limitl; | ||
187 | unsigned limitm; | ||
188 | unsigned limito; | ||
189 | unsigned limitp; | ||
190 | unsigned limitr; | ||
191 | unsigned limits; | ||
192 | unsigned limitt; | ||
193 | unsigned opt; | ||
194 | |||
195 | if ((ENABLE_CHPST && applet_name[0] == 'c') | ||
196 | || (ENABLE_SOFTLIMIT && applet_name[1] == 'o') | ||
197 | ) { | ||
198 | // FIXME: can we live with int-sized limits? | ||
199 | // can we live with 40000 days? | ||
200 | // if yes -> getopt converts strings to numbers for us | ||
201 | opt_complementary = "-1:a+:c+:d+:f+:l+:m+:o+:p+:r+:s+:t+"; | ||
202 | opt = getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:u:U:e:" | ||
203 | USE_CHPST("/:n:vP012"), | ||
204 | &limita, &limitc, &limitd, &limitf, &limitl, | ||
205 | &limitm, &limito, &limitp, &limitr, &limits, &limitt, | ||
206 | &set_user, &env_user, &env_dir | ||
207 | USE_CHPST(, &root, &nicestr)); | ||
208 | argv += optind; | ||
209 | if (opt & OPT_m) { // -m means -asld | ||
210 | limita = limits = limitl = limitd = limitm; | ||
211 | opt |= (OPT_s | OPT_l | OPT_a | OPT_d); | ||
212 | } | ||
213 | } else { | ||
214 | option_mask32 = opt = 0; | ||
215 | argv++; | ||
216 | } | ||
217 | |||
218 | // envdir? | ||
219 | if (ENABLE_ENVDIR && applet_name[3] == 'd') { | ||
220 | env_dir = *argv++; | ||
221 | opt |= OPT_e; | ||
222 | } | ||
223 | |||
224 | // setuidgid? | ||
225 | if (ENABLE_SETUIDGID && applet_name[0] == 's') { | ||
226 | set_user = *argv++; | ||
227 | opt |= OPT_u; | ||
228 | } | ||
229 | |||
230 | // envuidgid? | ||
231 | if (ENABLE_ENVUIDGID && applet_name[0] == 'e') { | ||
232 | env_user = *argv++; | ||
233 | opt |= OPT_U; | ||
234 | } | ||
235 | |||
236 | // we must have PROG [ARGS] | ||
237 | if (!*argv) | ||
238 | bb_show_usage(); | ||
239 | |||
240 | // set limits | ||
241 | if (opt & OPT_d) { | ||
181 | #ifdef RLIMIT_DATA | 242 | #ifdef RLIMIT_DATA |
182 | limit(RLIMIT_DATA, limitd); | 243 | limit(RLIMIT_DATA, limitd); |
183 | #else | 244 | #else |
184 | if (OPT_verbose) | 245 | if (opt & OPT_v) |
185 | bb_error_msg("system does not support RLIMIT_%s", | 246 | bb_error_msg("system does not support RLIMIT_%s", |
186 | "DATA"); | 247 | "DATA"); |
187 | #endif | 248 | #endif |
188 | } | 249 | } |
189 | if (limits >= -1) { | 250 | if (opt & OPT_s) { |
190 | #ifdef RLIMIT_STACK | 251 | #ifdef RLIMIT_STACK |
191 | limit(RLIMIT_STACK, limits); | 252 | limit(RLIMIT_STACK, limits); |
192 | #else | 253 | #else |
193 | if (OPT_verbose) | 254 | if (opt & OPT_v) |
194 | bb_error_msg("system does not support RLIMIT_%s", | 255 | bb_error_msg("system does not support RLIMIT_%s", |
195 | "STACK"); | 256 | "STACK"); |
196 | #endif | 257 | #endif |
197 | } | 258 | } |
198 | if (limitl >= -1) { | 259 | if (opt & OPT_l) { |
199 | #ifdef RLIMIT_MEMLOCK | 260 | #ifdef RLIMIT_MEMLOCK |
200 | limit(RLIMIT_MEMLOCK, limitl); | 261 | limit(RLIMIT_MEMLOCK, limitl); |
201 | #else | 262 | #else |
202 | if (OPT_verbose) | 263 | if (opt & OPT_v) |
203 | bb_error_msg("system does not support RLIMIT_%s", | 264 | bb_error_msg("system does not support RLIMIT_%s", |
204 | "MEMLOCK"); | 265 | "MEMLOCK"); |
205 | #endif | 266 | #endif |
206 | } | 267 | } |
207 | if (limita >= -1) { | 268 | if (opt & OPT_a) { |
208 | #ifdef RLIMIT_VMEM | 269 | #ifdef RLIMIT_VMEM |
209 | limit(RLIMIT_VMEM, limita); | 270 | limit(RLIMIT_VMEM, limita); |
210 | #else | 271 | #else |
211 | #ifdef RLIMIT_AS | 272 | #ifdef RLIMIT_AS |
212 | limit(RLIMIT_AS, limita); | 273 | limit(RLIMIT_AS, limita); |
213 | #else | 274 | #else |
214 | if (OPT_verbose) | 275 | if (opt & OPT_v) |
215 | bb_error_msg("system does not support RLIMIT_%s", | 276 | bb_error_msg("system does not support RLIMIT_%s", |
216 | "VMEM"); | 277 | "VMEM"); |
217 | #endif | 278 | #endif |
218 | #endif | 279 | #endif |
219 | } | 280 | } |
220 | if (limito >= -1) { | 281 | if (opt & OPT_o) { |
221 | #ifdef RLIMIT_NOFILE | 282 | #ifdef RLIMIT_NOFILE |
222 | limit(RLIMIT_NOFILE, limito); | 283 | limit(RLIMIT_NOFILE, limito); |
223 | #else | 284 | #else |
224 | #ifdef RLIMIT_OFILE | 285 | #ifdef RLIMIT_OFILE |
225 | limit(RLIMIT_OFILE, limito); | 286 | limit(RLIMIT_OFILE, limito); |
226 | #else | 287 | #else |
227 | if (OPT_verbose) | 288 | if (opt & OPT_v) |
228 | bb_error_msg("system does not support RLIMIT_%s", | 289 | bb_error_msg("system does not support RLIMIT_%s", |
229 | "NOFILE"); | 290 | "NOFILE"); |
230 | #endif | 291 | #endif |
231 | #endif | 292 | #endif |
232 | } | 293 | } |
233 | if (limitp >= -1) { | 294 | if (opt & OPT_p) { |
234 | #ifdef RLIMIT_NPROC | 295 | #ifdef RLIMIT_NPROC |
235 | limit(RLIMIT_NPROC, limitp); | 296 | limit(RLIMIT_NPROC, limitp); |
236 | #else | 297 | #else |
237 | if (OPT_verbose) | 298 | if (opt & OPT_v) |
238 | bb_error_msg("system does not support RLIMIT_%s", | 299 | bb_error_msg("system does not support RLIMIT_%s", |
239 | "NPROC"); | 300 | "NPROC"); |
240 | #endif | 301 | #endif |
241 | } | 302 | } |
242 | if (limitf >= -1) { | 303 | if (opt & OPT_f) { |
243 | #ifdef RLIMIT_FSIZE | 304 | #ifdef RLIMIT_FSIZE |
244 | limit(RLIMIT_FSIZE, limitf); | 305 | limit(RLIMIT_FSIZE, limitf); |
245 | #else | 306 | #else |
246 | if (OPT_verbose) | 307 | if (opt & OPT_v) |
247 | bb_error_msg("system does not support RLIMIT_%s", | 308 | bb_error_msg("system does not support RLIMIT_%s", |
248 | "FSIZE"); | 309 | "FSIZE"); |
249 | #endif | 310 | #endif |
250 | } | 311 | } |
251 | if (limitc >= -1) { | 312 | if (opt & OPT_c) { |
252 | #ifdef RLIMIT_CORE | 313 | #ifdef RLIMIT_CORE |
253 | limit(RLIMIT_CORE, limitc); | 314 | limit(RLIMIT_CORE, limitc); |
254 | #else | 315 | #else |
255 | if (OPT_verbose) | 316 | if (opt & OPT_v) |
256 | bb_error_msg("system does not support RLIMIT_%s", | 317 | bb_error_msg("system does not support RLIMIT_%s", |
257 | "CORE"); | 318 | "CORE"); |
258 | #endif | 319 | #endif |
259 | } | 320 | } |
260 | if (limitr >= -1) { | 321 | if (opt & OPT_r) { |
261 | #ifdef RLIMIT_RSS | 322 | #ifdef RLIMIT_RSS |
262 | limit(RLIMIT_RSS, limitr); | 323 | limit(RLIMIT_RSS, limitr); |
263 | #else | 324 | #else |
264 | if (OPT_verbose) | 325 | if (opt & OPT_v) |
265 | bb_error_msg("system does not support RLIMIT_%s", | 326 | bb_error_msg("system does not support RLIMIT_%s", |
266 | "RSS"); | 327 | "RSS"); |
267 | #endif | 328 | #endif |
268 | } | 329 | } |
269 | if (limitt >= -1) { | 330 | if (opt & OPT_t) { |
270 | #ifdef RLIMIT_CPU | 331 | #ifdef RLIMIT_CPU |
271 | limit(RLIMIT_CPU, limitt); | 332 | limit(RLIMIT_CPU, limitt); |
272 | #else | 333 | #else |
273 | if (OPT_verbose) | 334 | if (opt & OPT_v) |
274 | bb_error_msg("system does not support RLIMIT_%s", | 335 | bb_error_msg("system does not support RLIMIT_%s", |
275 | "CPU"); | 336 | "CPU"); |
276 | #endif | 337 | #endif |
277 | } | 338 | } |
278 | } | ||
279 | 339 | ||
280 | /* argv[0] */ | 340 | if (opt & OPT_P) |
281 | static void setuidgid(int, char **) NORETURN; | 341 | setsid(); |
282 | static void envuidgid(int, char **) NORETURN; | ||
283 | static void envdir(int, char **) NORETURN; | ||
284 | static void softlimit(int, char **) NORETURN; | ||
285 | 342 | ||
286 | int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 343 | if (opt & OPT_e) |
287 | int chpst_main(int argc UNUSED_PARAM, char **argv) | 344 | edir(env_dir); |
288 | { | 345 | |
289 | INIT_G(); | 346 | // FIXME: chrooted jail must have /etc/passwd if we move this after chroot! |
290 | 347 | // OTOH chroot fails for non-roots! | |
291 | if (applet_name[3] == 'd') envdir(argc, argv); | 348 | // SOLUTION: cache uid/gid before chroot, apply uid/gid after |
292 | if (applet_name[1] == 'o') softlimit(argc, argv); | 349 | if (opt & OPT_U) { |
293 | if (applet_name[0] == 's') setuidgid(argc, argv); | 350 | xget_uidgid(&ugid, env_user); |
294 | if (applet_name[0] == 'e') envuidgid(argc, argv); | 351 | xsetenv("GID", utoa(ugid.gid)); |
295 | // otherwise we are chpst | 352 | xsetenv("UID", utoa(ugid.uid)); |
296 | |||
297 | { | ||
298 | char *m,*d,*o,*p,*f,*c,*r,*t,*n; | ||
299 | getopt32(argv, "+u:U:e:m:d:o:p:f:c:r:t:/:n:vP012", | ||
300 | &set_user,&env_user,&env_dir, | ||
301 | &m,&d,&o,&p,&f,&c,&r,&t,&root,&n); | ||
302 | // if (option_mask32 & 0x1) // -u | ||
303 | // if (option_mask32 & 0x2) // -U | ||
304 | // if (option_mask32 & 0x4) // -e | ||
305 | if (option_mask32 & 0x8) limits = limitl = limita = limitd = xatoul(m); // -m | ||
306 | if (option_mask32 & 0x10) limitd = xatoul(d); // -d | ||
307 | if (option_mask32 & 0x20) limito = xatoul(o); // -o | ||
308 | if (option_mask32 & 0x40) limitp = xatoul(p); // -p | ||
309 | if (option_mask32 & 0x80) limitf = xatoul(f); // -f | ||
310 | if (option_mask32 & 0x100) limitc = xatoul(c); // -c | ||
311 | if (option_mask32 & 0x200) limitr = xatoul(r); // -r | ||
312 | if (option_mask32 & 0x400) limitt = xatoul(t); // -t | ||
313 | // if (option_mask32 & 0x800) // -/ | ||
314 | if (option_mask32 & 0x1000) nicelvl = xatoi(n); // -n | ||
315 | // The below consts should match #defines at top! | ||
316 | //if (option_mask32 & 0x2000) OPT_verbose = 1; // -v | ||
317 | //if (option_mask32 & 0x4000) OPT_pgrp = 1; // -P | ||
318 | //if (option_mask32 & 0x8000) OPT_nostdin = 1; // -0 | ||
319 | //if (option_mask32 & 0x10000) OPT_nostdout = 1; // -1 | ||
320 | //if (option_mask32 & 0x20000) OPT_nostderr = 1; // -2 | ||
321 | } | 353 | } |
322 | argv += optind; | ||
323 | if (!argv || !*argv) bb_show_usage(); | ||
324 | 354 | ||
325 | if (OPT_pgrp) setsid(); | 355 | if (opt & OPT_u) { |
326 | if (env_dir) edir(env_dir); | 356 | xget_uidgid(&ugid, set_user); |
327 | if (root) { | 357 | } |
358 | |||
359 | if (opt & OPT_root) { | ||
328 | xchdir(root); | 360 | xchdir(root); |
329 | xchroot("."); | 361 | xchroot("."); |
330 | } | 362 | } |
331 | slimit(); | 363 | |
332 | if (nicelvl) { | 364 | if (opt & OPT_u) { |
365 | if (setgroups(1, &ugid.gid) == -1) | ||
366 | bb_perror_msg_and_die("setgroups"); | ||
367 | xsetgid(ugid.gid); | ||
368 | xsetuid(ugid.uid); | ||
369 | } | ||
370 | |||
371 | if (opt & OPT_n) { | ||
333 | errno = 0; | 372 | errno = 0; |
334 | if (nice(nicelvl) == -1) | 373 | if (nice(xatoi(nicestr)) == -1) |
335 | bb_perror_msg_and_die("nice"); | 374 | bb_perror_msg_and_die("nice"); |
336 | } | 375 | } |
337 | if (env_user) euidgid(env_user); | ||
338 | if (set_user) suidgid(set_user); | ||
339 | if (OPT_nostdin) close(0); | ||
340 | if (OPT_nostdout) close(1); | ||
341 | if (OPT_nostderr) close(2); | ||
342 | BB_EXECVP(argv[0], argv); | ||
343 | bb_perror_msg_and_die("exec %s", argv[0]); | ||
344 | } | ||
345 | |||
346 | static void setuidgid(int argc UNUSED_PARAM, char **argv) | ||
347 | { | ||
348 | const char *account; | ||
349 | |||
350 | account = *++argv; | ||
351 | if (!account) bb_show_usage(); | ||
352 | if (!*++argv) bb_show_usage(); | ||
353 | suidgid((char*)account); | ||
354 | BB_EXECVP(argv[0], argv); | ||
355 | bb_perror_msg_and_die("exec %s", argv[0]); | ||
356 | } | ||
357 | |||
358 | static void envuidgid(int argc UNUSED_PARAM, char **argv) | ||
359 | { | ||
360 | const char *account; | ||
361 | 376 | ||
362 | account = *++argv; | 377 | if (opt & OPT_0) |
363 | if (!account) bb_show_usage(); | 378 | close(STDIN_FILENO); |
364 | if (!*++argv) bb_show_usage(); | 379 | if (opt & OPT_1) |
365 | euidgid((char*)account); | 380 | close(STDOUT_FILENO); |
366 | BB_EXECVP(argv[0], argv); | 381 | if (opt & OPT_2) |
367 | bb_perror_msg_and_die("exec %s", argv[0]); | 382 | close(STDERR_FILENO); |
368 | } | ||
369 | 383 | ||
370 | static void envdir(int argc UNUSED_PARAM, char **argv) | ||
371 | { | ||
372 | const char *dir; | ||
373 | |||
374 | dir = *++argv; | ||
375 | if (!dir) bb_show_usage(); | ||
376 | if (!*++argv) bb_show_usage(); | ||
377 | edir(dir); | ||
378 | BB_EXECVP(argv[0], argv); | ||
379 | bb_perror_msg_and_die("exec %s", argv[0]); | ||
380 | } | ||
381 | |||
382 | static void softlimit(int argc UNUSED_PARAM, char **argv) | ||
383 | { | ||
384 | char *a,*c,*d,*f,*l,*m,*o,*p,*r,*s,*t; | ||
385 | getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:", | ||
386 | &a,&c,&d,&f,&l,&m,&o,&p,&r,&s,&t); | ||
387 | if (option_mask32 & 0x001) limita = xatoul(a); // -a | ||
388 | if (option_mask32 & 0x002) limitc = xatoul(c); // -c | ||
389 | if (option_mask32 & 0x004) limitd = xatoul(d); // -d | ||
390 | if (option_mask32 & 0x008) limitf = xatoul(f); // -f | ||
391 | if (option_mask32 & 0x010) limitl = xatoul(l); // -l | ||
392 | if (option_mask32 & 0x020) limits = limitl = limita = limitd = xatoul(m); // -m | ||
393 | if (option_mask32 & 0x040) limito = xatoul(o); // -o | ||
394 | if (option_mask32 & 0x080) limitp = xatoul(p); // -p | ||
395 | if (option_mask32 & 0x100) limitr = xatoul(r); // -r | ||
396 | if (option_mask32 & 0x200) limits = xatoul(s); // -s | ||
397 | if (option_mask32 & 0x400) limitt = xatoul(t); // -t | ||
398 | argv += optind; | ||
399 | if (!argv[0]) bb_show_usage(); | ||
400 | slimit(); | ||
401 | BB_EXECVP(argv[0], argv); | 384 | BB_EXECVP(argv[0], argv); |
402 | bb_perror_msg_and_die("exec %s", argv[0]); | 385 | bb_perror_msg_and_die("exec %s", argv[0]); |
403 | } | 386 | } |