Bug Summary

File:src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../lib/libsa/cd9660.c
Warning:line 184, column 2
Value stored to 'rc' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple i386-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cd9660.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 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -target-cpu i586 -disable-red-zone -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/stand/efiboot/bootia32/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/efi/include/i386 -D EFIBOOT -D FWRANDOM -D NEEDS_HEAP_H -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/.. -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/efi/include -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/boot -D SOFTRAID -D _STANDALONE -D MDRANDOM -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/efi/include/i386 -D EFIBOOT -D FWRANDOM -D NEEDS_HEAP_H -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/.. -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/efi/include -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../stand/boot -D SOFTRAID -D _STANDALONE -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../.. -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../libsa -I . -I /usr/src/sys/arch/amd64/stand/efiboot/bootia32 -D SMALL -D SLOW -D NOBYFOUR -D __INTERNAL_LIBSA_CREAD -D HEAP_LIMIT=0xc00000 -D HIBERNATE -Oz -Wno-pointer-sign -std=gnu99 -fdebug-compilation-dir=/usr/src/sys/arch/amd64/stand/efiboot/bootia32/obj -ferror-limit 19 -fwrapv -fno-builtin -fwchar-type=short -fno-signed-wchar -fgnuc-version=4.2.1 -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 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sys/arch/amd64/stand/efiboot/bootia32/../../../../../lib/libsa/cd9660.c
1/* $OpenBSD: cd9660.c,v 1.15 2014/11/19 19:58:40 miod Exp $ */
2/* $NetBSD: cd9660.c,v 1.1 1996/09/30 16:01:19 ws Exp $ */
3
4/*
5 * Copyright (C) 1996 Wolfgang Solfrank.
6 * Copyright (C) 1996 TooLs GmbH.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by TooLs GmbH.
20 * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * Stand-alone ISO9660 file reading package.
37 *
38 * Note: This doesn't support Rock Ridge extensions, extended attributes,
39 * blocksizes other than 2048 bytes, multi-extent files, etc.
40 */
41#include <sys/param.h>
42#include <sys/stat.h>
43
44#include <lib/libkern/libkern.h>
45
46#include <isofs/cd9660/iso.h>
47
48#include "stand.h"
49#include "cd9660.h"
50
51struct file {
52 off_t off; /* Current offset within file */
53 daddr32_t bno; /* Starting block number */
54 off_t size; /* Size of file */
55};
56
57struct ptable_ent {
58 char namlen [ISODCL( 1, 1)(1 - 1 + 1)]; /* 711 */
59 char extlen [ISODCL( 2, 2)(2 - 2 + 1)]; /* 711 */
60 char block [ISODCL( 3, 6)(6 - 3 + 1)]; /* 732 */
61 char parent [ISODCL( 7, 8)(8 - 7 + 1)]; /* 722 */
62 char name [1];
63};
64#define PTFIXSZ8 8
65#define PTSIZE(pp)((((8 + isonum_711((pp)->namlen))+((2)-1))/(2))*(2)) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)((((8 + isonum_711((pp)->namlen))+((2)-1))/(2))*(2))
66
67#define cdb2devb(bno)((bno) * (1<<11) / (1 << 9)) ((bno) * ISO_DEFAULT_BLOCK_SIZE(1<<11) / DEV_BSIZE(1 << 9))
68
69static int
70pnmatch(const char *path, struct ptable_ent *pp)
71{
72 const char *cp;
73 int i;
74
75 cp = pp->name;
76 for (i = isonum_711(pp->namlen); --i >= 0; path++, cp++) {
77 if (toupper(*path)(((*path) >= 'a' && (*path) <= 'z')?((*path) - 'a'
+ 'A'):(*path))
== *cp)
78 continue;
79 return 0;
80 }
81 if (*path != '/')
82 return 0;
83 return 1;
84}
85
86static int
87dirmatch(const char *path, struct iso_directory_record *dp)
88{
89 const char *cp;
90 int i;
91
92 /* This needs to be a regular file */
93 if (dp->flags[0] & 6)
94 return 0;
95
96 cp = dp->name;
97 for (i = isonum_711(dp->name_len); --i >= 0; path++, cp++) {
98 if (!*path)
99 break;
100 if (toupper(*path)(((*path) >= 'a' && (*path) <= 'z')?((*path) - 'a'
+ 'A'):(*path))
== *cp)
101 continue;
102 return 0;
103 }
104 if (*path)
105 return 0;
106 /*
107 * Allow stripping of trailing dots and the version number.
108 * Note that this will find the first instead of the last version
109 * of a file.
110 */
111 if (i >= 0 && (*cp == ';' || *cp == '.')) {
112 /* This is to prevent matching of numeric extensions */
113 if (*cp == '.' && cp[1] != ';')
114 return 0;
115 while (--i >= 0)
116 if (*++cp != ';' && (*cp < '0' || *cp > '9'))
117 return 0;
118 }
119 return 1;
120}
121
122int
123cd9660_open(char *path, struct open_file *f)
124{
125 struct file *fp = 0;
126 char *buf;
127 struct iso_primary_descriptor *vd;
128 size_t buf_size, nread, psize, dsize;
129 daddr32_t bno;
130 int parent, ent;
131 struct ptable_ent *pp;
132 struct iso_directory_record *dp;
133 int rc;
134
135 /* First find the volume descriptor */
136 buf = alloc(buf_size = ISO_DEFAULT_BLOCK_SIZE(1<<11));
137 dp = (struct iso_directory_record *)buf;
138 vd = (struct iso_primary_descriptor *)buf;
139 for (bno = 16;; bno++) {
140 twiddle();
141 rc = f->f_dev->dv_strategy(f->f_devdata, F_READ0x0001, cdb2devb(bno)((bno) * (1<<11) / (1 << 9)),
142 ISO_DEFAULT_BLOCK_SIZE(1<<11), buf, &nread);
143 if (rc)
144 goto out;
145 if (nread != ISO_DEFAULT_BLOCK_SIZE(1<<11)) {
146 rc = EIO5;
147 goto out;
148 }
149 rc = EINVAL22;
150 if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id)(memcmp(("CD001"),(vd->id),(sizeof vd->id))) != 0)
151 goto out;
152 if (isonum_711(vd->type) == ISO_VD_END255)
153 goto out;
154 if (isonum_711(vd->type) == ISO_VD_PRIMARY1)
155 break;
156 }
157 if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE(1<<11))
158 goto out;
159
160 /* Now get the path table and lookup the directory of the file */
161 bno = isonum_732(vd->type_m_path_table);
162 psize = isonum_733(vd->path_table_size);
163
164 if (psize > ISO_DEFAULT_BLOCK_SIZE(1<<11)) {
165 free(buf, ISO_DEFAULT_BLOCK_SIZE(1<<11));
166 buf = alloc(buf_size = roundup(psize, ISO_DEFAULT_BLOCK_SIZE)((((psize)+(((1<<11))-1))/((1<<11)))*((1<<11
)))
);
167 }
168
169 twiddle();
170 rc = f->f_dev->dv_strategy(f->f_devdata, F_READ0x0001, cdb2devb(bno)((bno) * (1<<11) / (1 << 9)),
171 buf_size, buf, &nread);
172 if (rc)
173 goto out;
174 if (nread != buf_size) {
175 rc = EIO5;
176 goto out;
177 }
178
179 parent = 1;
180 pp = (struct ptable_ent *)buf;
181 ent = 1;
182 bno = isonum_732(pp->block) + isonum_711(pp->extlen);
183
184 rc = ENOENT2;
Value stored to 'rc' is never read
185 /*
186 * Remove extra separators
187 */
188 while (*path == '/')
189 path++;
190
191 while (*path) {
192 if ((char *)pp >= buf + psize)
193 break;
194 if (isonum_722(pp->parent) != parent)
195 break;
196 if (!pnmatch(path, pp)) {
197 pp = (struct ptable_ent *)((char *)pp + PTSIZE(pp)((((8 + isonum_711((pp)->namlen))+((2)-1))/(2))*(2)));
198 ent++;
199 continue;
200 }
201 path += isonum_711(pp->namlen) + 1;
202 parent = ent;
203 bno = isonum_732(pp->block) + isonum_711(pp->extlen);
204 while ((char *)pp < buf + psize) {
205 if (isonum_722(pp->parent) == parent)
206 break;
207 pp = (struct ptable_ent *)((char *)pp + PTSIZE(pp)((((8 + isonum_711((pp)->namlen))+((2)-1))/(2))*(2)));
208 ent++;
209 }
210 }
211
212 /* Now bno has the start of the directory that supposedly contains the file */
213 bno--;
214 dsize = 1; /* Something stupid, but > 0 XXX */
215 for (psize = 0; psize < dsize;) {
216 if (!(psize % ISO_DEFAULT_BLOCK_SIZE(1<<11))) {
217 bno++;
218 twiddle();
219 rc = f->f_dev->dv_strategy(f->f_devdata, F_READ0x0001,
220 cdb2devb(bno)((bno) * (1<<11) / (1 << 9)),
221 ISO_DEFAULT_BLOCK_SIZE(1<<11),
222 buf, &nread);
223 if (rc)
224 goto out;
225 if (nread != ISO_DEFAULT_BLOCK_SIZE(1<<11)) {
226 rc = EIO5;
227 goto out;
228 }
229 dp = (struct iso_directory_record *)buf;
230 }
231 if (!isonum_711(dp->length)) {
232 if ((void *)dp == buf)
233 psize += ISO_DEFAULT_BLOCK_SIZE(1<<11);
234 else
235 psize = roundup(psize, ISO_DEFAULT_BLOCK_SIZE)((((psize)+(((1<<11))-1))/((1<<11)))*((1<<11
)))
;
236 continue;
237 }
238 if (dsize == 1)
239 dsize = isonum_733(dp->size);
240 if (dirmatch(path, dp))
241 break;
242 psize += isonum_711(dp->length);
243 dp = (struct iso_directory_record *)((char *)dp +
244 isonum_711(dp->length));
245 }
246
247 if (psize >= dsize) {
248 rc = ENOENT2;
249 goto out;
250 }
251
252 /* allocate file system specific data structure */
253 fp = alloc(sizeof(struct file));
254 bzero(fp, sizeof(struct file))((void)memset((fp),0,(sizeof(struct file))));
255 f->f_fsdata = (void *)fp;
256
257 fp->off = 0;
258 fp->bno = isonum_733(dp->extent);
259 fp->size = isonum_733(dp->size);
260 free(buf, buf_size);
261
262 return 0;
263
264out:
265 if (fp)
266 free(fp, sizeof(struct file));
267 free(buf, buf_size);
268
269 return rc;
270}
271
272int
273cd9660_close(struct open_file *f)
274{
275 struct file *fp = (struct file *)f->f_fsdata;
276
277 f->f_fsdata = 0;
278 free(fp, sizeof *fp);
279
280 return 0;
281}
282
283int
284cd9660_read(struct open_file *f, void *start, size_t size, size_t *resid)
285{
286 struct file *fp = (struct file *)f->f_fsdata;
287 int rc = 0;
288 daddr32_t bno;
289 char buf[ISO_DEFAULT_BLOCK_SIZE(1<<11)];
290 char *dp, *st = start;
291 size_t nread, off;
292
293 while (size) {
294 if (fp->off < 0 || fp->off >= fp->size)
295 break;
296 bno = (fp->off >> ISO_DEFAULT_BLOCK_SHIFT11) + fp->bno;
297 if (fp->off & (ISO_DEFAULT_BLOCK_SIZE(1<<11) - 1)
298 || size < ISO_DEFAULT_BLOCK_SIZE(1<<11))
299 dp = buf;
300 else
301 dp = st;
302 twiddle();
303 rc = f->f_dev->dv_strategy(f->f_devdata, F_READ0x0001, cdb2devb(bno)((bno) * (1<<11) / (1 << 9)),
304 ISO_DEFAULT_BLOCK_SIZE(1<<11), dp, &nread);
305 if (rc)
306 return rc;
307 if (nread != ISO_DEFAULT_BLOCK_SIZE(1<<11))
308 return EIO5;
309
310 /*
311 * off is either 0 in the dp == st case or
312 * the offset to the interesting data into the buffer of 'buf'
313 */
314 off = fp->off & (ISO_DEFAULT_BLOCK_SIZE(1<<11) - 1);
315 nread -= off;
316 if (nread > size)
317 nread = size;
318
319 if (nread > (fp->size - fp->off))
320 nread = (fp->size - fp->off);
321
322 if (dp == buf)
323 bcopy(buf + off, st, nread)((void)memmove((st),(buf + off),(nread)));
324
325 st += nread;
326 fp->off += nread;
327 size -= nread;
328 }
329 if (resid)
330 *resid = size;
331 return rc;
332}
333
334int
335cd9660_write(struct open_file *f, void *start, size_t size, size_t *resid)
336{
337 return EROFS30;
338}
339
340off_t
341cd9660_seek(struct open_file *f, off_t offset, int where)
342{
343 struct file *fp = (struct file *)f->f_fsdata;
344
345 switch (where) {
346 case SEEK_SET0:
347 fp->off = offset;
348 break;
349 case SEEK_CUR1:
350 fp->off += offset;
351 break;
352 case SEEK_END2:
353 fp->off = fp->size - offset;
354 break;
355 default:
356 return -1;
357 }
358 return fp->off;
359}
360
361int
362cd9660_stat(struct open_file *f, struct stat *sb)
363{
364 struct file *fp = (struct file *)f->f_fsdata;
365
366 /* only important stuff */
367 sb->st_mode = S_IFREG0100000 | S_IRUSR0000400 | S_IRGRP0000040 | S_IROTH0000004;
368 sb->st_uid = sb->st_gid = 0;
369 sb->st_size = fp->size;
370 return 0;
371}
372
373/*
374 * Not implemented.
375 */
376#ifndef NO_READDIR
377int
378cd9660_readdir(struct open_file *f, char *name)
379{
380 return (EROFS30);
381}
382#endif