From e8877f78a9f167c16989929ea629f1ea0ea8a121 Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Mon, 14 May 2018 12:45:47 +0200 Subject: [PATCH] Problem: zmq_poller_[add/modify] accept invalid events arguments silently Solution: check and return an error on invalid arguments. Fixes #3088 --- src/zmq.cpp | 21 ++++++++++++++---- tests/test_poller.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/zmq.cpp b/src/zmq.cpp index 9a0135b9..4fd9b891 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -1197,6 +1197,15 @@ static int check_poller (void *const poller_) return 0; } +static int check_events (const short events_) +{ + if (events_ & ~(ZMQ_POLLIN | ZMQ_POLLOUT | ZMQ_POLLERR | ZMQ_POLLPRI)) { + errno = EINVAL; + return -1; + } + return 0; +} + static int check_poller_registration_args (void *const poller_, void *const s_) { if (-1 == check_poller (poller_)) @@ -1231,7 +1240,8 @@ static int check_poller_fd_registration_args (void *const poller_, int zmq_poller_add (void *poller_, void *s_, void *user_data_, short events_) { - if (-1 == check_poller_registration_args (poller_, s_)) + if (-1 == check_poller_registration_args (poller_, s_) + || -1 == check_events (events_)) return -1; zmq::socket_base_t *socket = (zmq::socket_base_t *) s_; @@ -1249,7 +1259,8 @@ int zmq_poller_add_fd (void *poller_, int zmq_poller_add_fd (void *poller_, int fd_, void *user_data_, short events_) #endif { - if (-1 == check_poller_fd_registration_args (poller_, fd_)) + if (-1 == check_poller_fd_registration_args (poller_, fd_) + || -1 == check_events (events_)) return -1; return ((zmq::socket_poller_t *) poller_) @@ -1259,7 +1270,8 @@ int zmq_poller_add_fd (void *poller_, int fd_, void *user_data_, short events_) int zmq_poller_modify (void *poller_, void *s_, short events_) { - if (-1 == check_poller_registration_args (poller_, s_)) + if (-1 == check_poller_registration_args (poller_, s_) + || -1 == check_events (events_)) return -1; zmq::socket_base_t *socket = (zmq::socket_base_t *) s_; @@ -1274,7 +1286,8 @@ int zmq_poller_modify_fd (void *poller_, SOCKET fd_, short events_) int zmq_poller_modify_fd (void *poller_, int fd_, short events_) #endif { - if (-1 == check_poller_fd_registration_args (poller_, fd_)) + if (-1 == check_poller_fd_registration_args (poller_, fd_) + || -1 == check_events (events_)) return -1; return ((zmq::socket_poller_t *) poller_)->modify_fd (fd_, events_); diff --git a/tests/test_poller.cpp b/tests/test_poller.cpp index a1fe989b..c0381deb 100644 --- a/tests/test_poller.cpp +++ b/tests/test_poller.cpp @@ -31,6 +31,7 @@ #include "testutil_unity.hpp" #include +#include void setUp () { @@ -393,6 +394,42 @@ void call_poller_modify_fd_unregistered_fails (void *poller, TEST_ASSERT_SUCCESS_ERRNO (close (plain_socket)); } +void call_poller_add_invalid_events_fails (void *poller, void *zeromq_socket) +{ + TEST_ASSERT_FAILURE_ERRNO ( + EINVAL, zmq_poller_add (poller, zeromq_socket, NULL, SHRT_MAX)); +} + +void call_poller_modify_invalid_events_fails (void *poller, void *zeromq_socket) +{ + TEST_ASSERT_SUCCESS_ERRNO (zmq_poller_add (poller, zeromq_socket, NULL, 0)); + + TEST_ASSERT_FAILURE_ERRNO ( + EINVAL, zmq_poller_modify (poller, zeromq_socket, SHRT_MAX)); +} + +void call_poller_add_fd_invalid_events_fails (void *poller, + void * /*zeromq_socket*/) +{ + fd_t plain_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + TEST_ASSERT_FAILURE_ERRNO ( + EINVAL, zmq_poller_add_fd (poller, plain_socket, NULL, SHRT_MAX)); + + TEST_ASSERT_SUCCESS_ERRNO (close (plain_socket)); +} + +void call_poller_modify_fd_invalid_events_fails (void *poller, + void * /*zeromq_socket*/) +{ + fd_t plain_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_poller_add_fd (poller, plain_socket, NULL, 0)); + TEST_ASSERT_FAILURE_ERRNO ( + EINVAL, zmq_poller_modify_fd (poller, plain_socket, SHRT_MAX)); + + TEST_ASSERT_SUCCESS_ERRNO (close (plain_socket)); +} + TEST_CASE_FUNC_PARAM (call_poller_add_twice_fails, test_with_empty_poller) TEST_CASE_FUNC_PARAM (call_poller_remove_unregistered_fails, test_with_empty_poller) @@ -406,6 +443,15 @@ TEST_CASE_FUNC_PARAM (call_poller_remove_fd_unregistered_fails, TEST_CASE_FUNC_PARAM (call_poller_modify_fd_unregistered_fails, test_with_empty_poller) +TEST_CASE_FUNC_PARAM (call_poller_add_invalid_events_fails, + test_with_empty_poller) +TEST_CASE_FUNC_PARAM (call_poller_modify_invalid_events_fails, + test_with_empty_poller) +TEST_CASE_FUNC_PARAM (call_poller_add_fd_invalid_events_fails, + test_with_empty_poller) +TEST_CASE_FUNC_PARAM (call_poller_modify_fd_invalid_events_fails, + test_with_empty_poller) + void call_poller_wait_empty_with_timeout_fails (void *poller, void * /*socket*/) { zmq_poller_event_t event; @@ -618,6 +664,10 @@ int main (void) RUN_TEST (test_call_poller_add_fd_twice_fails); RUN_TEST (test_call_poller_remove_fd_unregistered_fails); RUN_TEST (test_call_poller_modify_fd_unregistered_fails); + RUN_TEST (test_call_poller_add_invalid_events_fails); + RUN_TEST (test_call_poller_modify_invalid_events_fails); + RUN_TEST (test_call_poller_add_fd_invalid_events_fails); + RUN_TEST (test_call_poller_modify_fd_invalid_events_fails); RUN_TEST (test_call_poller_wait_empty_with_timeout_fails); RUN_TEST (test_call_poller_wait_empty_without_timeout_fails);