From be04e7661c80c30d5f06c3ecd8193f77f65b0fa6 Mon Sep 17 00:00:00 2001 From: ylavic Date: Fri, 17 Jun 2022 19:47:11 +0000 Subject: Fix various harmless cases of undefined behaviour, and add a Travis job testing under UBSan. * poll/unix/poll.c (apr_poll): For the on-stack array allocation use num+1 since allocating a 0-length array is undefined behaviour. * tables/apr_skiplist.c (get_b_rand): Use unsigned integers to avoid signed integer overflow in the left shift. (skiplist_qpush): Avoid calling memcpy(,NULL,0). * random/unix/apr_random.c (apr_random_add_entropy): Avoid calling memcpy(,NULL,0). * test/teststr.c (overflow_strfsize): Avoid signed integer overflow. Merge r1898076 from trunk. Submitted by: jorton git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1902021 13f79535-47bb-0310-9956-ffa450edef68 --- .travis.yml | 11 +++++++++++ poll/unix/poll.c | 2 +- random/unix/apr_random.c | 2 +- tables/apr_skiplist.c | 10 +++++----- test/teststr.c | 3 ++- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52343512d..d9027ea98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,6 +70,17 @@ matrix: packages: - libtool-bin - gcc-10 + - name: GCC-10, UBsan (Focal) + dist: focal + env: CC=gcc-10 + NOTEST_CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer -Werror -O2" + addons: + apt: + sources: + - sourceline: 'ppa:ubuntu-toolchain-r/test' + packages: + - libtool-bin + - gcc-10 before_script: sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' diff --git a/poll/unix/poll.c b/poll/unix/poll.c index f148f5e50..5b878f15b 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -75,7 +75,7 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num, int i, num_to_poll; #ifdef HAVE_VLA /* XXX: I trust that this is a segv when insufficient stack exists? */ - struct pollfd pollset[num]; + struct pollfd pollset[num + 1]; /* +1 since allocating 0 is undefined behaviour */ #elif defined(HAVE_ALLOCA) struct pollfd *pollset = alloca(sizeof(struct pollfd) * num); if (!pollset) diff --git a/random/unix/apr_random.c b/random/unix/apr_random.c index b042b66bd..9aee3e989 100644 --- a/random/unix/apr_random.c +++ b/random/unix/apr_random.c @@ -238,7 +238,7 @@ APR_DECLARE(void) apr_random_add_entropy(apr_random_t *g,const void *entropy_, if (p->pool_size < p->bytes+1) { unsigned char *np = apr_palloc(g->apr_pool,(p->bytes+1)*2); - memcpy(np,p->pool,p->bytes); + if (p->pool) memcpy(np,p->pool,p->bytes); p->pool = np; p->pool_size = (p->bytes+1)*2; } diff --git a/tables/apr_skiplist.c b/tables/apr_skiplist.c index b11acad69..8013ed781 100644 --- a/tables/apr_skiplist.c +++ b/tables/apr_skiplist.c @@ -60,15 +60,15 @@ struct apr_skiplistnode { apr_skiplist *sl; }; -static int get_b_rand(void) +static unsigned int get_b_rand(void) { - static int ph = 32; /* More bits than we will ever use */ - static int randseq; + static unsigned int ph = 32; /* More bits than we will ever use */ + static unsigned int randseq; if (ph > 31) { /* Num bits in return of rand() */ ph = 0; randseq = rand(); } - return randseq & (1 << ph++); + return randseq & (1U << ph++); } typedef struct { @@ -159,7 +159,7 @@ static apr_status_t skiplist_qpush(apr_skiplist_q *q, apr_skiplistnode *m) size_t size = (q->pos) ? q->pos * 2 : 32; if (q->p) { data = apr_palloc(q->p, size * sizeof(*data)); - if (data) { + if (data && q->data) { memcpy(data, q->data, q->pos * sizeof(*data)); } } diff --git a/test/teststr.c b/test/teststr.c index 1a1d8fa01..432fb6b21 100644 --- a/test/teststr.c +++ b/test/teststr.c @@ -309,7 +309,8 @@ static void overflow_strfsize(abts_case *tc, void *data) } for (off = LONG_MAX; off > 1; off /= 2) { apr_strfsize(off, buf); - apr_strfsize(off + 1, buf); + if (sizeof(apr_off_t) > sizeof(long) || off < LONG_MAX) + apr_strfsize(off + 1, buf); apr_strfsize(off - 1, buf); } -- cgit v1.2.1