aboutsummaryrefslogtreecommitdiff
path: root/libbb/vfork_daemon_rexec.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-13 14:45:51 +0100
committerRon Yorston <rmy@pobox.com>2015-10-13 14:45:51 +0100
commit8e509f11bceeec419abc718300bef7422d1fee4c (patch)
treefdfbc752ad94102e3613a5d7254f14a93eaf7f56 /libbb/vfork_daemon_rexec.c
parent420f5edfe7676fe6e7cddbbf15c04649d096e422 (diff)
parent4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 (diff)
downloadbusybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.gz
busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.bz2
busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb/vfork_daemon_rexec.c')
-rw-r--r--libbb/vfork_daemon_rexec.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index de4d14fce..2d3204507 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -71,28 +71,44 @@ pid_t FAST_FUNC xspawn(char **argv)
71} 71}
72 72
73#if ENABLE_FEATURE_PREFER_APPLETS 73#if ENABLE_FEATURE_PREFER_APPLETS
74static jmp_buf die_jmp;
75static void jump(void)
76{
77 /* Special case. We arrive here if NOFORK applet
78 * calls xfunc, which then decides to die.
79 * We don't die, but jump instead back to caller.
80 * NOFORK applets still cannot carelessly call xfuncs:
81 * p = xmalloc(10);
82 * q = xmalloc(10); // BUG! if this dies, we leak p!
83 */
84 /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0).
85 * This works because exitcodes are bytes,
86 * run_nofork_applet() ensures that by "& 0xff" */
87 longjmp(die_jmp, xfunc_error_retval | 0x100);
88}
89
74struct nofork_save_area { 90struct nofork_save_area {
75 jmp_buf die_jmp; 91 jmp_buf die_jmp;
92 void (*die_func)(void);
76 const char *applet_name; 93 const char *applet_name;
77 uint32_t option_mask32; 94 uint32_t option_mask32;
78 int die_sleep;
79 uint8_t xfunc_error_retval; 95 uint8_t xfunc_error_retval;
80}; 96};
81static void save_nofork_data(struct nofork_save_area *save) 97static void save_nofork_data(struct nofork_save_area *save)
82{ 98{
83 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); 99 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
100 save->die_func = die_func;
84 save->applet_name = applet_name; 101 save->applet_name = applet_name;
85 save->xfunc_error_retval = xfunc_error_retval;
86 save->option_mask32 = option_mask32; 102 save->option_mask32 = option_mask32;
87 save->die_sleep = die_sleep; 103 save->xfunc_error_retval = xfunc_error_retval;
88} 104}
89static void restore_nofork_data(struct nofork_save_area *save) 105static void restore_nofork_data(struct nofork_save_area *save)
90{ 106{
91 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); 107 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
108 die_func = save->die_func;
92 applet_name = save->applet_name; 109 applet_name = save->applet_name;
93 xfunc_error_retval = save->xfunc_error_retval;
94 option_mask32 = save->option_mask32; 110 option_mask32 = save->option_mask32;
95 die_sleep = save->die_sleep; 111 xfunc_error_retval = save->xfunc_error_retval;
96} 112}
97 113
98int FAST_FUNC run_nofork_applet(int applet_no, char **argv) 114int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
@@ -135,11 +151,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
135 while (argv[argc]) 151 while (argv[argc])
136 argc++; 152 argc++;
137 153
138 /* Special flag for xfunc_die(). If xfunc will "die" 154 /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */
139 * in NOFORK applet, xfunc_die() sees negative 155 die_func = jump;
140 * die_sleep and longjmp here instead. */
141 die_sleep = -1;
142
143 rc = setjmp(die_jmp); 156 rc = setjmp(die_jmp);
144 if (!rc) { 157 if (!rc) {
145 /* Some callers (xargs) 158 /* Some callers (xargs)
@@ -148,10 +161,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
148 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 161 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
149 /* Finally we can call NOFORK applet's main() */ 162 /* Finally we can call NOFORK applet's main() */
150 rc = applet_main[applet_no](argc, tmp_argv); 163 rc = applet_main[applet_no](argc, tmp_argv);
151 } else { /* xfunc died in NOFORK applet */ 164 } else {
152 /* in case they meant to return 0... */ 165 /* xfunc died in NOFORK applet */
153 if (rc == -2222)
154 rc = 0;
155 } 166 }
156 167
157 /* Restoring some globals */ 168 /* Restoring some globals */