Module: xenomai-3 Branch: wip/drivers Commit: 59284782ac15e24a55f57581bdb4dccd4bc84a73 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=59284782ac15e24a55f57581bdb4dccd4bc84a73
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Sep 6 09:40:34 2016 +0200 drivers/ipc: fix potential race in select() Acquiring the poll state and binding the selector must be done atomically, so that such state does not change before xnselect_bind() decides whether the caller should wait. --- kernel/drivers/ipc/bufp.c | 7 +------ kernel/drivers/ipc/iddp.c | 7 +------ kernel/drivers/ipc/rtipc.c | 26 +++++++++++++------------- kernel/drivers/ipc/xddp.c | 7 +------ 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c index f129eaa..2e7f5ad 100644 --- a/kernel/drivers/ipc/bufp.c +++ b/kernel/drivers/ipc/bufp.c @@ -1043,15 +1043,12 @@ static int bufp_ioctl(struct rtdm_fd *fd, return ret; } -static unsigned int bufp_pollstate(struct rtdm_fd *fd) +static unsigned int bufp_pollstate(struct rtdm_fd *fd) /* atomic */ { struct rtipc_private *priv = rtdm_fd_to_private(fd); struct bufp_socket *sk = priv->state, *rsk; unsigned int mask = 0; struct rtdm_fd *rfd; - spl_t s; - - cobalt_atomic_enter(s); if (test_bit(_BUFP_BOUND, &sk->status) && sk->fillsz > 0) mask |= POLLIN; @@ -1072,8 +1069,6 @@ static unsigned int bufp_pollstate(struct rtdm_fd *fd) } else mask |= POLLOUT; - cobalt_atomic_leave(s); - return mask; } diff --git a/kernel/drivers/ipc/iddp.c b/kernel/drivers/ipc/iddp.c index 028e40a..6d3da57 100644 --- a/kernel/drivers/ipc/iddp.c +++ b/kernel/drivers/ipc/iddp.c @@ -935,15 +935,12 @@ static void iddp_exit(void) xnmap_delete(portmap); } -static unsigned int iddp_pollstate(struct rtdm_fd *fd) +static unsigned int iddp_pollstate(struct rtdm_fd *fd) /* atomic */ { struct rtipc_private *priv = rtdm_fd_to_private(fd); struct iddp_socket *sk = priv->state; unsigned int mask = 0; struct rtdm_fd *rfd; - spl_t s; - - cobalt_atomic_enter(s); if (test_bit(_IDDP_BOUND, &sk->status) && !list_empty(&sk->inq)) mask |= POLLIN; @@ -966,8 +963,6 @@ static unsigned int iddp_pollstate(struct rtdm_fd *fd) } else mask |= POLLOUT; - cobalt_atomic_leave(s); - return mask; } diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c index 77fc7dd..7bd4950 100644 --- a/kernel/drivers/ipc/rtipc.c +++ b/kernel/drivers/ipc/rtipc.c @@ -481,28 +481,28 @@ static int rtipc_select(struct rtdm_fd *fd, struct xnselector *selector, spl_t s; int ret; + if (type != XNSELECT_READ && type != XNSELECT_WRITE) + return -EINVAL; + + binding = xnmalloc(sizeof(*binding)); + if (binding == NULL) + return -ENOMEM; + + cobalt_atomic_enter(s); + pollstate = priv->proto->proto_ops.pollstate(fd); - switch (type) { - case XNSELECT_READ: + if (type == XNSELECT_READ) { mask = pollstate & POLLIN; block = &priv->recv_block; - break; - case XNSELECT_WRITE: + } else { mask = pollstate & POLLOUT; block = &priv->send_block; - break; - default: - return -EINVAL; } - binding = xnmalloc(sizeof(*binding)); - if (binding == NULL) - return -ENOMEM; - - xnlock_get_irqsave(&nklock, s); ret = xnselect_bind(block, binding, selector, type, index, mask); - xnlock_put_irqrestore(&nklock, s); + + cobalt_atomic_leave(s); if (ret) xnfree(binding); diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c index c91aa02..c48b935 100644 --- a/kernel/drivers/ipc/xddp.c +++ b/kernel/drivers/ipc/xddp.c @@ -1081,15 +1081,12 @@ static int xddp_ioctl(struct rtdm_fd *fd, return ret; } -static unsigned int xddp_pollstate(struct rtdm_fd *fd) +static unsigned int xddp_pollstate(struct rtdm_fd *fd) /* atomic */ { struct rtipc_private *priv = rtdm_fd_to_private(fd); struct xddp_socket *sk = priv->state, *rsk; unsigned int mask = 0, pollstate; struct rtdm_fd *rfd; - spl_t s; - - cobalt_atomic_enter(s); pollstate = __xnpipe_pollstate(sk->minor); if (test_bit(_XDDP_BOUND, &sk->status)) @@ -1110,8 +1107,6 @@ static unsigned int xddp_pollstate(struct rtdm_fd *fd) } else mask |= POLLOUT; - cobalt_atomic_leave(s); - return mask; } _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git