diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 16:40:34 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-08 16:40:34 +0000 |
commit | cc90f44402106dd6fb5d3f669958d9681e2b212f (patch) | |
tree | bdde24966d6e112fabe8201ce98c5e50ea2b29f6 | |
parent | 08daf564ae4519ebb8f563a9e5bee4bd608a6c05 (diff) | |
download | busybox-w32-cc90f44402106dd6fb5d3f669958d9681e2b212f.tar.gz busybox-w32-cc90f44402106dd6fb5d3f669958d9681e2b212f.tar.bz2 busybox-w32-cc90f44402106dd6fb5d3f669958d9681e2b212f.zip |
hush: plug leak in run_pipe(). NOMMU only.
-rw-r--r-- | shell/hush.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index 6075f514a..4641dca11 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -214,6 +214,7 @@ static void debug_print_strings(const char *prefix, char **vv) | |||
214 | /* | 214 | /* |
215 | * Leak hunting. Use hush_leaktool.sh for post-processing. | 215 | * Leak hunting. Use hush_leaktool.sh for post-processing. |
216 | */ | 216 | */ |
217 | //#define FOR_HUSH_LEAKTOOL | ||
217 | #ifdef FOR_HUSH_LEAKTOOL | 218 | #ifdef FOR_HUSH_LEAKTOOL |
218 | static void *xxmalloc(int lineno, size_t size) | 219 | static void *xxmalloc(int lineno, size_t size) |
219 | { | 220 | { |
@@ -247,12 +248,24 @@ static void xxfree(void *ptr) | |||
247 | 248 | ||
248 | #define ERR_PTR ((void*)(long)1) | 249 | #define ERR_PTR ((void*)(long)1) |
249 | 250 | ||
250 | static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER; | ||
251 | |||
252 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" | 251 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" |
253 | 252 | ||
254 | #define SPECIAL_VAR_SYMBOL 3 | 253 | #define SPECIAL_VAR_SYMBOL 3 |
255 | 254 | ||
255 | static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER; | ||
256 | |||
257 | /* This supports saving pointers malloced in vfork child, | ||
258 | * to be freed in the parent. One pointer is saved in | ||
259 | * G.argv_from_re_execing global var instead. TODO: unify. | ||
260 | */ | ||
261 | #if !BB_MMU | ||
262 | typedef struct nommu_save_t { | ||
263 | char **new_env; | ||
264 | char **old_env; | ||
265 | char **argv; | ||
266 | } nommu_save_t; | ||
267 | #endif | ||
268 | |||
256 | /* The descrip member of this structure is only used to make | 269 | /* The descrip member of this structure is only used to make |
257 | * debugging output pretty */ | 270 | * debugging output pretty */ |
258 | static const struct { | 271 | static const struct { |
@@ -729,6 +742,16 @@ static char **add_strings_to_strings(char **strings, char **add, int need_to_dup | |||
729 | v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]); | 742 | v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]); |
730 | return v; | 743 | return v; |
731 | } | 744 | } |
745 | #ifdef FOR_HUSH_LEAKTOOL | ||
746 | static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup) | ||
747 | { | ||
748 | char **ptr = add_strings_to_strings(strings, add, need_to_dup); | ||
749 | fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr); | ||
750 | return ptr; | ||
751 | } | ||
752 | #define add_strings_to_strings(strings, add, need_to_dup) \ | ||
753 | xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup) | ||
754 | #endif | ||
732 | 755 | ||
733 | static char **add_string_to_strings(char **strings, char *add) | 756 | static char **add_string_to_strings(char **strings, char *add) |
734 | { | 757 | { |
@@ -737,6 +760,16 @@ static char **add_string_to_strings(char **strings, char *add) | |||
737 | v[1] = NULL; | 760 | v[1] = NULL; |
738 | return add_strings_to_strings(strings, v, /*dup:*/ 0); | 761 | return add_strings_to_strings(strings, v, /*dup:*/ 0); |
739 | } | 762 | } |
763 | #ifdef FOR_HUSH_LEAKTOOL | ||
764 | static char **xx_add_string_to_strings(int lineno, char **strings, char *add) | ||
765 | { | ||
766 | char **ptr = add_string_to_strings(strings, add); | ||
767 | fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr); | ||
768 | return ptr; | ||
769 | } | ||
770 | #define add_string_to_strings(strings, add) \ | ||
771 | xx_add_string_to_strings(__LINE__, strings, add) | ||
772 | #endif | ||
740 | 773 | ||
741 | static void putenv_all(char **strings) | 774 | static void putenv_all(char **strings) |
742 | { | 775 | { |
@@ -2452,13 +2485,7 @@ static void free_pipe_list(struct pipe *head, int indent) | |||
2452 | } | 2485 | } |
2453 | 2486 | ||
2454 | 2487 | ||
2455 | #if !BB_MMU | 2488 | #if BB_MMU |
2456 | typedef struct nommu_save_t { | ||
2457 | char **new_env; | ||
2458 | char **old_env; | ||
2459 | char **argv; | ||
2460 | } nommu_save_t; | ||
2461 | #else | ||
2462 | #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ | 2489 | #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ |
2463 | pseudo_exec_argv(argv, assignment_cnt, argv_expanded) | 2490 | pseudo_exec_argv(argv, assignment_cnt, argv_expanded) |
2464 | #define pseudo_exec(nommu_save, command, argv_expanded) \ | 2491 | #define pseudo_exec(nommu_save, command, argv_expanded) \ |
@@ -2974,7 +3001,9 @@ static int run_pipe(struct pipe *pi) | |||
2974 | restore_redirects(squirrel); | 3001 | restore_redirects(squirrel); |
2975 | free_strings_and_unsetenv(new_env, 1); | 3002 | free_strings_and_unsetenv(new_env, 1); |
2976 | putenv_all(old_env); | 3003 | putenv_all(old_env); |
2977 | free(old_env); /* not free_strings()! */ | 3004 | /* Free the pointers, but the strings themselves |
3005 | * are in environ now, don't use free_strings! */ | ||
3006 | free(old_env); | ||
2978 | clean_up_and_ret1: | 3007 | clean_up_and_ret1: |
2979 | free(argv_expanded); | 3008 | free(argv_expanded); |
2980 | IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) | 3009 | IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) |
@@ -3072,6 +3101,9 @@ static int run_pipe(struct pipe *pi) | |||
3072 | free(nommu_save.argv); | 3101 | free(nommu_save.argv); |
3073 | free_strings_and_unsetenv(nommu_save.new_env, 1); | 3102 | free_strings_and_unsetenv(nommu_save.new_env, 1); |
3074 | putenv_all(nommu_save.old_env); | 3103 | putenv_all(nommu_save.old_env); |
3104 | /* Free the pointers, but the strings themselves | ||
3105 | * are in environ now, don't use free_strings! */ | ||
3106 | free(nommu_save.old_env); | ||
3075 | #endif | 3107 | #endif |
3076 | free(argv_expanded); | 3108 | free(argv_expanded); |
3077 | argv_expanded = NULL; | 3109 | argv_expanded = NULL; |