From 56f4fc195fcda682cf34cab70a6c613d381e99ae Mon Sep 17 00:00:00 2001 From: Maksym Planeta Date: Wed, 2 Mar 2016 19:11:25 +0100 Subject: [PATCH] Set FD_CLOEXEC for ipmi driver device file. If a privileged process, which uses this library, spawns a non-privileged child, the child can inherit open file descriptor to ipmi driver. This may become a significant both safety and security vulnerability, if access to ipmi device file is not intended (For details see [1]). Another possibility for Linux is to use O_CLOEXEC flag, which is considered to be thread safe. But F_CLOEXEC is more portable. 1. https://cwe.mitre.org/data/definitions/403.html --- libfreeipmi/driver/ipmi-inteldcmi-driver.c | 14 ++++++++++++++ libfreeipmi/driver/ipmi-openipmi-driver.c | 14 ++++++++++++++ libfreeipmi/driver/ipmi-ssif-driver.c | 15 +++++++++++++++ libfreeipmi/driver/ipmi-sunbmc-driver.c | 14 ++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/libfreeipmi/driver/ipmi-inteldcmi-driver.c b/libfreeipmi/driver/ipmi-inteldcmi-driver.c index 22bf079..9f2f5cc 100644 --- a/libfreeipmi/driver/ipmi-inteldcmi-driver.c +++ b/libfreeipmi/driver/ipmi-inteldcmi-driver.c @@ -423,6 +423,7 @@ int ipmi_inteldcmi_ctx_io_init (ipmi_inteldcmi_ctx_t ctx) { char *driver_device; + int flags; if (!ctx || ctx->magic != IPMI_INTELDCMI_CTX_MAGIC) { @@ -444,6 +445,19 @@ ipmi_inteldcmi_ctx_io_init (ipmi_inteldcmi_ctx_t ctx) goto cleanup; } + flags = fcntl(ctx->device_fd, F_GETFD); + if (flags < 0) + { + INTELDCMI_ERRNO_TO_INTELDCMI_ERRNUM (ctx, errno); + goto cleanup; + } + flags |= FD_CLOEXEC; + if (fcntl(ctx->device_fd, F_SETFD, flags) < 0) + { + INTELDCMI_ERRNO_TO_INTELDCMI_ERRNUM (ctx, errno); + goto cleanup; + } + ctx->io_init = 1; out: ctx->errnum = IPMI_INTELDCMI_ERR_SUCCESS; diff --git a/libfreeipmi/driver/ipmi-openipmi-driver.c b/libfreeipmi/driver/ipmi-openipmi-driver.c index bc8f578..1bde870 100644 --- a/libfreeipmi/driver/ipmi-openipmi-driver.c +++ b/libfreeipmi/driver/ipmi-openipmi-driver.c @@ -352,6 +352,7 @@ ipmi_openipmi_ctx_io_init (ipmi_openipmi_ctx_t ctx) { unsigned int addr = IPMI_SLAVE_ADDRESS_BMC; char *driver_device; + int flags; if (!ctx || ctx->magic != IPMI_OPENIPMI_CTX_MAGIC) { @@ -374,6 +375,19 @@ ipmi_openipmi_ctx_io_init (ipmi_openipmi_ctx_t ctx) goto cleanup; } + flags = fcntl(ctx->device_fd, F_GETFD); + if (flags < 0) + { + OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); + goto cleanup; + } + flags |= FD_CLOEXEC; + if (fcntl(ctx->device_fd, F_SETFD, flags) < 0) + { + OPENIPMI_ERRNO_TO_OPENIPMI_ERRNUM (ctx, errno); + goto cleanup; + } + if (ioctl (ctx->device_fd, IPMICTL_SET_MY_ADDRESS_CMD, &addr) < 0) diff --git a/libfreeipmi/driver/ipmi-ssif-driver.c b/libfreeipmi/driver/ipmi-ssif-driver.c index 61c1dd2..2678460 100644 --- a/libfreeipmi/driver/ipmi-ssif-driver.c +++ b/libfreeipmi/driver/ipmi-ssif-driver.c @@ -679,6 +679,8 @@ ipmi_ssif_ctx_set_flags (ipmi_ssif_ctx_t ctx, unsigned int flags) int ipmi_ssif_ctx_io_init (ipmi_ssif_ctx_t ctx) { + int flags; + if (!ctx || ctx->magic != IPMI_SSIF_CTX_MAGIC) { ERR_TRACE (ipmi_ssif_ctx_errormsg (ctx), ipmi_ssif_ctx_errnum (ctx)); @@ -701,6 +703,19 @@ ipmi_ssif_ctx_io_init (ipmi_ssif_ctx_t ctx) goto cleanup; } + flags = fcntl(ctx->device_fd, F_GETFD); + if (flags < 0) + { + SSIF_SET_ERRNUM (ctx, errno); + goto cleanup; + } + flags |= FD_CLOEXEC; + if (fcntl(ctx->device_fd, F_SETFD, flags) < 0) + { + SSIF_SET_ERRNUM (ctx, errno); + goto cleanup; + } + if (ioctl (ctx->device_fd, IPMI_I2C_SLAVE, ctx->driver_address) < 0) diff --git a/libfreeipmi/driver/ipmi-sunbmc-driver.c b/libfreeipmi/driver/ipmi-sunbmc-driver.c index c18efc6..92bd0e1 100644 --- a/libfreeipmi/driver/ipmi-sunbmc-driver.c +++ b/libfreeipmi/driver/ipmi-sunbmc-driver.c @@ -303,6 +303,7 @@ ipmi_sunbmc_ctx_io_init (ipmi_sunbmc_ctx_t ctx) uint8_t method; #endif /* !(defined(HAVE_SYS_STROPTS_H) && defined(IOCTL_IPMI_INTERFACE_METHOD)) */ char *driver_device; + int flags; if (!ctx || ctx->magic != IPMI_SUNBMC_CTX_MAGIC) { @@ -325,6 +326,19 @@ ipmi_sunbmc_ctx_io_init (ipmi_sunbmc_ctx_t ctx) goto cleanup; } + flags = fcntl(ctx->device_fd, F_GETFD); + if (flags < 0) + { + SUNBMC_ERRNO_TO_SUNBMC_ERRNUM (ctx, errno); + goto cleanup; + } + flags |= FD_CLOEXEC; + if (fcntl(ctx->device_fd, F_SETFD, flags) < 0) + { + SUNBMC_ERRNO_TO_SUNBMC_ERRNUM (ctx, errno); + goto cleanup; + } + #if defined(HAVE_SYS_STROPTS_H) #ifdef IOCTL_IPMI_INTERFACE_METHOD -- 2.7.0