core: donate the fdset to do_reexecute() to avoid a double free
do_reexecute() freed the FDSet on the switch-root/soft-reboot fallback
but the caller's copy stayed live, so main() freed it again if every
fallback exec then failed. Donate the fdset instead: pass it with
TAKE_PTR() and take ownership via a _cleanup_ local, freeing it exactly
once on every exit path.
Follow-up for 3c7878f94b
This commit is contained in:
+5
-2
@@ -2123,7 +2123,7 @@ static int do_reexecute(
|
||||
char* argv[],
|
||||
const struct rlimit *saved_rlimit_nofile,
|
||||
const struct rlimit *saved_rlimit_memlock,
|
||||
FDSet *fds,
|
||||
FDSet *_fds, /* donated */
|
||||
const char *switch_root_dir,
|
||||
const char *switch_root_init,
|
||||
uint64_t saved_capability_ambient_set,
|
||||
@@ -2139,6 +2139,9 @@ static int do_reexecute(
|
||||
assert(saved_rlimit_memlock);
|
||||
assert(ret_error_message);
|
||||
|
||||
/* The fdset is donated to us, take ownership so it is freed on all exit paths. */
|
||||
_cleanup_fdset_free_ FDSet *fds = TAKE_PTR(_fds);
|
||||
|
||||
/* Close and disarm the watchdog, so that the new instance can reinitialize it, but the machine
|
||||
* doesn't get rebooted while we do that. */
|
||||
watchdog_close(/* disarm= */ true);
|
||||
@@ -3848,7 +3851,7 @@ finish:
|
||||
argc, argv,
|
||||
&saved_rlimit_nofile,
|
||||
&saved_rlimit_memlock,
|
||||
fds,
|
||||
TAKE_PTR(fds),
|
||||
switch_root_dir,
|
||||
switch_root_init,
|
||||
saved_ambient_set,
|
||||
|
||||
Reference in New Issue
Block a user