vppinfra: fix random buffer OOB crash with ASAN 74/37974/1
authorDmitry Valter <d-valter@yandex-team.ru>
Sun, 22 Jan 2023 13:09:15 +0000 (13:09 +0000)
committerDmitry Valter <dvalter@protonmail.com>
Sun, 22 Jan 2023 13:09:15 +0000 (13:09 +0000)
Don't truncate with vec_set_len bytes before they can be used. When
built with ASAN, it these bytes are poisoned and trigger SIGSEGV when
read.

Type: fix
Signed-off-by: Dmitry Valter <d-valter@yandex-team.ru>
Change-Id: I912dbbd83822b884f214b3ddcde02e3527848592

src/vppinfra/random_buffer.h

index 078e960..83e6bce 100644 (file)
@@ -54,6 +54,9 @@ typedef struct
   /* Random buffer. */
   uword *buffer;
 
+  /* An actual length to be applied before using the buffer. */
+  uword next_read_len;
+
   /* Cache up to 1 word worth of bytes for random data
      less than one word at a time. */
   uword n_cached_bytes;
@@ -84,6 +87,11 @@ clib_random_buffer_get_data (clib_random_buffer_t * b, uword n_bytes)
 {
   uword n_words, i, l;
 
+  if (b->buffer)
+    vec_set_len (b->buffer, b->next_read_len);
+  else
+    ASSERT (b->next_read_len == 0);
+
   l = b->n_cached_bytes;
   if (n_bytes <= l)
     {
@@ -100,7 +108,7 @@ clib_random_buffer_get_data (clib_random_buffer_t * b, uword n_bytes)
     clib_random_buffer_fill (b, n_words);
 
   i = vec_len (b->buffer) - n_words;
-  vec_set_len (b->buffer, i);
+  b->next_read_len = i;
 
   if (n_bytes < sizeof (uword))
     {