facebook / facebook/infer

False positive UNINITIALIZED_VALUE in C with semctl()

Open
#1,061 3 comments 1 reaction 0 assignees View on GitHub
c false-positive
Dominant language
OCaml
Stars
15.7k
Forks
2.1k
Avg merge
19h 36m
Merged PRs (30d)
13

Description

**Infer version**
```
$ infer --version
Infer version v0.15.0
Copyright 2009 - present Facebook. All Rights Reserved.
```
**OS**
Release Linux Mint 19.1 Tessa 64-bit
Kernel Linux 4.15.0-45-generic x86_64
MATE 1.20.1

**Command**
```
$ infer run -- clang -Wall -Wextra -Wpedantic -g -O2 test.c
```
**Result**
```
test.c:34: error: UNINITIALIZED_VALUE
The value read from semid_ds.sem_ctime was never initialized.
32.
33. printf("Last semop time: %ld\n", (long)semid_ds.sem_otime);
34. > printf("Last change time: %ld\n", (long)semid_ds.sem_ctime);
35. printf("No. of semaphores in set: %lu\n", semid_ds.sem_nsems);
36.

test.c:35: error: UNINITIALIZED_VALUE
The value read from semid_ds.sem_nsems was never initialized.
33. printf("Last semop time: %ld\n", (long)semid_ds.sem_otime);
34. printf("Last change time: %ld\n", (long)semid_ds.sem_ctime);
35. > printf("No. of semaphores in set: %lu\n", semid_ds.sem_nsems);
36.
37. return 0;

test.c:33: error: UNINITIALIZED_VALUE
The value read from semid_ds.sem_otime was never initialized.
31. return -1;
32.
33. > printf("Last semop time: %ld\n", (long)semid_ds.sem_otime);
34. printf("Last change time: %ld\n", (long)semid_ds.sem_ctime);
35. printf("No. of semaphores in set: %lu\n", semid_ds.sem_nsems);
```
**Source**
```c
#include
#include
#include

#include

/* POSIX.1 requires that the caller define this union. */
/* On versions of glibc where this union is not */
/* defined, the macro _SEM_SEMUN_UNDEFINED is defined. */
#ifdef _SEM_SEMUN_UNDEFINED
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
#ifdef IPC_INFO
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
#endif
};
#endif

int main(void)
{
int semid = 0;
struct semid_ds semid_ds;
union semun semid_un;

semid_un.buf = &semid_ds;

if (-1 == semctl(semid, 0, IPC_STAT, semid_un))
return -1;

printf("Last semop time: %ld\n", (long)semid_ds.sem_otime);
printf("Last change time: %ld\n", (long)semid_ds.sem_ctime);
printf("No. of semaphores in set: %lu\n", semid_ds.sem_nsems);

return 0;
}
```
**Problem**
I believe this is a false positive because source follows `man semctl` and correctly reports values:
```
$ clang -Wall -Wextra -Wpedantic -g -O2 test.c
$ sudo ./a.out
Last semop time: 1550598871
Last change time: 1550598871
No. of semaphores in set: 17
```
For the reference:
```
$ date -d @1550598871
Tue Feb 19 19:54:31 EET 2019
```
Here is the output of `ipcs` utility:
```
$ sudo ipcs -s --id=0

Semaphore Array semid=0
uid=122 gid=131 cuid=122 cgid=131
mode=0600, access_perms=0600
nsems = 17
otime = Tue Feb 19 19:54:31 2019
ctime = Tue Feb 19 19:54:31 2019
semnum value ncount zcount pid
0 1 0 0 1325
1 1 0 0 1325
2 1 0 0 1325
3 1 0 0 1325
4 1 0 0 1325
5 1 0 0 1325
6 1 0 0 1325
7 1 0 0 1325
8 1 0 0 1325
9 1 0 0 1325
10 1 0 0 1325
11 1 0 0 1325
12 1 0 0 1325
13 1 0 0 1325
14 1 0 0 1325
15 1 0 0 1325
16 537 0 0 1325

```
I believe this is down to incomplete `semctl()` model.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.