analyzer icon indicating copy to clipboard operation
analyzer copied to clipboard

Spurious type-based races for deep accesses to unknown pointers

Open sim642 opened this issue 9 months ago • 1 comments

Example

Program

// PARAM: --set lib.activated[+] zlib
#include <pthread.h>
#include <zlib.h>

void *t_fun(void *arg) {
  z_stream stream;
  inflateInit2(&stream, 32 + 15);
  return NULL;
}

int main(void) {
  pthread_t id;
  pthread_t id2;
  pthread_create(&id, NULL, t_fun, NULL);
  pthread_create(&id2, NULL, t_fun, NULL);
  return 0;
}

Races

[Warning][Race] Memory location (struct internal_state) (race with conf. 60):
  write with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]] (conf. 60)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  write with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]] (conf. 60)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  read with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]] (conf. 60)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  read with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]] (conf. 60)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
[Warning][Race] Memory location (struct z_stream_s) (race with conf. 80):
  write with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]] (conf. 80)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  write with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]] (conf. 80)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  read with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:14:3-14:40#top]] (conf. 80)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)
  read with [mhp:{tid=[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]}, thread:[main, t_fun@tests/regression/04-mutex/01-simple_rc.c:15:3-15:41#top]] (conf. 80)  (exp: & stream) (tests/regression/04-mutex/01-simple_rc.c:7:2-7:32)

Problem

There shouldn't be a race on the (struct z_stream_s) type because it is only accessed with a known pointer &stream. However, inflateInit2 writes its first argument deeply, so ReachableFrom &stream is used to find the written addresses. That also includes an unknown pointer from uninitialized pointer fields. That unknown pointer is turned into a type-based race warning for (struct z_stream_s), which is wrong because the unknown pointer isn't of that type, but (struct internal_state).

A proper solution would require ReachableFrom to return typed unknown pointers or something.

sim642 avatar Sep 27 '23 14:09 sim642