Bug Summary

File:isofs/udf/udf_subr.c
Warning:line 158, column 6
1st function call argument is an uninitialized value

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 udf_subr.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 static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/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 -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/isofs/udf/udf_subr.c
1/* $OpenBSD: udf_subr.c,v 1.25 2014/12/16 18:30:03 tedu Exp $ */
2
3/*
4 * Copyright (c) 2006, Miodrag Vallat
5 * Copyright (c) 2006, Pedro Martelletto
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/buf.h>
32#include <sys/kernel.h>
33#include <sys/malloc.h>
34#include <sys/mutex.h>
35#include <sys/stat.h>
36#include <sys/mount.h>
37#include <sys/vnode.h>
38#include <sys/lock.h>
39#include <sys/dirent.h>
40#include <sys/disklabel.h>
41
42#include <crypto/siphash.h>
43
44#include <isofs/udf/ecma167-udf.h>
45#include <isofs/udf/udf.h>
46#include <isofs/udf/udf_extern.h>
47
48int udf_vat_read(struct umount *, uint32_t *);
49
50/*
51 * Convert a CS0 dstring to a 16-bit Unicode string.
52 * Returns the length of the Unicode string, in unicode characters (not
53 * bytes!), or -1 if an error arises.
54 * Note that the transname destination buffer is expected to be large
55 * enough to hold the result, and will not be terminated in any way.
56 */
57int
58udf_rawnametounicode(u_int len, char *cs0string, unicode_t *transname)
59{
60 unicode_t *origname = transname;
61
62 if (len-- == 0)
63 return (-1);
64
65 switch (*cs0string++) {
66 case 8: /* bytes string */
67 while (len-- != 0)
68 *transname++ = (unicode_t)*cs0string++;
69 break;
70 case 16: /* 16 bit unicode string */
71 if (len & 1)
72 return (-1);
73 len >>= 1;
74 while (len-- != 0) {
75 unicode_t tmpchar;
76
77 tmpchar = (unicode_t)*cs0string++;
78 tmpchar = (tmpchar << 8) | (unicode_t)*cs0string++;
79 *transname++ = tmpchar;
80 }
81 break;
82 default:
83 return (-1);
84 }
85
86 return (transname - origname);
87}
88
89/*
90 * Do a lazy probe on the underlying media to check if it's a UDF volume, in
91 * which case we fake a disk label for it.
92 */
93int
94udf_disklabelspoof(dev_t dev, void (*strat)(struct buf *),
95 struct disklabel *lp)
96{
97 char vid[32];
98 int i, bsize = 2048, error = EINVAL22;
99 uint32_t sector = 256, mvds_start, mvds_end;
100 struct buf *bp;
101 struct anchor_vdp avdp;
102 struct pri_vol_desc *pvd;
103
104 /*
105 * Get a buffer to work with.
106 */
107 bp = geteblk(bsize);
108 bp->b_dev = dev;
109
110 /*
111 * Look for an Anchor Volume Descriptor at sector 256.
112 */
113 bp->b_blkno = sector * btodb(bsize)((bsize) >> 9);
114 bp->b_bcount = bsize;
115 CLR(bp->b_flags, B_READ | B_WRITE | B_DONE)((bp->b_flags) &= ~(0x00008000 | 0x00000000 | 0x00000100
))
;
116 SET(bp->b_flags, B_BUSY | B_READ | B_RAW)((bp->b_flags) |= (0x00000010 | 0x00008000 | 0x00004000));
117 bp->b_resid = bp->b_blkno / lp->d_secpercyl;
118
119 (*strat)(bp);
120 if (biowait(bp))
1
Assuming the condition is false
2
Taking false branch
121 goto out;
122
123 if (udf_checktag((struct desc_tag *)bp->b_data, TAGID_ANCHOR))
3
Assuming the condition is false
4
Taking false branch
124 goto out;
125
126 bcopy(bp->b_data, &avdp, sizeof(avdp));
127 mvds_start = letoh32(avdp.main_vds_ex.loc)((__uint32_t)(avdp.main_vds_ex.loc));
128 mvds_end = mvds_start + (letoh32(avdp.main_vds_ex.len)((__uint32_t)(avdp.main_vds_ex.len)) - 1) / bsize;
129
130 /*
131 * Then try to find a reference to a Primary Volume Descriptor.
132 */
133 for (sector = mvds_start; sector < mvds_end; sector++) {
5
Assuming 'sector' is >= 'mvds_end'
6
Loop condition is false. Execution continues on line 152
134 bp->b_blkno = sector * btodb(bsize)((bsize) >> 9);
135 bp->b_bcount = bsize;
136 CLR(bp->b_flags, B_READ | B_WRITE | B_DONE)((bp->b_flags) &= ~(0x00008000 | 0x00000000 | 0x00000100
))
;
137 SET(bp->b_flags, B_BUSY | B_READ | B_RAW)((bp->b_flags) |= (0x00000010 | 0x00008000 | 0x00004000));
138 bp->b_resid = bp->b_blkno / lp->d_secpercyl;
139
140 (*strat)(bp);
141 if (biowait(bp))
142 goto out;
143
144 pvd = (struct pri_vol_desc *)bp->b_data;
145 if (!udf_checktag(&pvd->tag, TAGID_PRI_VOL))
146 break;
147 }
148
149 /*
150 * If we couldn't find a reference, bail out.
151 */
152 if (sector == mvds_end)
7
Assuming 'sector' is not equal to 'mvds_end'
8
Taking false branch
153 goto out;
154
155 /*
156 * Okay, it's a UDF volume. Spoof a disk label for it.
157 */
158 if (udf_transname(pvd->vol_id, vid, sizeof(pvd->vol_id) - 1, NULL((void *)0)))
9
1st function call argument is an uninitialized value
159 strlcpy(lp->d_typename, vid, sizeof(lp->d_typename));
160
161 for (i = 0; i < MAXPARTITIONS16; i++) {
162 DL_SETPSIZE(&lp->d_partitions[i], 0)do { u_int64_t __x = (0); (&lp->d_partitions[i])->p_sizeh
= __x >> 32; (&lp->d_partitions[i])->p_size =
__x; } while (0)
;
163 DL_SETPOFFSET(&lp->d_partitions[i], 0)do { u_int64_t __x = (0); (&lp->d_partitions[i])->p_offseth
= __x >> 32; (&lp->d_partitions[i])->p_offset
= __x; } while (0)
;
164 }
165
166 /*
167 * Fake two partitions, 'a' and 'c'.
168 */
169 DL_SETPSIZE(&lp->d_partitions[0], DL_GETDSIZE(lp))do { u_int64_t __x = ((((u_int64_t)(lp)->d_secperunith <<
32) + (lp)->d_secperunit)); (&lp->d_partitions[0])
->p_sizeh = __x >> 32; (&lp->d_partitions[0])
->p_size = __x; } while (0)
;
170 lp->d_partitions[0].p_fstype = FS_UDF21;
171 DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp))do { u_int64_t __x = ((((u_int64_t)(lp)->d_secperunith <<
32) + (lp)->d_secperunit)); (&lp->d_partitions[2])
->p_sizeh = __x >> 32; (&lp->d_partitions[2])
->p_size = __x; } while (0)
;
172 lp->d_partitions[RAW_PART2].p_fstype = FS_UDF21;
173 lp->d_npartitions = MAXPARTITIONS16;
174 lp->d_version = 1;
175
176 lp->d_bbsize = 8192; /* Fake. */
177 lp->d_sbsize = 64*1024; /* Fake. */
178 lp->d_magic = DISKMAGIC((u_int32_t)0x82564557);
179 lp->d_magic2 = DISKMAGIC((u_int32_t)0x82564557);
180 lp->d_checksum = dkcksum(lp);
181
182 error = 0;
183out:
184 bp->b_flags |= B_INVAL0x00000800;
185 brelse(bp);
186
187 return (error);
188}
189
190/* Get a vnode for the Virtual Allocation Table (VAT) */
191int
192udf_vat_get(struct umount *ump, uint32_t lb)
193{
194 struct vnode *vp;
195 struct unode *up;
196 int error;
197
198 error = udf_vget(ump->um_mountp, lb - ump->um_start - 3, &vp);
199 if (error)
200 return (error);
201
202 up = VTOU(vp)((struct unode *)((vp)->v_data));
203 up->u_vatlenun_u.u_vatlen = (letoh64(up->u_fentry->inf_len)((__uint64_t)(up->u_fentry->inf_len)) - 36) >> 2;
204
205 ump->um_vat = malloc(sizeof(struct unode), M_UDFMOUNT140, M_WAITOK0x0001);
206 *ump->um_vat = *up;
207
208 ump->um_flags &= ~UDF_MNT_FIND_VAT0x01;
209 ump->um_flags |= UDF_MNT_USES_VAT0x02;
210
211 vput(vp);
212
213 return (0);
214}
215
216/* Look up a sector in the VAT */
217int
218udf_vat_map(struct umount *ump, uint32_t *sector)
219{
220 /* If there's no VAT, then it's easy */
221 if (!(ump->um_flags & UDF_MNT_USES_VAT0x02)) {
222 *sector += ump->um_start;
223 return (0);
224 }
225
226 /* Sanity check the given sector */
227 if (*sector >= ump->um_vat->u_vatlenun_u.u_vatlen)
228 return (EINVAL22);
229
230 return (udf_vat_read(ump, sector));
231}
232
233/* Read from the VAT */
234int
235udf_vat_read(struct umount *ump, uint32_t *sector)
236{
237 struct buf *bp;
238 uint8_t *data;
239 int error, size;
240
241 size = 4;
242
243 /*
244 * Note that we rely on the buffer cache to keep frequently accessed
245 * buffers around to avoid reading them from the disk all the time.
246 */
247 error = udf_readatoffset(ump->um_vat, &size, *sector << 2, &bp, &data);
248 if (error) {
249 if (bp != NULL((void *)0))
250 brelse(bp);
251
252 return (error);
253 }
254
255 /* Make sure we read at least a whole entry */
256 if (size < 4) {
257 if (bp != NULL((void *)0))
258 brelse(bp);
259
260 return (EINVAL22);
261 }
262
263 /* Map the sector */
264 *sector = letoh32(*(uint32_t *)data)((__uint32_t)(*(uint32_t *)data)) + ump->um_start;
265
266 brelse(bp);
267
268 return (0);
269}