diff options
-rw-r--r-- | applets/applets.c | 272 | ||||
-rw-r--r-- | applets/busybox.c | 6 | ||||
-rw-r--r-- | scripts/config/confdata.c | 8 |
3 files changed, 137 insertions, 149 deletions
diff --git a/applets/applets.c b/applets/applets.c index 21b0c3dbc..bf6b16026 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -54,10 +54,6 @@ static struct BB_applet *applet_using; | |||
54 | const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1); | 54 | const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1); |
55 | 55 | ||
56 | 56 | ||
57 | #ifdef CONFIG_FEATURE_SUID | ||
58 | |||
59 | static void check_suid (struct BB_applet *app); | ||
60 | |||
61 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 57 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
62 | 58 | ||
63 | #include <sys/stat.h> | 59 | #include <sys/stat.h> |
@@ -65,8 +61,6 @@ static void check_suid (struct BB_applet *app); | |||
65 | #include "pwd_.h" | 61 | #include "pwd_.h" |
66 | #include "grp_.h" | 62 | #include "grp_.h" |
67 | 63 | ||
68 | static void parse_config_file (void); | ||
69 | |||
70 | #define CONFIG_FILE "/etc/busybox.conf" | 64 | #define CONFIG_FILE "/etc/busybox.conf" |
71 | 65 | ||
72 | /* applets [] is const, so we have to define this "override" structure */ | 66 | /* applets [] is const, so we have to define this "override" structure */ |
@@ -79,77 +73,12 @@ struct BB_suid_config | |||
79 | mode_t m_mode; | 73 | mode_t m_mode; |
80 | 74 | ||
81 | struct BB_suid_config *m_next; | 75 | struct BB_suid_config *m_next; |
82 | }; | 76 | } static *suid_config; |
83 | 77 | ||
84 | static struct BB_suid_config *suid_config; | ||
85 | static int suid_cfg_readable; | 78 | static int suid_cfg_readable; |
86 | 79 | ||
87 | #endif /* CONFIG_FEATURE_SUID_CONFIG */ | ||
88 | |||
89 | #endif /* CONFIG_FEATURE_SUID */ | ||
90 | |||
91 | |||
92 | |||
93 | extern void bb_show_usage (void) | ||
94 | { | ||
95 | const char *format_string; | ||
96 | const char *usage_string = usage_messages; | ||
97 | int i; | ||
98 | |||
99 | for (i = applet_using - applets; i > 0;) { | ||
100 | if (!*usage_string++) { | ||
101 | --i; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | format_string = "%s\n\nUsage: %s %s\n\n"; | ||
106 | if (*usage_string == '\b') | ||
107 | format_string = "%s\n\nNo help available.\n\n"; | ||
108 | fprintf (stderr, format_string, bb_msg_full_version, applet_using->name, | ||
109 | usage_string); | ||
110 | |||
111 | exit (EXIT_FAILURE); | ||
112 | } | ||
113 | |||
114 | static int applet_name_compare (const void *x, const void *y) | ||
115 | { | ||
116 | const char *name = x; | ||
117 | const struct BB_applet *applet = y; | ||
118 | |||
119 | return strcmp (name, applet->name); | ||
120 | } | ||
121 | |||
122 | extern const size_t NUM_APPLETS; | ||
123 | |||
124 | struct BB_applet *find_applet_by_name (const char *name) | ||
125 | { | ||
126 | return bsearch (name, applets, NUM_APPLETS, sizeof (struct BB_applet), | ||
127 | applet_name_compare); | ||
128 | } | ||
129 | |||
130 | void run_applet_by_name (const char *name, int argc, char **argv) | ||
131 | { | ||
132 | if(ENABLE_FEATURE_SUID_CONFIG) parse_config_file (); | ||
133 | |||
134 | if(!strncmp(name, "busybox", 7)) busybox_main(argc, argv); | ||
135 | /* Do a binary search to find the applet entry given the name. */ | ||
136 | applet_using = find_applet_by_name(name); | ||
137 | if(applet_using) { | ||
138 | bb_applet_name = applet_using->name; | ||
139 | if(argc==2 && !strcmp(argv[1], "--help")) bb_show_usage (); | ||
140 | if(ENABLE_FEATURE_SUID) check_suid (applet_using); | ||
141 | exit ((*(applet_using->main)) (argc, argv)); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
146 | #ifdef CONFIG_FEATURE_SUID | ||
147 | |||
148 | #ifdef CONFIG_FEATURE_SUID_CONFIG | ||
149 | |||
150 | /* check if u is member of group g */ | 80 | /* check if u is member of group g */ |
151 | static int | 81 | static int ingroup (uid_t u, gid_t g) |
152 | ingroup (uid_t u, gid_t g) | ||
153 | { | 82 | { |
154 | struct group *grp = getgrgid (g); | 83 | struct group *grp = getgrgid (g); |
155 | 84 | ||
@@ -166,76 +95,6 @@ ingroup (uid_t u, gid_t g) | |||
166 | return 0; | 95 | return 0; |
167 | } | 96 | } |
168 | 97 | ||
169 | #endif | ||
170 | |||
171 | |||
172 | void | ||
173 | check_suid (struct BB_applet *applet) | ||
174 | { | ||
175 | uid_t ruid = getuid (); /* real [ug]id */ | ||
176 | uid_t rgid = getgid (); | ||
177 | |||
178 | #ifdef CONFIG_FEATURE_SUID_CONFIG | ||
179 | if (suid_cfg_readable) { | ||
180 | struct BB_suid_config *sct; | ||
181 | |||
182 | for (sct = suid_config; sct; sct = sct->m_next) { | ||
183 | if (sct->m_applet == applet) | ||
184 | break; | ||
185 | } | ||
186 | if (sct) { | ||
187 | mode_t m = sct->m_mode; | ||
188 | |||
189 | if (sct->m_uid == ruid) /* same uid */ | ||
190 | m >>= 6; | ||
191 | else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */ | ||
192 | m >>= 3; | ||
193 | |||
194 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | ||
195 | bb_error_msg_and_die ("You have no permission to run this applet!"); | ||
196 | |||
197 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { /* *both* have to be set for sgid */ | ||
198 | if (setegid (sct->m_gid)) | ||
199 | bb_error_msg_and_die | ||
200 | ("BusyBox binary has insufficient rights to set proper GID for applet!"); | ||
201 | } else | ||
202 | setgid (rgid); /* no sgid -> drop */ | ||
203 | |||
204 | if (sct->m_mode & S_ISUID) { | ||
205 | if (seteuid (sct->m_uid)) | ||
206 | bb_error_msg_and_die | ||
207 | ("BusyBox binary has insufficient rights to set proper UID for applet!"); | ||
208 | } else | ||
209 | setuid (ruid); /* no suid -> drop */ | ||
210 | } else { | ||
211 | /* default: drop all priviledges */ | ||
212 | setgid (rgid); | ||
213 | setuid (ruid); | ||
214 | } | ||
215 | return; | ||
216 | } else { | ||
217 | #ifndef CONFIG_FEATURE_SUID_CONFIG_QUIET | ||
218 | static int onetime = 0; | ||
219 | |||
220 | if (!onetime) { | ||
221 | onetime = 1; | ||
222 | fprintf (stderr, "Using fallback suid method\n"); | ||
223 | } | ||
224 | #endif | ||
225 | } | ||
226 | #endif | ||
227 | |||
228 | if (applet->need_suid == _BB_SUID_ALWAYS) { | ||
229 | if (geteuid () != 0) | ||
230 | bb_error_msg_and_die ("This applet requires root priviledges!"); | ||
231 | } else if (applet->need_suid == _BB_SUID_NEVER) { | ||
232 | setgid (rgid); /* drop all priviledges */ | ||
233 | setuid (ruid); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | #ifdef CONFIG_FEATURE_SUID_CONFIG | ||
238 | |||
239 | /* This should probably be a libbb routine. In that case, | 98 | /* This should probably be a libbb routine. In that case, |
240 | * I'd probably rename it to something like bb_trimmed_slice. | 99 | * I'd probably rename it to something like bb_trimmed_slice. |
241 | */ | 100 | */ |
@@ -470,10 +329,135 @@ static void parse_config_file(void) | |||
470 | return; | 329 | return; |
471 | } | 330 | } |
472 | 331 | ||
473 | #endif | 332 | #else |
333 | #define parse_config_file(x) | ||
334 | #endif /* CONFIG_FEATURE_SUID_CONFIG */ | ||
335 | |||
336 | #ifdef CONFIG_FEATURE_SUID | ||
337 | static void check_suid (struct BB_applet *applet) | ||
338 | { | ||
339 | uid_t ruid = getuid (); /* real [ug]id */ | ||
340 | uid_t rgid = getgid (); | ||
341 | |||
342 | #ifdef CONFIG_FEATURE_SUID_CONFIG | ||
343 | if (suid_cfg_readable) { | ||
344 | struct BB_suid_config *sct; | ||
345 | |||
346 | for (sct = suid_config; sct; sct = sct->m_next) { | ||
347 | if (sct->m_applet == applet) | ||
348 | break; | ||
349 | } | ||
350 | if (sct) { | ||
351 | mode_t m = sct->m_mode; | ||
352 | |||
353 | if (sct->m_uid == ruid) /* same uid */ | ||
354 | m >>= 6; | ||
355 | else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */ | ||
356 | m >>= 3; | ||
357 | |||
358 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | ||
359 | bb_error_msg_and_die ("You have no permission to run this applet!"); | ||
474 | 360 | ||
361 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { /* *both* have to be set for sgid */ | ||
362 | if (setegid (sct->m_gid)) | ||
363 | bb_error_msg_and_die | ||
364 | ("BusyBox binary has insufficient rights to set proper GID for applet!"); | ||
365 | } else | ||
366 | setgid (rgid); /* no sgid -> drop */ | ||
367 | |||
368 | if (sct->m_mode & S_ISUID) { | ||
369 | if (seteuid (sct->m_uid)) | ||
370 | bb_error_msg_and_die | ||
371 | ("BusyBox binary has insufficient rights to set proper UID for applet!"); | ||
372 | } else | ||
373 | setuid (ruid); /* no suid -> drop */ | ||
374 | } else { | ||
375 | /* default: drop all priviledges */ | ||
376 | setgid (rgid); | ||
377 | setuid (ruid); | ||
378 | } | ||
379 | return; | ||
380 | } else { | ||
381 | #ifndef CONFIG_FEATURE_SUID_CONFIG_QUIET | ||
382 | static int onetime = 0; | ||
383 | |||
384 | if (!onetime) { | ||
385 | onetime = 1; | ||
386 | fprintf (stderr, "Using fallback suid method\n"); | ||
387 | } | ||
388 | #endif | ||
389 | } | ||
475 | #endif | 390 | #endif |
476 | 391 | ||
392 | if (applet->need_suid == _BB_SUID_ALWAYS) { | ||
393 | if (geteuid () != 0) | ||
394 | bb_error_msg_and_die ("This applet requires root priviledges!"); | ||
395 | } else if (applet->need_suid == _BB_SUID_NEVER) { | ||
396 | setgid (rgid); /* drop all priviledges */ | ||
397 | setuid (ruid); | ||
398 | } | ||
399 | } | ||
400 | #else | ||
401 | #define check_suid(x) | ||
402 | #endif /* CONFIG_FEATURE_SUID */ | ||
403 | |||
404 | |||
405 | |||
406 | |||
407 | |||
408 | extern void bb_show_usage (void) | ||
409 | { | ||
410 | const char *format_string; | ||
411 | const char *usage_string = usage_messages; | ||
412 | int i; | ||
413 | |||
414 | for (i = applet_using - applets; i > 0;) { | ||
415 | if (!*usage_string++) { | ||
416 | --i; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | format_string = "%s\n\nUsage: %s %s\n\n"; | ||
421 | if (*usage_string == '\b') | ||
422 | format_string = "%s\n\nNo help available.\n\n"; | ||
423 | fprintf (stderr, format_string, bb_msg_full_version, applet_using->name, | ||
424 | usage_string); | ||
425 | |||
426 | exit (EXIT_FAILURE); | ||
427 | } | ||
428 | |||
429 | static int applet_name_compare (const void *x, const void *y) | ||
430 | { | ||
431 | const char *name = x; | ||
432 | const struct BB_applet *applet = y; | ||
433 | |||
434 | return strcmp (name, applet->name); | ||
435 | } | ||
436 | |||
437 | extern const size_t NUM_APPLETS; | ||
438 | |||
439 | struct BB_applet *find_applet_by_name (const char *name) | ||
440 | { | ||
441 | return bsearch (name, applets, NUM_APPLETS, sizeof (struct BB_applet), | ||
442 | applet_name_compare); | ||
443 | } | ||
444 | |||
445 | void run_applet_by_name (const char *name, int argc, char **argv) | ||
446 | { | ||
447 | if(ENABLE_FEATURE_SUID_CONFIG) parse_config_file (); | ||
448 | |||
449 | if(!strncmp(name, "busybox", 7)) busybox_main(argc, argv); | ||
450 | /* Do a binary search to find the applet entry given the name. */ | ||
451 | applet_using = find_applet_by_name(name); | ||
452 | if(applet_using) { | ||
453 | bb_applet_name = applet_using->name; | ||
454 | if(argc==2 && !strcmp(argv[1], "--help")) bb_show_usage (); | ||
455 | if(ENABLE_FEATURE_SUID) check_suid (applet_using); | ||
456 | exit ((*(applet_using->main)) (argc, argv)); | ||
457 | } | ||
458 | } | ||
459 | |||
460 | |||
477 | /* END CODE */ | 461 | /* END CODE */ |
478 | /* | 462 | /* |
479 | Local Variables: | 463 | Local Variables: |
diff --git a/applets/busybox.c b/applets/busybox.c index 420c9c0e5..a49565008 100644 --- a/applets/busybox.c +++ b/applets/busybox.c | |||
@@ -5,8 +5,10 @@ | |||
5 | #include <errno.h> | 5 | #include <errno.h> |
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include "busybox.h" | 7 | #include "busybox.h" |
8 | #ifdef CONFIG_LOCALE_SUPPORT | 8 | #if ENABLE_LOCALE_SUPPORT |
9 | #include <locale.h> | 9 | #include <locale.h> |
10 | #else | ||
11 | #define setlocale(x,y) | ||
10 | #endif | 12 | #endif |
11 | 13 | ||
12 | const char *bb_applet_name; | 14 | const char *bb_applet_name; |
@@ -54,6 +56,8 @@ static void install_links(const char *busybox, int use_symbolic_links) | |||
54 | } | 56 | } |
55 | } | 57 | } |
56 | 58 | ||
59 | #else | ||
60 | #define install_links(x,y) | ||
57 | #endif /* CONFIG_FEATURE_INSTALLER */ | 61 | #endif /* CONFIG_FEATURE_INSTALLER */ |
58 | 62 | ||
59 | int main(int argc, char **argv) | 63 | int main(int argc, char **argv) |
diff --git a/scripts/config/confdata.c b/scripts/config/confdata.c index 0a1f085ae..1d1b61e2b 100644 --- a/scripts/config/confdata.c +++ b/scripts/config/confdata.c | |||
@@ -322,8 +322,8 @@ int conf_write(const char *name) | |||
322 | while (menu) { | 322 | while (menu) { |
323 | sym = menu->sym; | 323 | sym = menu->sym; |
324 | if (!sym) { | 324 | if (!sym) { |
325 | if (!menu_is_visible(menu)) | 325 | //if (!menu_is_visible(menu)) |
326 | goto next; | 326 | // goto next; |
327 | str = menu_get_prompt(menu); | 327 | str = menu_get_prompt(menu); |
328 | fprintf(out, "\n" | 328 | fprintf(out, "\n" |
329 | "#\n" | 329 | "#\n" |
@@ -336,8 +336,8 @@ int conf_write(const char *name) | |||
336 | " */\n", str); | 336 | " */\n", str); |
337 | } else if (!(sym->flags & SYMBOL_CHOICE)) { | 337 | } else if (!(sym->flags & SYMBOL_CHOICE)) { |
338 | sym_calc_value(sym); | 338 | sym_calc_value(sym); |
339 | if (!(sym->flags & SYMBOL_WRITE)) | 339 | //if (!(sym->flags & SYMBOL_WRITE)) |
340 | goto next; | 340 | // goto next; |
341 | sym->flags &= ~SYMBOL_WRITE; | 341 | sym->flags &= ~SYMBOL_WRITE; |
342 | type = sym->type; | 342 | type = sym->type; |
343 | if (type == S_TRISTATE) { | 343 | if (type == S_TRISTATE) { |