diff options
-rw-r--r-- | runit/chpst.c | 128 |
1 files changed, 82 insertions, 46 deletions
diff --git a/runit/chpst.c b/runit/chpst.c index 87cd8e04a..0c26d836e 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -39,21 +39,43 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
39 | #define OPT_nostdout (option_mask32 & 0x10000) | 39 | #define OPT_nostdout (option_mask32 & 0x10000) |
40 | #define OPT_nostderr (option_mask32 & 0x20000) | 40 | #define OPT_nostderr (option_mask32 & 0x20000) |
41 | 41 | ||
42 | static char *set_user; | 42 | struct globals { |
43 | static char *env_user; | 43 | char *set_user; |
44 | static const char *env_dir; | 44 | char *env_user; |
45 | static long limitd = -2; | 45 | const char *env_dir; |
46 | static long limits = -2; | 46 | const char *root; |
47 | static long limitl = -2; | 47 | long limitd; /* limitX are initialized to -2 */ |
48 | static long limita = -2; | 48 | long limits; |
49 | static long limito = -2; | 49 | long limitl; |
50 | static long limitp = -2; | 50 | long limita; |
51 | static long limitf = -2; | 51 | long limito; |
52 | static long limitc = -2; | 52 | long limitp; |
53 | static long limitr = -2; | 53 | long limitf; |
54 | static long limitt = -2; | 54 | long limitc; |
55 | static int nicelvl; | 55 | long limitr; |
56 | static const char *root; | 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) | ||
57 | 79 | ||
58 | static void suidgid(char *user) | 80 | static void suidgid(char *user) |
59 | { | 81 | { |
@@ -100,7 +122,8 @@ static void edir(const char *directory_name) | |||
100 | directory_name); | 122 | directory_name); |
101 | break; | 123 | break; |
102 | } | 124 | } |
103 | if (d->d_name[0] == '.') continue; | 125 | if (d->d_name[0] == '.') |
126 | continue; | ||
104 | fd = open(d->d_name, O_RDONLY | O_NDELAY); | 127 | fd = open(d->d_name, O_RDONLY | O_NDELAY); |
105 | if (fd < 0) { | 128 | if (fd < 0) { |
106 | if ((errno == EISDIR) && env_dir) { | 129 | if ((errno == EISDIR) && env_dir) { |
@@ -129,9 +152,9 @@ static void edir(const char *directory_name) | |||
129 | tail = memchr(buf, '\n', sizeof(buf)); | 152 | tail = memchr(buf, '\n', sizeof(buf)); |
130 | /* skip trailing whitespace */; | 153 | /* skip trailing whitespace */; |
131 | while (1) { | 154 | while (1) { |
132 | if (tail[0]==' ') tail[0] = '\0'; | 155 | if (tail[0] == ' ') tail[0] = '\0'; |
133 | if (tail[0]=='\t') tail[0] = '\0'; | 156 | if (tail[0] == '\t') tail[0] = '\0'; |
134 | if (tail[0]=='\n') tail[0] = '\0'; | 157 | if (tail[0] == '\n') tail[0] = '\0'; |
135 | if (tail == buf) break; | 158 | if (tail == buf) break; |
136 | tail--; | 159 | tail--; |
137 | } | 160 | } |
@@ -139,7 +162,8 @@ static void edir(const char *directory_name) | |||
139 | } | 162 | } |
140 | } | 163 | } |
141 | closedir(dir); | 164 | closedir(dir); |
142 | if (fchdir(wdir) == -1) bb_perror_msg_and_die("fchdir"); | 165 | if (fchdir(wdir) == -1) |
166 | bb_perror_msg_and_die("fchdir"); | ||
143 | close(wdir); | 167 | close(wdir); |
144 | } | 168 | } |
145 | 169 | ||
@@ -147,12 +171,14 @@ static void limit(int what, long l) | |||
147 | { | 171 | { |
148 | struct rlimit r; | 172 | struct rlimit r; |
149 | 173 | ||
150 | if (getrlimit(what, &r) == -1) bb_perror_msg_and_die("getrlimit"); | 174 | if (getrlimit(what, &r) == -1) |
175 | bb_perror_msg_and_die("getrlimit"); | ||
151 | if ((l < 0) || (l > r.rlim_max)) | 176 | if ((l < 0) || (l > r.rlim_max)) |
152 | r.rlim_cur = r.rlim_max; | 177 | r.rlim_cur = r.rlim_max; |
153 | else | 178 | else |
154 | r.rlim_cur = l; | 179 | r.rlim_cur = l; |
155 | if (setrlimit(what, &r) == -1) bb_perror_msg_and_die("setrlimit"); | 180 | if (setrlimit(what, &r) == -1) |
181 | bb_perror_msg_and_die("setrlimit"); | ||
156 | } | 182 | } |
157 | 183 | ||
158 | static void slimit(void) | 184 | static void slimit(void) |
@@ -161,24 +187,27 @@ static void slimit(void) | |||
161 | #ifdef RLIMIT_DATA | 187 | #ifdef RLIMIT_DATA |
162 | limit(RLIMIT_DATA, limitd); | 188 | limit(RLIMIT_DATA, limitd); |
163 | #else | 189 | #else |
164 | if (OPT_verbose) bb_error_msg("system does not support %s", | 190 | if (OPT_verbose) |
165 | "RLIMIT_DATA"); | 191 | bb_error_msg("system does not support RLIMIT_%s", |
192 | "DATA"); | ||
166 | #endif | 193 | #endif |
167 | } | 194 | } |
168 | if (limits >= -1) { | 195 | if (limits >= -1) { |
169 | #ifdef RLIMIT_STACK | 196 | #ifdef RLIMIT_STACK |
170 | limit(RLIMIT_STACK, limits); | 197 | limit(RLIMIT_STACK, limits); |
171 | #else | 198 | #else |
172 | if (OPT_verbose) bb_error_msg("system does not support %s", | 199 | if (OPT_verbose) |
173 | "RLIMIT_STACK"); | 200 | bb_error_msg("system does not support RLIMIT_%s", |
201 | "STACK"); | ||
174 | #endif | 202 | #endif |
175 | } | 203 | } |
176 | if (limitl >= -1) { | 204 | if (limitl >= -1) { |
177 | #ifdef RLIMIT_MEMLOCK | 205 | #ifdef RLIMIT_MEMLOCK |
178 | limit(RLIMIT_MEMLOCK, limitl); | 206 | limit(RLIMIT_MEMLOCK, limitl); |
179 | #else | 207 | #else |
180 | if (OPT_verbose) bb_error_msg("system does not support %s", | 208 | if (OPT_verbose) |
181 | "RLIMIT_MEMLOCK"); | 209 | bb_error_msg("system does not support RLIMIT_%s", |
210 | "MEMLOCK"); | ||
182 | #endif | 211 | #endif |
183 | } | 212 | } |
184 | if (limita >= -1) { | 213 | if (limita >= -1) { |
@@ -189,8 +218,8 @@ static void slimit(void) | |||
189 | limit(RLIMIT_AS, limita); | 218 | limit(RLIMIT_AS, limita); |
190 | #else | 219 | #else |
191 | if (OPT_verbose) | 220 | if (OPT_verbose) |
192 | bb_error_msg("system does not support %s", | 221 | bb_error_msg("system does not support RLIMIT_%s", |
193 | "RLIMIT_VMEM"); | 222 | "VMEM"); |
194 | #endif | 223 | #endif |
195 | #endif | 224 | #endif |
196 | } | 225 | } |
@@ -202,8 +231,8 @@ static void slimit(void) | |||
202 | limit(RLIMIT_OFILE, limito); | 231 | limit(RLIMIT_OFILE, limito); |
203 | #else | 232 | #else |
204 | if (OPT_verbose) | 233 | if (OPT_verbose) |
205 | bb_error_msg("system does not support %s", | 234 | bb_error_msg("system does not support RLIMIT_%s", |
206 | "RLIMIT_NOFILE"); | 235 | "NOFILE"); |
207 | #endif | 236 | #endif |
208 | #endif | 237 | #endif |
209 | } | 238 | } |
@@ -211,53 +240,60 @@ static void slimit(void) | |||
211 | #ifdef RLIMIT_NPROC | 240 | #ifdef RLIMIT_NPROC |
212 | limit(RLIMIT_NPROC, limitp); | 241 | limit(RLIMIT_NPROC, limitp); |
213 | #else | 242 | #else |
214 | if (OPT_verbose) bb_error_msg("system does not support %s", | 243 | if (OPT_verbose) |
215 | "RLIMIT_NPROC"); | 244 | bb_error_msg("system does not support RLIMIT_%s", |
245 | "NPROC"); | ||
216 | #endif | 246 | #endif |
217 | } | 247 | } |
218 | if (limitf >= -1) { | 248 | if (limitf >= -1) { |
219 | #ifdef RLIMIT_FSIZE | 249 | #ifdef RLIMIT_FSIZE |
220 | limit(RLIMIT_FSIZE, limitf); | 250 | limit(RLIMIT_FSIZE, limitf); |
221 | #else | 251 | #else |
222 | if (OPT_verbose) bb_error_msg("system does not support %s", | 252 | if (OPT_verbose) |
223 | "RLIMIT_FSIZE"); | 253 | bb_error_msg("system does not support RLIMIT_%s", |
254 | "FSIZE"); | ||
224 | #endif | 255 | #endif |
225 | } | 256 | } |
226 | if (limitc >= -1) { | 257 | if (limitc >= -1) { |
227 | #ifdef RLIMIT_CORE | 258 | #ifdef RLIMIT_CORE |
228 | limit(RLIMIT_CORE, limitc); | 259 | limit(RLIMIT_CORE, limitc); |
229 | #else | 260 | #else |
230 | if (OPT_verbose) bb_error_msg("system does not support %s", | 261 | if (OPT_verbose) |
231 | "RLIMIT_CORE"); | 262 | bb_error_msg("system does not support RLIMIT_%s", |
263 | "CORE"); | ||
232 | #endif | 264 | #endif |
233 | } | 265 | } |
234 | if (limitr >= -1) { | 266 | if (limitr >= -1) { |
235 | #ifdef RLIMIT_RSS | 267 | #ifdef RLIMIT_RSS |
236 | limit(RLIMIT_RSS, limitr); | 268 | limit(RLIMIT_RSS, limitr); |
237 | #else | 269 | #else |
238 | if (OPT_verbose) bb_error_msg("system does not support %s", | 270 | if (OPT_verbose) |
239 | "RLIMIT_RSS"); | 271 | bb_error_msg("system does not support RLIMIT_%s", |
272 | "RSS"); | ||
240 | #endif | 273 | #endif |
241 | } | 274 | } |
242 | if (limitt >= -1) { | 275 | if (limitt >= -1) { |
243 | #ifdef RLIMIT_CPU | 276 | #ifdef RLIMIT_CPU |
244 | limit(RLIMIT_CPU, limitt); | 277 | limit(RLIMIT_CPU, limitt); |
245 | #else | 278 | #else |
246 | if (OPT_verbose) bb_error_msg("system does not support %s", | 279 | if (OPT_verbose) |
247 | "RLIMIT_CPU"); | 280 | bb_error_msg("system does not support RLIMIT_%s", |
281 | "CPU"); | ||
248 | #endif | 282 | #endif |
249 | } | 283 | } |
250 | } | 284 | } |
251 | 285 | ||
252 | /* argv[0] */ | 286 | /* argv[0] */ |
253 | static void setuidgid(int, char **); | 287 | static void setuidgid(int, char **) ATTRIBUTE_NORETURN; |
254 | static void envuidgid(int, char **); | 288 | static void envuidgid(int, char **) ATTRIBUTE_NORETURN; |
255 | static void envdir(int, char **); | 289 | static void envdir(int, char **) ATTRIBUTE_NORETURN; |
256 | static void softlimit(int, char **); | 290 | static void softlimit(int, char **) ATTRIBUTE_NORETURN; |
257 | 291 | ||
258 | int chpst_main(int argc, char **argv); | 292 | int chpst_main(int argc, char **argv); |
259 | int chpst_main(int argc, char **argv) | 293 | int chpst_main(int argc, char **argv) |
260 | { | 294 | { |
295 | INIT_G(); | ||
296 | |||
261 | if (applet_name[3] == 'd') envdir(argc, argv); | 297 | if (applet_name[3] == 'd') envdir(argc, argv); |
262 | if (applet_name[1] == 'o') softlimit(argc, argv); | 298 | if (applet_name[1] == 'o') softlimit(argc, argv); |
263 | if (applet_name[0] == 's') setuidgid(argc, argv); | 299 | if (applet_name[0] == 's') setuidgid(argc, argv); |