From 62a669d9f04e83debe729347617a935707badc7e Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 1 Oct 2011 14:14:27 +0100 Subject: Mark simple file and socket descriptors as uninheritable. This patch creates two utility functions: int open_cloexec(pathname, flags) int create_cloexec(pathname, flags, mode) These return a file descriptor with the CLOEXEC flag set, to ensure that the descriptor is not inherited across a fork/exec operation. The sockets returned by: _x_io_tcp_connect_ipv4() _x_io_tcp_connect() now also have their CLOEXEC flag set. --- src/xine-utils/utils.c | 39 +++++++++++++++++++++++++++++++++++++++ src/xine-utils/xine_check.c | 6 +++--- src/xine-utils/xineutils.h | 12 ++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) (limited to 'src/xine-utils') diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c index 2f62c95a8..f5d5a0ff3 100644 --- a/src/xine-utils/utils.c +++ b/src/xine-utils/utils.c @@ -38,6 +38,7 @@ #include #include #include +#include #if HAVE_EXECINFO_H #include @@ -56,6 +57,10 @@ #include #endif +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + typedef struct { char *language; /* name of the locale */ char *encoding; /* typical encoding */ @@ -697,3 +702,37 @@ char *xine_strcat_realloc (char **dest, char *append) strcat (*dest = newstr, append); return newstr; } + + +static int set_close_on_execute(int fd) +{ +#ifndef WIN32 + return fcntl(fd, F_SETFD, FD_CLOEXEC); +#else + return SetHandleInformation((HANDLE)_get_osfhandle(fd), HANDLE_FLAG_INHERIT, 0); +#endif +} + + +int open_cloexec(const char *name, int flags) +{ + int fd = open(name, (flags | O_CLOEXEC)); + + if (fd >= 0) { + set_close_on_execute(fd); + } + + return fd; +} + +int create_cloexec(const char *name, int flags, mode_t mode) +{ + int fd = open(name, (flags | O_CREAT | O_CLOEXEC), mode); + + if (fd >= 0) { + set_close_on_execute(fd); + } + + return fd; +} + diff --git a/src/xine-utils/xine_check.c b/src/xine-utils/xine_check.c index ad94b0382..90100d725 100644 --- a/src/xine-utils/xine_check.c +++ b/src/xine-utils/xine_check.c @@ -168,7 +168,7 @@ static xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) { return hc; } - if ( (fd = open(hc->cdrom_dev, O_RDWR)) < 0) { + if ( (fd = open(hc->cdrom_dev, O_RDWR | O_CLOEXEC)) < 0) { switch (errno) { case EACCES: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->cdrom_dev); @@ -204,7 +204,7 @@ static xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) { return hc; } - if ( (fd = open(hc->dvd_dev, O_RDWR)) < 0) { + if ( (fd = open(hc->dvd_dev, O_RDWR | O_CLOEXEC)) < 0) { switch (errno) { case EACCES: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->dvd_dev); @@ -247,7 +247,7 @@ static xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) { return hc; } - fd = open (hc->dvd_dev, O_RDONLY | O_NONBLOCK); + fd = open (hc->dvd_dev, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (fd < 0) { set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not open %s.\n", hc->dvd_dev); return hc; diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index 0fd0bbf0e..5fe1fb7e5 100644 --- a/src/xine-utils/xineutils.h +++ b/src/xine-utils/xineutils.h @@ -215,6 +215,18 @@ void xine_strdupa(char *dest, char *src) XINE_PROTECTED XINE_DEPRECATED; */ char *xine_strcat_realloc (char **dest, char *append) XINE_PROTECTED; +/** + * opens a file, ensuring that the descriptor will be closed + * automatically after a fork/execute. + */ +int open_cloexec(const char *name, int flags) XINE_PROTECTED; + +/** + * creates a file, ensuring that the descriptor will be closed + * automatically after a fork/execute. + */ +int create_cloexec(const char *name, int flags, mode_t mode) XINE_PROTECTED; + /* * Color Conversion Utility Functions * The following data structures and functions facilitate the conversion -- cgit v1.2.3 From b01bd8b294c35be664b018dd6e5fa9ec30e521ca Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 3 Oct 2011 01:13:10 +0100 Subject: Assign O_CLOEXEC a safe default value if it hasn't been defined already. --- src/xine-utils/xine_check.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/xine-utils') diff --git a/src/xine-utils/xine_check.c b/src/xine-utils/xine_check.c index 90100d725..5bc936da8 100644 --- a/src/xine-utils/xine_check.c +++ b/src/xine-utils/xine_check.c @@ -46,6 +46,10 @@ #include "xineutils.h" +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + #if defined(__linux__) #include -- cgit v1.2.3 From 5db268a002e7a102855e84a3ff5e1c27ca7cb927 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 3 Oct 2011 12:11:56 +0100 Subject: Prefix open_cloexec() and create_cloexec() with xine_, and add new xine_socket_cloexec() function. --- src/xine-utils/utils.c | 21 +++++++++++++++++++-- src/xine-utils/xineutils.h | 10 ++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/xine-utils') diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c index f5d5a0ff3..25e8cc2b0 100644 --- a/src/xine-utils/utils.c +++ b/src/xine-utils/utils.c @@ -35,7 +35,9 @@ #include #include +#include #include +#include #include #include #include @@ -714,7 +716,7 @@ static int set_close_on_execute(int fd) } -int open_cloexec(const char *name, int flags) +int xine_open_cloexec(const char *name, int flags) { int fd = open(name, (flags | O_CLOEXEC)); @@ -725,7 +727,7 @@ int open_cloexec(const char *name, int flags) return fd; } -int create_cloexec(const char *name, int flags, mode_t mode) +int xine_create_cloexec(const char *name, int flags, mode_t mode) { int fd = open(name, (flags | O_CREAT | O_CLOEXEC), mode); @@ -736,3 +738,18 @@ int create_cloexec(const char *name, int flags, mode_t mode) return fd; } +int xine_socket_cloexec(int domain, int type, int protocol) +{ + int s = socket(domain, type, protocol); + + if (s >= 0) { +#ifndef WIN32 + fcntl(s, F_SETFD, FD_CLOEXEC); +#else + SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0); +#endif + } + + return s; +} + diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index 5fe1fb7e5..d0946e471 100644 --- a/src/xine-utils/xineutils.h +++ b/src/xine-utils/xineutils.h @@ -219,13 +219,19 @@ char *xine_strcat_realloc (char **dest, char *append) XINE_PROTECTED; * opens a file, ensuring that the descriptor will be closed * automatically after a fork/execute. */ -int open_cloexec(const char *name, int flags) XINE_PROTECTED; +int xine_open_cloexec(const char *name, int flags) XINE_PROTECTED; /** * creates a file, ensuring that the descriptor will be closed * automatically after a fork/execute. */ -int create_cloexec(const char *name, int flags, mode_t mode) XINE_PROTECTED; +int xine_create_cloexec(const char *name, int flags, mode_t mode) XINE_PROTECTED; + +/** + * creates a socket, ensuring that the descriptor will be closed + * automatically after a fork/execute. + */ +int xine_socket_cloexec(int domain, int type, int protocol) XINE_PROTECTED; /* * Color Conversion Utility Functions -- cgit v1.2.3 From fa660f82ae5889b931c645133abb151f26fba343 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 3 Oct 2011 21:07:39 +0100 Subject: Set CLOEXEC flag on three more sockets. There are two functions that actually set this flag: int _x_set_file_close_on_exec() int _x_set_socket_close_on_exec() (We need two functions because file descriptors and sockets are not the same under WIN32 - of course). These function have been assigned "internal" visibility so that they can be used throughout libxine.so itself while still not being exported to the global symbol table. In other words, they're both as close to being "static" as I can make them. --- src/xine-utils/attributes.h | 9 +++++++++ src/xine-utils/utils.c | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src/xine-utils') diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h index 2326dab18..9f02d9b7b 100644 --- a/src/xine-utils/attributes.h +++ b/src/xine-utils/attributes.h @@ -66,6 +66,15 @@ # define XINE_PROTECTED #endif +/* Export hidden only for private/internal libxine functions */ +#if defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_INTERNAL) +# define XINE_INTERNAL __attribute__((__visibility__("internal"))) +#elif defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT) +# define XINE_INTERNAL __attribute__((__visibility__("default"))) +#else +# define XINE_INTERNAL +#endif + #ifdef SUPPORT_ATTRIBUTE_SENTINEL # define XINE_SENTINEL __attribute__((__sentinel__)) #else diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c index 25e8cc2b0..70c600b96 100644 --- a/src/xine-utils/utils.c +++ b/src/xine-utils/utils.c @@ -706,7 +706,7 @@ char *xine_strcat_realloc (char **dest, char *append) } -static int set_close_on_execute(int fd) +int _x_set_file_close_on_exec(int fd) { #ifndef WIN32 return fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -715,13 +715,22 @@ static int set_close_on_execute(int fd) #endif } +int _x_set_socket_close_on_exec(int s) +{ +#ifndef WIN32 + return fcntl(s, F_SETFD, FD_CLOEXEC); +#else + return SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0); +#endif +} + int xine_open_cloexec(const char *name, int flags) { int fd = open(name, (flags | O_CLOEXEC)); if (fd >= 0) { - set_close_on_execute(fd); + _x_set_file_close_on_exec(fd); } return fd; @@ -732,7 +741,7 @@ int xine_create_cloexec(const char *name, int flags, mode_t mode) int fd = open(name, (flags | O_CREAT | O_CLOEXEC), mode); if (fd >= 0) { - set_close_on_execute(fd); + _x_set_file_close_on_exec(fd); } return fd; @@ -743,11 +752,7 @@ int xine_socket_cloexec(int domain, int type, int protocol) int s = socket(domain, type, protocol); if (s >= 0) { -#ifndef WIN32 - fcntl(s, F_SETFD, FD_CLOEXEC); -#else - SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0); -#endif + _x_set_socket_close_on_exec(s); } return s; -- cgit v1.2.3