Bug Summary

File:home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Library/coreboot/coreboot.c
Warning:line 80, column 13
Access to field 'signature' results in a dereference of a null pointer (loaded from variable 'cbh')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name coreboot.c -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 2 -fhalf-no-semantic-interposition -fno-jump-tables -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/Library/coreboot -resource-dir /opt/xgcc/lib/clang/17 -include PcdData.h -D COREBOOT32 -D RELEASE -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EDKII/BaseTools/Source/C/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/EdkII/MdePkg/Include/X64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Include/x64 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Core/Runtime -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -Os -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/build/StmPkg/Library/coreboot -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-max-loop 10 -analyzer-output=plist-html -faddrsig -o /cb-build/coreboot_scanbuild.0/PURISM_LIBREM15_V4_STM-scanbuildtmp/2024-05-02-081243-2232343-1/report-S9botM.plist -x c /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/stm/Stm/StmPkg/Library/coreboot/coreboot.c
1
2/****************************************************************
3 * Memory map
4 ****************************************************************/
5
6struct cb_header {
7 UINT32 signature;
8 UINT32 header_bytes;
9 UINT32 header_checksum;
10 UINT32 table_bytes;
11 UINT32 table_checksum;
12 UINT32 table_entries;
13};
14
15#define CB_SIGNATURE0x4f49424C 0x4f49424C // "LBIO"
16
17struct cb_memory_range {
18 UINT64 start;
19 UINT64 size;
20 UINT32 type;
21};
22
23struct cb_memory {
24 UINT32 tag;
25 UINT32 size;
26 struct cb_memory_range map[0];
27};
28
29struct cb_forward {
30 UINT32 tag;
31 UINT32 size;
32 UINT64 forward;
33};
34
35#define CB_TAG_FORWARD0x11 0x11
36
37struct cb_cbmem_ref {
38 UINT32 tag;
39 UINT32 size;
40 UINT64 cbmem_addr;
41};
42
43#define CB_TAG_CBMEM_CONSOLE0x17 0x17
44
45struct cbmem_console {
46 UINT32 size;
47 UINT32 cursor;
48 UINT8 body[0];
49} PACKED;
50
51#define CBMC_CURSOR_MASK((1 << 28) - 1) ((1 << 28) - 1)
52#define CBMC_OVERFLOW(1 << 31) (1 << 31)
53
54static struct cbmem_console *cbcon = NULL((void *) 0);
55
56static UINT16
57ipchksum(char *buf, int count)
58{
59 UINT16 *p = (UINT16*)buf;
60 UINT32 sum = 0;
61 while (count > 1) {
62 sum += *p;
63 p++;
64 count -= 2;
65 }
66 if (count)
67 sum += *(UINT8*)p;
68 sum = (sum >> 16) + (sum & 0xffff);
69 sum += (sum >> 16);
70 return ~sum;
71}
72
73// Try to locate the coreboot header in a given address range.
74static struct cb_header *
75find_cb_header(UINT64 addr, int len)
76{
77 UINT64 end = addr + len;
78 for (; addr < end; addr += 16) {
4
Loop condition is true. Entering loop body
79 struct cb_header *cbh = (void*)addr;
5
'cbh' initialized to a null pointer value
80 if (cbh->signature != CB_SIGNATURE0x4f49424C)
6
Access to field 'signature' results in a dereference of a null pointer (loaded from variable 'cbh')
81 continue;
82 UINT32 tsize = cbh->table_bytes;
83 if (! tsize)
84 continue;
85 if (ipchksum((void*)addr, sizeof(*cbh)) != 0)
86 continue;
87 if (ipchksum((void*)addr + sizeof(*cbh), tsize)
88 != cbh->table_checksum)
89 continue;
90 return cbh;
91 }
92 return NULL((void *) 0);
93}
94
95// Try to find the coreboot memory table in the given coreboot table.
96void *
97find_cb_subtable(struct cb_header *cbh, UINT32 tag)
98{
99 char *tbl = (char *)cbh + sizeof(*cbh);
100 UINT32 count = cbh->table_entries;
101 int i;
102 for (i=0; i<count; i++) {
103 struct cb_memory *cbm = (void*)tbl;
104 tbl += cbm->size;
105 if (cbm->tag == tag)
106 return cbm;
107 }
108 return NULL((void *) 0);
109}
110
111struct cb_header *
112find_cb_table(void)
113{
114 struct cb_header *cbh = find_cb_header(0, 0x1000);
2
Passing the value 0 via 1st parameter 'addr'
3
Calling 'find_cb_header'
115 if (!cbh)
116 return NULL((void *) 0);
117 struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD0x11);
118 if (cbf) {
119 //dprintf(3, "Found coreboot table forwarder.\n");
120 cbh = find_cb_header(cbf->forward, 0x100);
121 if (!cbh)
122 return NULL((void *) 0);
123 }
124 return cbh;
125}
126
127static UINT32 STM_cursor = 0;
128
129int init_cbcons(void)
130{
131 struct cb_header *cbh = find_cb_table();
1
Calling 'find_cb_table'
132
133 if (!cbh)
134 goto fail;
135
136 struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE0x17);
137
138 if (cbref) {
139 cbcon = (void*)(UINT64)cbref->cbmem_addr;
140
141 // set the cursor such that the STM console will not overwrite the
142 // coreboot console output
143 STM_cursor = cbcon->cursor & CBMC_CURSOR_MASK((1 << 28) - 1);
144 }
145
146 return 0;
147fail:
148 return -1;
149}
150
151void coreboot_debug_putc(char c)
152{
153#ifdef CONFIG_STM_CBMEM_CONSOLE
154 if (!cbcon)
155 return;
156
157 UINT32 cursor = cbcon->cursor & CBMC_CURSOR_MASK((1 << 28) - 1);
158 UINT32 flags = cbcon->cursor & ~CBMC_CURSOR_MASK((1 << 28) - 1);
159
160 if (cursor >= cbcon->size)
161 return; // Old coreboot version with legacy overflow mechanism.
162
163 cbcon->body[cursor++] = c;
164 if (cursor >= cbcon->size) {
165 cursor = STM_cursor;
166 flags |= CBMC_OVERFLOW(1 << 31);
167 }
168 cbcon->cursor = flags | cursor;
169#endif
170}
171