Skip to content

Commit

Permalink
http: fix use-of-uninitialized-value bug
Browse files Browse the repository at this point in the history
This was found via MSan.

In nxt_http_fields_hash() we setup a nxt_lvlhsh_query_t structure and
initialise a couple of its members.

At some point we call

  lhq->proto->alloc(lhq->pool, nxt_lvlhsh_bucket_size(lhq->proto));

Which in this case is

  void *
  nxt_lvlhsh_alloc(void *data, size_t size)
  {
      return nxt_memalign(size, size);
  }

So even though lhq.ppol wasn't previously initialised we don't actually
use it in that particular function.

However MSan triggers on the fact that we are passing an uninitialised
value into that function.

Indeed, compilers will generally complain about such things, e.g

  /* u.c */
  struct t {
  	void *p;
  	int len;
  };

  static void test(void *p __attribute__((unused)), int len)
  {
  	(void)len;
  }

  int main(void)
  {
  	struct t t;

  	t.len = 42;
  	test(t.p, t.len);

  	return 0;
  }

GCC and Clang will produce a -Wuninitialized warning.

But they won't catch the following...

  /* u2.c */
  struct t {
          void *p;
          int len;
  };

  static void _test(void *p __attribute__((unused)), int len)
  {
          (void)len;
  }

  static void test(struct t *t)
  {
          _test(t->p, t->len);
  }

  int main(void)
  {
          struct t t;

          t.len = 42;
          test(&t);

          return 0;
  }

Which is why we don't get a compiler warning about lhq.pool.

In this case initialising lhg.pool even though we don't use it here
seems like the right thing to do and maybe compilers will start being
able to catch these in the future.

Actually GCC with -fanalyzer does catch the above

  $ gcc -Wall -Wextra -O0 -fanalyzer u2.c
  u2.c: In function ‘test’:
  u2.c:15:9: warning: use of uninitialized value ‘*t.p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
     15 |         _test(t->p, t->len);
        |         ^~~~~~~~~~~~~~~~~~~
    ‘main’: events 1-3
      |
      |   18 | int main(void)
      |      |     ^~~~
      |      |     |
      |      |     (1) entry to ‘main’
      |   19 | {
      |   20 |         struct t t;
      |      |                  ~
      |      |                  |
      |      |                  (2) region created on stack here
      |......
      |   23 |         test(&t);
      |      |         ~~~~~~~~
      |      |         |
      |      |         (3) calling ‘test’ from ‘main’
      |
      +--> ‘test’: events 4-5
             |
             |   13 | static void test(struct t *t)
             |      |             ^~~~
             |      |             |
             |      |             (4) entry to ‘test’
             |   14 | {
             |   15 |         _test(t->p, t->len);
             |      |         ~~~~~~~~~~~~~~~~~~~
             |      |         |
             |      |         (5) use of uninitialized value ‘*t.p’ here
             |

Signed-off-by: Arjun <[email protected]>
Link: <https://clang.llvm.org/docs/MemorySanitizer.html>
[ Commit message - Andrew ]
Signed-off-by: Andrew Clayton <[email protected]>
  • Loading branch information
pkillarjun authored and ac000 committed Jun 14, 2024
1 parent d7ec30c commit 04a24f6
Showing 1 changed file with 1 addition and 0 deletions.
1 change: 1 addition & 0 deletions src/nxt_http_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,7 @@ nxt_http_fields_hash(nxt_lvlhsh_t *hash,

lhq.replace = 0;
lhq.proto = &nxt_http_fields_hash_proto;
lhq.pool = NULL;

for (i = 0; i < count; i++) {
key = NXT_HTTP_FIELD_HASH_INIT;
Expand Down

0 comments on commit 04a24f6

Please sign in to comment.