TetherController - fix missing calls to posix_*_destroy() on error paths
This fixes a couple cases were errors can result in a missing calls to:
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fa);
which potentially results in a memory leak.
It's hard to accomplish this with helper functions, because if init fails,
you shouldn't call destroy, but if adddup2/setflags fails you need to...
Test: atest clatd_test libbpf_android_test libnetdbpf_test netd_integration_test netd_unit_test netdutils_test resolv_integration_test resolv_unit_test
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: If6e5d778e16e2ab69cd5f7d75824f320e1b0888c
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 0c5b6bf..9d56b3e 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -36,6 +36,7 @@
#include <vector>
#define LOG_TAG "TetherController"
+#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
@@ -116,22 +117,6 @@
return !strcmp(BP_TOOLS_MODE, bootmode);
}
-int setPosixSpawnFileActionsAddDup2(posix_spawn_file_actions_t* fa, int fd, int new_fd) {
- int res = posix_spawn_file_actions_init(fa);
- if (res) {
- return res;
- }
- return posix_spawn_file_actions_adddup2(fa, fd, new_fd);
-}
-
-int setPosixSpawnAttrFlags(posix_spawnattr_t* attr, short flags) {
- int res = posix_spawnattr_init(attr);
- if (res) {
- return res;
- }
- return posix_spawnattr_setflags(attr, flags);
-}
-
} // namespace
auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
@@ -267,23 +252,33 @@
// dup2 creates fd without CLOEXEC, dnsmasq will receive commands through the
// duplicated fd.
posix_spawn_file_actions_t fa;
- int res = setPosixSpawnFileActionsAddDup2(&fa, pipeRead.get(), STDIN_FILENO);
+ int res = posix_spawn_file_actions_init(&fa);
if (res) {
- ALOGE("posix_spawn set fa failed (%s)", strerror(res));
+ ALOGE("posix_spawn_file_actions_init failed (%s)", strerror(res));
+ return -res;
+ }
+ const android::base::ScopeGuard faGuard = [&] { posix_spawn_file_actions_destroy(&fa); };
+ res = posix_spawn_file_actions_adddup2(&fa, pipeRead.get(), STDIN_FILENO);
+ if (res) {
+ ALOGE("posix_spawn_file_actions_adddup2 failed (%s)", strerror(res));
return -res;
}
posix_spawnattr_t attr;
- res = setPosixSpawnAttrFlags(&attr, POSIX_SPAWN_USEVFORK);
+ res = posix_spawnattr_init(&attr);
if (res) {
- ALOGE("posix_spawn set attr flag failed (%s)", strerror(res));
+ ALOGE("posix_spawnattr_init failed (%s)", strerror(res));
+ return -res;
+ }
+ const android::base::ScopeGuard attrGuard = [&] { posix_spawnattr_destroy(&attr); };
+ res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK);
+ if (res) {
+ ALOGE("posix_spawnattr_setflags failed (%s)", strerror(res));
return -res;
}
pid_t pid;
res = posix_spawn(&pid, args[0], &fa, &attr, &args[0], nullptr);
- posix_spawnattr_destroy(&attr);
- posix_spawn_file_actions_destroy(&fa);
if (res) {
ALOGE("posix_spawn failed (%s)", strerror(res));
return -res;