Bug Summary

File:src/gnu/usr.bin/cvs/obj/conftest.c
Warning:line 34, column 13
This function call is prohibited after a successful vfork

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name conftest.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/cvs/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/gnu/usr.bin/cvs/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c conftest.c
1#line 3086 "configure"
2#include "confdefs.h"
3/* Thanks to Paul Eggert for this test. */
4#include <stdio.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#ifdef HAVE_UNISTD_H1
8#include <unistd.h>
9#endif
10#ifdef HAVE_VFORK_H
11#include <vfork.h>
12#endif
13/* On some sparc systems, changes by the child to local and incoming
14 argument registers are propagated back to the parent.
15 The compiler is told about this with #include <vfork.h>,
16 but some compilers (e.g. gcc -O) don't grok <vfork.h>.
17 Test for this by using a static variable whose address
18 is put into a register that is clobbered by the vfork. */
19static
20#ifdef __cplusplus
21sparc_address_test (int arg)
22#else
23sparc_address_test (arg) int arg;
24#endif
25{
26 static pid_t child;
27 if (!child
0.1
'child' is 0
) {
1
Taking true branch
28 child = vfork ();
29 if (child
1.1
'child' is >= 0
< 0) {
2
Taking false branch
30 perror ("vfork");
31 _exit(2);
32 }
33 if (!child
2.1
'child' is 0
) {
3
Taking true branch
34 arg = getpid();
4
This function call is prohibited after a successful vfork
35 write(-1, "", 0);
36 _exit (arg);
37 }
38 }
39}
40main() {
41 pid_t parent = getpid ();
42 pid_t child;
43
44 sparc_address_test ();
45
46 child = vfork ();
47
48 if (child == 0) {
49 /* Here is another test for sparc vfork register problems.
50 This test uses lots of local variables, at least
51 as many local variables as main has allocated so far
52 including compiler temporaries. 4 locals are enough for
53 gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
54 A buggy compiler should reuse the register of parent
55 for one of the local variables, since it will think that
56 parent can't possibly be used any more in this routine.
57 Assigning to the local variable will thus munge parent
58 in the parent process. */
59 pid_t
60 p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
61 p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
62 /* Convince the compiler that p..p7 are live; otherwise, it might
63 use the same hardware register for all 8 local variables. */
64 if (p != p1 || p != p2 || p != p3 || p != p4
65 || p != p5 || p != p6 || p != p7)
66 _exit(1);
67
68 /* On some systems (e.g. IRIX 3.3),
69 vfork doesn't separate parent from child file descriptors.
70 If the child closes a descriptor before it execs or exits,
71 this munges the parent's descriptor as well.
72 Test for this by closing stdout in the child. */
73 _exit(close(fileno(stdout)(!__isthreaded ? (((&__sF[1]))->_file) : (fileno)((&
__sF[1])))
) != 0);
74 } else {
75 int status;
76 struct stat st;
77
78 while (wait(&status) != child)
79 ;
80 exit(
81 /* Was there some problem with vforking? */
82 child < 0
83
84 /* Did the child fail? (This shouldn't happen.) */
85 || status
86
87 /* Did the vfork/compiler bug occur? */
88 || parent != getpid()
89
90 /* Did the file descriptor bug occur? */
91 || fstat(fileno(stdout)(!__isthreaded ? (((&__sF[1]))->_file) : (fileno)((&
__sF[1])))
, &st) != 0
92 );
93 }
94}