diff options
author | Dmitry Antipov <dmantipov@yandex.ru> | 2020-06-04 16:42:30 +0300 |
---|---|---|
committer | Amar Tumballi <amar@kadalu.io> | 2020-06-17 17:26:12 +0000 |
commit | 3db89cf23a5574e902b7785e65655dea65b98aae (patch) | |
tree | 2199a5a9cb629297a35d68af3815877be0e788a8 /rpc/rpc-lib/src | |
parent | 9c17cd3b9ca2e44b272b7061de6990dba1ca6937 (diff) | |
download | glusterfs-3db89cf23a5574e902b7785e65655dea65b98aae.tar.gz glusterfs-3db89cf23a5574e902b7785e65655dea65b98aae.tar.xz glusterfs-3db89cf23a5574e902b7785e65655dea65b98aae.zip |
rpc: fix undefined behaviour in __builtin_ctz
Found with GCC UBsan:
rpcsvc.c:102:36: runtime error: passing zero to ctz(), which is not a valid argument
#0 0x7fcd1ff6faa4 in rpcsvc_get_free_queue_index /path/to/glusterfs/rpc/rpc-lib/src/rpcsvc.c:102
#1 0x7fcd1ff81e12 in rpcsvc_handle_rpc_call /path/to/glusterfs/rpc/rpc-lib/src/rpcsvc.c:837
#2 0x7fcd1ff833ad in rpcsvc_notify /path/to/glusterfs/rpc/rpc-lib/src/rpcsvc.c:1000
#3 0x7fcd1ff8829d in rpc_transport_notify /path/to/glusterfs/rpc/rpc-lib/src/rpc-transport.c:520
#4 0x7fcd0dd72f16 in socket_event_poll_in_async /path/to/glusterfs/rpc/rpc-transport/socket/src/socket.c:2502
#5 0x7fcd0dd8986a in gf_async ../../../../libglusterfs/src/glusterfs/async.h:189
#6 0x7fcd0dd8986a in socket_event_poll_in /path/to/glusterfs/rpc/rpc-transport/socket/src/socket.c:2543
#7 0x7fcd0dd8986a in socket_event_handler /path/to/glusterfs/rpc/rpc-transport/socket/src/socket.c:2934
#8 0x7fcd0dd8986a in socket_event_handler /path/to/glusterfs/rpc/rpc-transport/socket/src/socket.c:2854
#9 0x7fcd2048aff7 in event_dispatch_epoll_handler /path/to/glusterfs/libglusterfs/src/event-epoll.c:640
#10 0x7fcd2048aff7 in event_dispatch_epoll_worker /path/to/glusterfs/libglusterfs/src/event-epoll.c:751
...
Fix, simplify, and prefer 'unsigned long' as underlying bitmap type.
Change-Id: If3f24dfe7bef8bc7a11a679366e219a73caeb9e4
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Fixes: #1283
Diffstat (limited to 'rpc/rpc-lib/src')
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 54 | ||||
-rw-r--r-- | rpc/rpc-lib/src/rpcsvc.h | 2 |
2 files changed, 15 insertions, 41 deletions
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index f7d911bf1c..eace6eaee3 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -66,59 +66,33 @@ rpcsvc_request_handler(void *arg); static int rpcsvc_match_subnet_v4(const char *addrtok, const char *ipaddr); -void +static void rpcsvc_toggle_queue_status(rpcsvc_program_t *prog, - rpcsvc_request_queue_t *queue, char status[]) + rpcsvc_request_queue_t *queue, + unsigned long status[]) { - int queue_index = 0, status_index = 0, set_bit = 0; - - if (queue != &prog->request_queue[0]) { - queue_index = (queue - &prog->request_queue[0]); - } - - status_index = queue_index / 8; - set_bit = queue_index % 8; + unsigned queue_index = queue - prog->request_queue; - status[status_index] ^= (1 << set_bit); - - return; + status[queue_index / __BITS_PER_LONG] ^= (1UL << (queue_index % + __BITS_PER_LONG)); } int rpcsvc_get_free_queue_index(rpcsvc_program_t *prog) { - int queue_index = 0, max_index = 0, i = 0; - unsigned int right_most_unset_bit = 0; + unsigned i, j = 0; - right_most_unset_bit = 8; - - max_index = gf_roof(EVENT_MAX_THREADS, 8) / 8; - for (i = 0; i < max_index; i++) { - if (prog->request_queue_status[i] == 0) { - right_most_unset_bit = 0; + for (i = 0; i < EVENT_MAX_THREADS / __BITS_PER_LONG; i++) + if (prog->request_queue_status[i] != ULONG_MAX) { + j = __builtin_ctzl(~prog->request_queue_status[i]); break; - } else { - /* get_rightmost_set_bit (sic)*/ - right_most_unset_bit = __builtin_ctz( - ~prog->request_queue_status[i]); - if (right_most_unset_bit < 8) { - break; - } } - } - - if (right_most_unset_bit > 7) { - queue_index = -1; - } else { - queue_index = i * 8; - queue_index += right_most_unset_bit; - } - if (queue_index != -1) { - prog->request_queue_status[i] |= (0x1 << right_most_unset_bit); - } + if (i == EVENT_MAX_THREADS / __BITS_PER_LONG) + return -1; - return queue_index; + prog->request_queue_status[i] |= (1UL << j); + return i * __BITS_PER_LONG + j; } rpcsvc_notify_wrapper_t * diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index a88fc841b6..c370b33057 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -457,7 +457,7 @@ struct rpcsvc_program { gf_boolean_t alive; gf_boolean_t synctask; - char request_queue_status[EVENT_MAX_THREADS / 8 + 1]; + unsigned long request_queue_status[EVENT_MAX_THREADS / __BITS_PER_LONG]; }; typedef struct rpcsvc_cbk_program { |