Bug Summary

File:src/usr.sbin/tcpdump/print-fddi.c
Warning:line 329, column 1
Address of stack memory associated with local variable 'ehdr' is still referred to by the global variable 'packetp' upon returning to the caller. This will be a dangling reference

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 print-fddi.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/usr.sbin/tcpdump/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -I /usr/src/usr.sbin/tcpdump/../hostapd -I /usr/src/usr.sbin/tcpdump/../../lib/libpcap -D CSLIP -D PPP -D HAVE_FDDI -D ETHER_SERVICE -D HAVE_ETHER_NTOHOST -D INET6 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -D FAKE_PF_KERNEL -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/tcpdump/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 /usr/src/usr.sbin/tcpdump/print-fddi.c
1/* $OpenBSD: print-fddi.c,v 1.19 2021/12/01 18:28:46 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24#ifdef HAVE_FDDI1
25#include <sys/time.h>
26#include <sys/socket.h>
27#include <sys/file.h>
28#include <sys/ioctl.h>
29
30#include <net/if.h>
31
32#include <netinet/in.h>
33#include <netinet/if_ether.h>
34#include <netinet/ip.h>
35
36#include <ctype.h>
37#include <netdb.h>
38#include <pcap.h>
39#include <stdio.h>
40#include <string.h>
41
42#include "interface.h"
43#include "addrtoname.h"
44#include "ethertype.h"
45
46#include "fddi.h"
47
48/*
49 * Some FDDI interfaces use bit-swapped addresses.
50 */
51#if defined(ultrix) || defined(__alpha) || defined(__bsdi) || \
52 defined(__NetBSD__) || defined(__OpenBSD__1)
53int fddi_bitswap = 0;
54#else
55int fddi_bitswap = 1;
56#endif
57
58/*
59 * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
60 *
61 * Based in part on code by Van Jacobson, which bears this note:
62 *
63 * NOTE: This is a very preliminary hack for FDDI support.
64 * There are all sorts of wired in constants & nothing (yet)
65 * to print SMT packets as anything other than hex dumps.
66 * Most of the necessary changes are waiting on my redoing
67 * the "header" that a kernel fddi driver supplies to bpf: I
68 * want it to look like one byte of 'direction' (0 or 1
69 * depending on whether the packet was inbound or outbound),
70 * two bytes of system/driver dependent data (anything an
71 * implementor thinks would be useful to filter on and/or
72 * save per-packet, then the real 21-byte FDDI header.
73 * Steve McCanne & I have also talked about adding the
74 * 'direction' byte to all bpf headers (e.g., in the two
75 * bytes of padding on an ethernet header). It's not clear
76 * we could do this in a backwards compatible way & we hate
77 * the idea of an incompatible bpf change. Discussions are
78 * proceeding.
79 *
80 * Also, to really support FDDI (and better support 802.2
81 * over ethernet) we really need to re-think the rather simple
82 * minded assumptions about fixed length & fixed format link
83 * level headers made in gencode.c. One day...
84 *
85 * - vj
86 */
87
88#define FDDI_HDRLEN(sizeof(struct fddi_header)) (sizeof(struct fddi_header))
89
90static u_char fddi_bit_swap[] = {
91 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
92 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
93 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
94 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
95 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
96 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
97 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
98 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
99 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
100 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
101 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
102 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
103 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
104 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
105 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
106 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
107 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
108 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
109 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
110 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
111 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
112 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
113 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
114 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
115 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
116 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
117 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
118 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
119 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
120 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
121 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
122 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
123};
124
125/*
126 * Print FDDI frame-control bits
127 */
128static inline void
129print_fddi_fc(u_char fc)
130{
131 switch (fc) {
132
133 case FDDIFC_VOID0x40: /* Void frame */
134 printf("void ");
135 break;
136
137 case FDDIFC_NRT0x80: /* Nonrestricted token */
138 printf("nrt ");
139 break;
140
141 case FDDIFC_RT0xc0: /* Restricted token */
142 printf("rt ");
143 break;
144
145 case FDDIFC_SMT_INFO0x41: /* SMT Info */
146 printf("info ");
147 break;
148
149 case FDDIFC_SMT_NSA0x4F: /* SMT Next station adrs */
150 printf("nsa ");
151 break;
152
153 case FDDIFC_MAC_BEACON0xc2: /* MAC Beacon frame */
154 printf("beacon ");
155 break;
156
157 case FDDIFC_MAC_CLAIM0xc3: /* MAC Claim frame */
158 printf("claim ");
159 break;
160
161 default:
162 switch (fc & FDDIFC_CLFF0xF0) {
163
164 case FDDIFC_MAC0xc0:
165 printf("mac%1x ", fc & FDDIFC_ZZZZ0x0F);
166 break;
167
168 case FDDIFC_SMT0x40:
169 printf("smt%1x ", fc & FDDIFC_ZZZZ0x0F);
170 break;
171
172 case FDDIFC_LLC_ASYNC0x50:
173 printf("async%1x ", fc & FDDIFC_ZZZZ0x0F);
174 break;
175
176 case FDDIFC_LLC_SYNC0xd0:
177 printf("sync%1x ", fc & FDDIFC_ZZZZ0x0F);
178 break;
179
180 case FDDIFC_IMP_ASYNC0x60:
181 printf("imp_async%1x ", fc & FDDIFC_ZZZZ0x0F);
182 break;
183
184 case FDDIFC_IMP_SYNC0xe0:
185 printf("imp_sync%1x ", fc & FDDIFC_ZZZZ0x0F);
186 break;
187
188 default:
189 printf("%02x ", fc);
190 break;
191 }
192 }
193}
194
195/* Extract src, dst addresses */
196static inline void
197extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
198{
199 int i;
200
201 if (fddi_bitswap) {
202 /*
203 * bit-swap the fddi addresses (isn't the IEEE standards
204 * process wonderful!) then convert them to names.
205 */
206 for (i = 0; i < 6; ++i)
207 fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
208 for (i = 0; i < 6; ++i)
209 fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
210 }
211 else {
212 memcpy(fdst, (char *)fddip->fddi_dhost, 6);
213 memcpy(fsrc, (char *)fddip->fddi_shost, 6);
214 }
215}
216
217/*
218 * Print the FDDI MAC header
219 */
220static inline void
221fddi_print(const struct fddi_header *fddip, u_int length,
222 const u_char *fsrc, const u_char *fdst)
223{
224 char *srcname, *dstname;
225
226 srcname = etheraddr_string(fsrc);
227 dstname = etheraddr_string(fdst);
228
229 if (vflag)
230 printf("%02x %s %s %d: ",
231 fddip->fddi_fc,
232 srcname, dstname,
233 length);
234 else if (qflag)
235 printf("%s %s %d: ", srcname, dstname, length);
236 else {
237 (void) print_fddi_fc(fddip->fddi_fc);
238 printf("%s %s %d: ", srcname, dstname, length);
239 }
240}
241
242static inline void
243fddi_smt_print(const u_char *p, u_int length)
244{
245 printf("<SMT printer not yet implemented>");
246}
247
248/*
249 * This is the top level routine of the printer. 'sp' is the points
250 * to the FDDI header of the packet, 'tvp' is the timestamp,
251 * 'length' is the length of the packet off the wire, and 'caplen'
252 * is the number of bytes actually captured.
253 */
254void
255fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
256 const u_char *p)
257{
258 u_int caplen = h->caplen;
259 u_int length = h->len;
260 u_short extracted_ethertype;
261 const struct fddi_header *fddip = (struct fddi_header *)p;
262 struct ether_header ehdr;
263
264 ts_print(&h->ts);
265
266 if (caplen < FDDI_HDRLEN(sizeof(struct fddi_header))) {
1
Assuming the condition is false
2
Taking false branch
267 printf("[|fddi]");
268 goto out;
269 }
270 /*
271 * Get the FDDI addresses into a canonical form
272 */
273 extract_fddi_addrs(fddip, (char *)ESRC(&ehdr)((&ehdr)->ether_shost), (char *)EDST(&ehdr)((&ehdr)->ether_dhost));
274 /*
275 * Some printers want to get back at the link level addresses,
276 * and/or check that they're not walking off the end of the packet.
277 * Rather than pass them all the way down, we set these globals.
278 */
279 snapend = p + caplen;
280 /*
281 * Actually, the only printer that uses packetp is print-bootp.c,
282 * and it assumes that packetp points to an Ethernet header. The
283 * right thing to do is to fix print-bootp.c to know which link
284 * type is in use when it excavates. XXX
285 */
286 packetp = (u_char *)&ehdr;
287
288 if (eflag)
3
Assuming 'eflag' is 0
4
Taking false branch
289 fddi_print(fddip, length, ESRC(&ehdr)((&ehdr)->ether_shost), EDST(&ehdr)((&ehdr)->ether_dhost));
290
291 /* Skip over FDDI MAC header */
292 length -= FDDI_HDRLEN(sizeof(struct fddi_header));
293 p += FDDI_HDRLEN(sizeof(struct fddi_header));
294 caplen -= FDDI_HDRLEN(sizeof(struct fddi_header));
295
296 /* Frame Control field determines interpretation of packet */
297 extracted_ethertype = 0;
298 if ((fddip->fddi_fc & FDDIFC_CLFF0xF0) == FDDIFC_LLC_ASYNC0x50) {
5
Assuming the condition is false
6
Taking false branch
299 /* Try to print the LLC-layer header & higher layers */
300 if (llc_print(p, length, caplen, ESRC(&ehdr)((&ehdr)->ether_shost), EDST(&ehdr)((&ehdr)->ether_dhost))
301 == 0) {
302 /*
303 * Some kinds of LLC packet we cannot
304 * handle intelligently
305 */
306 if (!eflag)
307 fddi_print(fddip, length,
308 ESRC(&ehdr)((&ehdr)->ether_shost), EDST(&ehdr)((&ehdr)->ether_dhost));
309 if (extracted_ethertype) {
310 printf("(LLC %s) ",
311 etherproto_string(htons(extracted_ethertype)(__uint16_t)(__builtin_constant_p(extracted_ethertype) ? (__uint16_t
)(((__uint16_t)(extracted_ethertype) & 0xffU) << 8 |
((__uint16_t)(extracted_ethertype) & 0xff00U) >> 8
) : __swap16md(extracted_ethertype))
));
312 }
313 if (!xflag && !qflag)
314 default_print(p, caplen);
315 }
316 } else if ((fddip->fddi_fc & FDDIFC_CLFF0xF0) == FDDIFC_SMT0x40)
7
Assuming the condition is true
8
Taking true branch
317 fddi_smt_print(p, caplen);
318 else {
319 /* Some kinds of FDDI packet we cannot handle intelligently */
320 if (!eflag)
321 fddi_print(fddip, length, ESRC(&ehdr)((&ehdr)->ether_shost), EDST(&ehdr)((&ehdr)->ether_dhost));
322 if (!xflag && !qflag)
323 default_print(p, caplen);
324 }
325 if (xflag)
9
Assuming 'xflag' is 0
10
Taking false branch
326 default_print(p, caplen);
327out:
328 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
11
Assuming '__isthreaded' is not equal to 0
12
'?' condition is false
329}
13
Address of stack memory associated with local variable 'ehdr' is still referred to by the global variable 'packetp' upon returning to the caller. This will be a dangling reference
330#else
331#include <sys/types.h>
332#include <sys/time.h>
333
334#include <stdio.h>
335
336#include "interface.h"
337void
338fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
339 const u_char *p)
340{
341
342 error("not configured for fddi");
343 /* NOTREACHED */
344}
345#endif