aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 16:40:34 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 16:40:34 +0000
commitcc90f44402106dd6fb5d3f669958d9681e2b212f (patch)
treebdde24966d6e112fabe8201ce98c5e50ea2b29f6
parent08daf564ae4519ebb8f563a9e5bee4bd608a6c05 (diff)
downloadbusybox-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.c52
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
218static void *xxmalloc(int lineno, size_t size) 219static 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
250static 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
255static 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
262typedef 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 */
258static const struct { 271static 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
746static 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
733static char **add_string_to_strings(char **strings, char *add) 756static 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
764static 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
741static void putenv_all(char **strings) 774static 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
2456typedef 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;