From 9b3dabd8537787b1fa397f9dfacd95a58ba0f379 Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 1 Jun 2012 10:26:30 -0500 Subject: [PATCH] Fork open file descriptors * Add O_CLOEXEC to all open(...) calls * Add "e" to all fopen(...) calls * Prevents passing open file descriptors to child processes. Leaving psid's available to the child could cause unwanted i/o problems and possibly a security leak. --- configure.ac | 2 ++ m4/funcs.m4 | 22 ++++++++++++++++++++++ src/misc/configuration.cxx | 2 +- src/rigcontrol/ptt.cxx | 32 +++++++++++++++++++++++++++----- src/rigcontrol/rigMEM.cxx | 4 ++-- src/rigcontrol/serial.cxx | 8 +++++++- src/soundcard/mixer.cxx | 15 +++++++++++++-- src/soundcard/sound.cxx | 7 ++++++- 8 files changed, 80 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 2ed72ed5..c4b5df04 100644 --- a/configure.ac +++ b/configure.ac @@ -123,6 +123,8 @@ AC_FUNC_STRFTIME AC_FUNC_STRTOD AC_CHECK_FUNCS([getaddrinfo gethostbyname hstrerror gmtime_r localtime_r memmove memset mkdir select setenv snprintf socket socketpair strcasecmp strcasestr strchr strdup strerror strlcpy strncasecmp strrchr strstr strtol uname unsetenv vsnprintf]) +# Check for O_CLOEXEC +AC_FCNTL_FLAGS AC_PRESERVE_HELP_ORDER diff --git a/m4/funcs.m4 b/m4/funcs.m4 index c18c234f..13e13ecf 100644 --- a/m4/funcs.m4 +++ b/m4/funcs.m4 @@ -13,3 +13,25 @@ AC_DEFINE_UNQUOTED([HAVE_]FUNC_NAME_UC, $ac_cv_have_func_[]$1, [Define to 1 if w LIBS="$LIBS_search_libs_save" ]) + +# --------------------------------------------------------------------------- +# Macro: FCNTL_FLAGS +# --------------------------------------------------------------------------- + +AC_DEFUN([AC_FCNTL_FLAGS], +[ + AC_CACHE_CHECK([for O_CLOEXEC], [ac_cv_o_cloexec], [ + AC_LANG_PUSH([C]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -I${srcdir}" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [ int flags= O_CLOEXEC])], [ac_cv_o_cloexec="yes"], [ac_cv_o_cloexec="no"]) + AC_LANG_POP + ]) + + AS_IF([test "x$ac_cv_o_cloexec" = "xyes"],[ AC_DEFINE(HAVE_O_CLOEXEC, 1, [Define to 1 if you have O_CLOEXEC defined])]) +]) + +# --------------------------------------------------------------------------- +# End Macro: FCNTL_FLAGS +# --------------------------------------------------------------------------- diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index 55799178..fc7c3c62 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -886,7 +886,7 @@ static bool open_serial(const char* dev) { bool ret = false; #ifdef __CYGWIN__ - int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); + int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY | O_CLOEXEC); if (fd != -1) { close(fd); ret = true; diff --git a/src/rigcontrol/ptt.cxx b/src/rigcontrol/ptt.cxx index 1c5780cd..3b6b61d8 100644 --- a/src/rigcontrol/ptt.cxx +++ b/src/rigcontrol/ptt.cxx @@ -204,7 +204,12 @@ void PTT::open_tty(void) com_to_tty(pttdevName); # endif - if ((pttfd = open(pttdevName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { + int oflags = O_RDWR | O_NOCTTY | O_NDELAY; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + if ((pttfd = open(pttdevName.c_str(), oflags)) < 0) { LOG_ERROR("Could not open \"%s\": %s", pttdevName.c_str(), strerror(errno)); return; } @@ -295,8 +300,13 @@ void PTT::set_tty(bool ptt) void PTT::open_parport(void) { if (progdefaults.PTTdev.find("tty") != string::npos) return; - - if ((pttfd = open(progdefaults.PTTdev.c_str(), O_RDWR | O_NDELAY)) == -1) { + + int oflags = O_RDWR | O_NDELAY; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + if ((pttfd = open(progdefaults.PTTdev.c_str(), oflags)) == -1) { LOG_ERROR("Could not open %s: %s", progdefaults.PTTdev.c_str(), strerror(errno)); return; } @@ -417,7 +427,13 @@ static bool open_fifos(const char* base, int fd[2]) LOG_ERROR("%s is not a fifo", fifo.c_str()); return false; } - if ((fd[0] = open(fifo.c_str(), O_RDONLY | O_NONBLOCK)) == -1) { + + int oflags = O_RDONLY | O_NONBLOCK; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + if ((fd[0] = open(fifo.c_str(), oflags)) == -1) { LOG_ERROR("Could not open %s: %s", fifo.c_str(), strerror(errno)); return false; } @@ -428,7 +444,13 @@ static bool open_fifos(const char* base, int fd[2]) LOG_ERROR("%s is not a fifo", fifo.c_str()); return false; } - if ((fd[1] = open(fifo.c_str(), O_WRONLY | O_NONBLOCK)) == -1) { + oflags = O_WRONLY | O_NONBLOCK; + +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + if ((fd[1] = open(fifo.c_str(), oflags)) == -1) { LOG_ERROR("Could not open %s: %s", fifo.c_str(), strerror(errno)); return false; } diff --git a/src/rigcontrol/rigMEM.cxx b/src/rigcontrol/rigMEM.cxx index b2aa51b3..6c21d540 100644 --- a/src/rigcontrol/rigMEM.cxx +++ b/src/rigcontrol/rigMEM.cxx @@ -301,7 +301,7 @@ static void *rigMEM_loop(void *args) break; if (TogglePTT || rig_qsy || change_mode) { - IOout = fopen("c:/RIGCTL/ptt", "w"); + IOout = fopen("c:/RIGCTL/ptt", "we"); if (IOout) { LOG_VERBOSE("sent %d, %c, %s", (int)qsy_f, @@ -318,7 +318,7 @@ static void *rigMEM_loop(void *args) } } - IOin = fopen("c:/RIGCTL/rig", "r"); + IOin = fopen("c:/RIGCTL/rig", "re"); if (IOin) { fscanf(IOin, "%ld\n", &IOfreq); fscanf(IOin, "%s", szmode); diff --git a/src/rigcontrol/serial.cxx b/src/rigcontrol/serial.cxx index 761276f4..9cc01517 100644 --- a/src/rigcontrol/serial.cxx +++ b/src/rigcontrol/serial.cxx @@ -71,7 +71,13 @@ bool Cserial::OpenPort() { #ifdef __CYGWIN__ com_to_tty(device); #endif - if ((fd = open( device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY)) < 0) + + int oflags = O_RDWR | O_NOCTTY | O_NDELAY; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + if ((fd = open( device.c_str(), oflags)) < 0) return false; // save current port settings tcflush (fd, TCIFLUSH); diff --git a/src/soundcard/mixer.cxx b/src/soundcard/mixer.cxx index a8ea62de..fbdcff15 100644 --- a/src/soundcard/mixer.cxx +++ b/src/soundcard/mixer.cxx @@ -73,7 +73,13 @@ void MixerOSS::openMixer(const char *dev) if (mixer_fd != -1) closeMixer(); mixer = dev; try { - mixer_fd = open(mixer.c_str(), O_RDWR); + + int oflags = O_RDWR; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + mixer_fd = open(mixer.c_str(), oflags); if (mixer_fd == -1) throw MixerException(errno); if ((err = initMask()) != 0) @@ -144,7 +150,12 @@ void MixerOSS::findNumMixers() szDevice[10] = 0; else szDevice[10] = '0'+(i-1); - fd = open(szDevice, O_RDWR); + int oflags = O_RDWR; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + fd = open(szDevice, oflags); if (fd >= 0) { Devices[NumMixers] = i; NumMixers++; diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index ecdf5523..589affbb 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -399,7 +399,12 @@ int SoundOSS::Open(int md, int freq) mode = md; try { - device_fd = open(device.c_str(), mode, 0); + int oflags = md; +# ifdef HAVE_O_CLOEXEC + oflags = oflags | O_CLOEXEC; +# endif + + device_fd = open(device.c_str(), oflags, 0); if (device_fd == -1) throw SndException(errno); Format(AFMT_S16_LE); // default: 16 bit little endian