[posix] close files on exec (#3977)

This commit adds the *_CLOEXEC flags when opening files. This ensures
files are closed when spawning new processes.

* use LOG_DAEMON as syslog facility
* remove setenv() when forkpty
This commit is contained in:
Yakun Xu
2019-07-12 09:40:06 -07:00
committed by Jonathan Hui
parent cac09b7a70
commit ae014b3f6d
11 changed files with 77 additions and 72 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ otError utilsFlashInit(void)
create = true;
}
sFlashFd = open(fileName, O_RDWR | O_CREAT, 0600);
sFlashFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
lseek(sFlashFd, 0, SEEK_SET);
otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
+14 -37
View File
@@ -320,7 +320,7 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
int fd = -1;
int rval = 0;
fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK);
fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
if (fd == -1)
{
perror("open uart failed");
@@ -480,8 +480,9 @@ exit:
#if OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
int HdlcInterface::ForkPty(const char *aCommand, const char *aArguments)
{
int fd = -1;
int pid = -1;
int fd = -1;
int pid = -1;
int rval = -1;
{
struct termios tios;
@@ -490,54 +491,30 @@ int HdlcInterface::ForkPty(const char *aCommand, const char *aArguments)
cfmakeraw(&tios);
tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
pid = forkpty(&fd, NULL, &tios, NULL);
VerifyOrExit(pid >= 0);
VerifyOrExit((pid = forkpty(&fd, NULL, &tios, NULL)) != -1, perror("forkpty()"));
}
if (0 == pid)
{
const int kMaxCommand = 255;
char cmd[kMaxCommand];
int rval;
struct rlimit limit;
rval = getrlimit(RLIMIT_NOFILE, &limit);
rval = setenv("SHELL", SOCKET_UTILS_DEFAULT_SHELL, 0);
VerifyOrExit(rval == 0, perror("setenv failed"));
// Close all file descriptors larger than STDERR_FILENO.
for (rlim_t i = (STDERR_FILENO + 1); i < limit.rlim_cur; i++)
{
close(static_cast<int>(i));
}
const int kMaxCommand = 255;
char cmd[kMaxCommand];
rval = snprintf(cmd, sizeof(cmd), "exec %s %s", aCommand, aArguments);
VerifyOrExit(rval > 0 && static_cast<size_t>(rval) < sizeof(cmd),
otLogCritPlat("NCP file and configuration is too long!"));
fprintf(stderr, "NCP file and configuration is too long!");
rval = -1);
execl(getenv("SHELL"), getenv("SHELL"), "-c", cmd, NULL);
perror("open pty failed");
exit(OT_EXIT_INVALID_ARGUMENTS);
VerifyOrExit((rval = execl(SOCKET_UTILS_DEFAULT_SHELL, SOCKET_UTILS_DEFAULT_SHELL, "-c", cmd, NULL)) != -1,
perror("execl(OT_RCP)"));
}
else
{
int rval = fcntl(fd, F_GETFL);
if (rval != -1)
{
rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK);
}
if (rval == -1)
{
perror("set nonblock failed");
close(fd);
fd = -1;
}
VerifyOrExit((rval = fcntl(fd, F_GETFL)) != -1, perror("fcntl(F_GETFL)"));
VerifyOrExit((rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK | O_CLOEXEC)) != -1, perror("fcntl(F_SETFL)"));
}
exit:
VerifyOrDie(rval == 0, OT_EXIT_FAILURE);
return fd;
}
#endif // OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
+1 -1
View File
@@ -46,7 +46,7 @@ void platformLoggingInit(const char *aName)
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
(OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
openlog(aName, LOG_PID, LOG_USER);
openlog(aName, LOG_PID, LOG_DAEMON);
setlogmask(setlogmask(0) & LOG_UPTO(LOG_DEBUG));
#else
+27
View File
@@ -30,11 +30,14 @@
#include "platform-posix.h"
#include <assert.h>
#include <fcntl.h>
#include <setjmp.h>
#include <sys/socket.h>
#include <unistd.h>
#include <openthread/platform/misc.h>
#include "code_utils.h"
#include "openthread-system.h"
#include "common/logging.hpp"
@@ -123,3 +126,27 @@ void VerifyOrDie(bool aCondition, int aExitCode)
exit(aExitCode);
}
}
int SocketWithCloseExec(int aDomain, int aType, int aProtocol)
{
int rval = 0;
int fd = -1;
#ifdef __APPLE__
otEXPECT_ACTION((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
otEXPECT_ACTION((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)"));
otEXPECT_ACTION((rval = fcntl(fd, F_SETFD, rval | FD_CLOEXEC)) != -1, perror("fcntl(F_SETFD)"));
#else
otEXPECT_ACTION((fd = socket(aDomain, aType | SOCK_CLOEXEC, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
#endif
exit:
if (rval == -1 && fd != -1)
{
VerifyOrDie(close(fd) == 0, OT_EXIT_FAILURE);
fd = -1;
}
return fd;
}
+3 -3
View File
@@ -386,8 +386,8 @@ void platformNetifInit(otInstance *aInstance)
{
struct ifreq ifr;
sIpFd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
VerifyOrExit(sIpFd > 0);
sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
VerifyOrExit(sIpFd >= 0);
sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
VerifyOrExit(sNetlinkFd > 0);
@@ -403,7 +403,7 @@ void platformNetifInit(otInstance *aInstance)
VerifyOrExit(bind(sNetlinkFd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == 0);
}
sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR);
sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC);
VerifyOrExit(sTunFd > 0, otLogCritPlat("Unable to open tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
memset(&ifr, 0, sizeof(ifr));
+14
View File
@@ -399,6 +399,20 @@ void VerifyOrDie(bool aCondition, int aExitCode);
*/
void SuccessOrDie(otError aError);
/**
* This function creates a socket with SOCK_CLOEXEC flag set.
*
* @param[in] aDomain The communication domain.
* @param[in] aType The semantics of communication.
* @param[in] aProtocol The protocol to use.
*
* @returns The file descriptor of the created socket.
*
* @retval -1 Failed to create socket.
*
*/
int SocketWithCloseExec(int aDomain, int aType, int aProtocol);
#ifdef __cplusplus
}
#endif
+2 -2
View File
@@ -77,7 +77,7 @@ static int swapOpen(void)
int fd;
getSettingsFileName(fileName, true);
fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC, 0600);
fd = open(fileName, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
VerifyOrDie(fd != -1);
return fd;
@@ -152,7 +152,7 @@ void otPlatSettingsInit(otInstance *aInstance)
char fileName[kMaxFileNameSize];
getSettingsFileName(fileName, false);
sSettingsFd = open(fileName, O_RDWR | O_CREAT, 0600);
sSettingsFd = open(fileName, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
}
VerifyOrDie(sSettingsFd != -1);
+1 -1
View File
@@ -84,7 +84,7 @@ void otSimInit(void)
sockaddr.sin_port = htons(kBasePort + sPortOffset + sNodeId);
sockaddr.sin_addr.s_addr = INADDR_ANY;
sSockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sSockFd = SocketWithCloseExec(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sSockFd == -1)
{
+6 -19
View File
@@ -60,17 +60,6 @@ static bool sEnabled = false;
static const uint8_t *sWriteBuffer = NULL;
static uint16_t sWriteLength = 0;
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
static void set_flag_cloexec(int a_fd)
{
int ret = fcntl(a_fd, F_GETFD, 0);
VerifyOrDie(ret != -1, OT_EXIT_FAILURE);
ret |= FD_CLOEXEC;
ret = fcntl(a_fd, F_SETFD, ret);
VerifyOrDie(ret != -1, OT_EXIT_FAILURE);
}
#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
otError otPlatUartEnable(void)
{
otError error = OT_ERROR_NONE;
@@ -78,17 +67,14 @@ otError otPlatUartEnable(void)
struct sockaddr_un sockname;
int ret;
sUartSocket = socket(AF_UNIX, SOCK_STREAM, 0);
sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0);
if (sUartSocket == -1)
{
perror("socket");
exit(OT_EXIT_FAILURE);
}
set_flag_cloexec(sUartSocket);
sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY, 0600);
sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600);
if (sUartLock == -1)
{
@@ -96,8 +82,6 @@ otError otPlatUartEnable(void)
exit(OT_EXIT_FAILURE);
}
set_flag_cloexec(sUartLock);
if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1)
{
perror("flock");
@@ -290,7 +274,10 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co
}
else if (rval <= 0)
{
perror("UART read");
if (rval != 0)
{
perror("read(UART)");
}
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
close(sSessionSocket);
sSessionSocket = -1;
+2 -2
View File
@@ -217,8 +217,8 @@ otError otPlatUdpSocket(otUdpSocket *aUdpSocket)
assert(aUdpSocket->mHandle == NULL);
fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
VerifyOrExit(fd > 0, error = OT_ERROR_FAILED);
fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
VerifyOrExit(fd >= 0, error = OT_ERROR_FAILED);
aUdpSocket->mHandle = FdToHandle(fd);
+6 -6
View File
@@ -1138,7 +1138,7 @@ static bool setup_spi_dev(const char *path)
int ret;
sSpiDevPath = path;
fd = open(path, O_RDWR);
fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0)
{
perror("open");
@@ -1212,7 +1212,7 @@ static bool setup_res_gpio(const char *path)
goto bail;
}
setup_fd = open(dir_path, O_WRONLY);
setup_fd = open(dir_path, O_WRONLY | O_CLOEXEC);
if (setup_fd >= 0)
{
@@ -1223,7 +1223,7 @@ static bool setup_res_gpio(const char *path)
}
}
sResGpioValueFd = open(value_path, O_WRONLY);
sResGpioValueFd = open(value_path, O_WRONLY | O_CLOEXEC);
bail:
@@ -1308,7 +1308,7 @@ static bool setup_int_gpio(const char *path)
goto bail;
}
setup_fd = open(dir_path, O_WRONLY);
setup_fd = open(dir_path, O_WRONLY | O_CLOEXEC);
if (setup_fd >= 0)
{
@@ -1322,7 +1322,7 @@ static bool setup_int_gpio(const char *path)
close(setup_fd);
}
setup_fd = open(edge_path, O_WRONLY);
setup_fd = open(edge_path, O_WRONLY | O_CLOEXEC);
if (setup_fd >= 0)
{
@@ -1339,7 +1339,7 @@ static bool setup_int_gpio(const char *path)
setup_fd = -1;
}
sIntGpioValueFd = open(value_path, O_RDONLY);
sIntGpioValueFd = open(value_path, O_RDONLY | O_CLOEXEC);
bail: