TetherController: Fix a memory and fd leak
Error paths (e.g. the one for setPosixSpawnAttrFlags/etc.) didn't
attempt to `free(args)`. Swapping to a vector neatly handles all of this
for us.
Caught by the static analyzer:
system/netd/server/TetherController.cpp:271:9: warning: Potential leak
of memory pointed to by 'args' [clang-analyzer-unix.Malloc]
Also caught by reviewers: we appear to leak a few FDs here in error
paths. This cleans those up, too.
Bug: None
Test: Ran the analyzer again. TreeHugger for functionality.
Change-Id: Ie53b3cdf4745aafa6f1e1284ccb7433ff345838e
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 4fc603a..bf1d177 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -36,8 +36,9 @@
#include <vector>
#define LOG_TAG "TetherController"
-#include <android-base/strings.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <log/log.h>
#include <netdutils/StatusOr.h>
@@ -55,7 +56,9 @@
namespace net {
using android::base::Join;
+using android::base::Pipe;
using android::base::StringPrintf;
+using android::base::unique_fd;
using android::netdutils::statusFromErrno;
using android::netdutils::StatusOr;
@@ -212,9 +215,8 @@
ALOGD("Starting tethering services");
- int pipefd[2];
-
- if (pipe2(pipefd, O_CLOEXEC) < 0) {
+ unique_fd pipeRead, pipeWrite;
+ if (!Pipe(&pipeRead, &pipeWrite, O_CLOEXEC)) {
int res = errno;
ALOGE("pipe2() failed (%s)", strerror(errno));
return -res;
@@ -251,7 +253,7 @@
dhcp_ranges[addrIndex + 1]));
}
- auto args = (char**)std::calloc(argVector.size() + 1, sizeof(char*));
+ std::vector<char*> args(argVector.size() + 1);
for (unsigned i = 0; i < argVector.size(); i++) {
args[i] = (char*)argVector[i].c_str();
}
@@ -266,7 +268,7 @@
// dup2 creates fd without CLOEXEC, dnsmasq will receive commands through the
// duplicated fd.
posix_spawn_file_actions_t fa;
- int res = setPosixSpawnFileActionsAddDup2(&fa, pipefd[0], STDIN_FILENO);
+ int res = setPosixSpawnFileActionsAddDup2(&fa, pipeRead.get(), STDIN_FILENO);
if (res) {
ALOGE("posix_spawn set fa failed (%s)", strerror(res));
return -res;
@@ -280,18 +282,15 @@
}
pid_t pid;
- res = posix_spawn(&pid, args[0], &fa, &attr, args, nullptr);
- close(pipefd[0]);
- free(args);
+ 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));
- close(pipefd[1]);
return -res;
}
mDaemonPid = pid;
- mDaemonFd = pipefd[1];
+ mDaemonFd = pipeWrite.release();
configureForTethering(true);
applyDnsInterfaces();
ALOGD("Tethering services running");