Bug Summary

File:src/usr.sbin/makefs/msdos/msdosfs_lookup.c
Warning:line 230, column 14
Although the value stored to 'rberror' is used in the enclosing expression, the value is never actually read from 'rberror'

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 msdosfs_lookup.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/makefs/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/makefs -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/makefs/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/makefs/msdos/msdosfs_lookup.c
1/* $OpenBSD: msdosfs_lookup.c,v 1.4 2021/10/06 00:40:41 deraadt Exp $ */
2/* $NetBSD: msdosfs_lookup.c,v 1.35 2016/01/30 09:59:27 mlelstv Exp $ */
3
4/*-
5 * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
6 * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
7 * All rights reserved.
8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by TooLs GmbH.
21 * 4. The name of TooLs GmbH may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35/*
36 * Written by Paul Popelka (paulp@uts.amdahl.com)
37 *
38 * You can do anything you want with this software, just don't say you wrote
39 * it, and don't remove this notice.
40 *
41 * This software is provided "as is".
42 *
43 * The author supplies this software to be publicly redistributed on the
44 * understanding that the author is not responsible for the correct
45 * functioning of this software in any circumstances and is not liable for
46 * any damages caused by this software.
47 *
48 * October 1992
49 */
50
51
52#include "ffs/buf.h"
53
54#include <msdosfs/bpb.h>
55#include "msdos/direntry.h"
56#include "msdos/denode.h"
57#include "msdos/msdosfsmount.h"
58#include "msdos/fat.h"
59
60
61
62/*
63 * dep - directory entry to copy into the directory
64 * ddep - directory to add to
65 * depp - return the address of the denode for the created directory entry
66 * if depp != 0
67 * cnp - componentname needed for Win95 long filenames
68 */
69int
70createde(struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp)
71{
72 int error, rberror;
73 u_long dirclust, clusoffset;
74 u_long fndoffset, havecnt = 0, wcnt = 1, i;
75 struct direntry *ndep;
76 struct msdosfsmount *pmp = ddep->de_pmp;
77 struct mkfsbuf *bp;
78 daddr_t bn;
79 int blsize;
80#define async0 0
81
82#ifdef MSDOSFS_DEBUG
83 printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n",
84 dep, ddep, depp, cnp);
85#endif
86
87 /*
88 * If no space left in the directory then allocate another cluster
89 * and chain it onto the end of the file. There is one exception
90 * to this. That is, if the root directory has no more space it
91 * can NOT be expanded. extendfile() checks for and fails attempts
92 * to extend the root directory. We just return an error in that
93 * case.
94 */
95 if (ddep->de_fndoffset >= ddep->de_FileSize) {
96 u_long needlen = ddep->de_fndoffset + sizeof(struct direntry)
97 - ddep->de_FileSize;
98 dirclust = de_clcount(pmp, needlen)(((needlen) + (pmp)->pm_bpcluster - 1) >> (pmp)->
pm_cnshift)
;
99 if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR1)) != 0) {
100 (void)detrunc(ddep, ddep->de_FileSize, 0);
101 goto err_norollback;
102 }
103
104 /*
105 * Update the size of the directory
106 */
107 ddep->de_FileSize += de_cn2off(pmp, dirclust)((dirclust) << (pmp)->pm_cnshift);
108 }
109
110 /*
111 * We just read in the cluster with space. Copy the new directory
112 * entry in. Then write it to disk. NOTE: DOS directories
113 * do not get smaller as clusters are emptied.
114 */
115 error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset)((ddep->de_fndoffset) >> (pmp)->pm_cnshift),
116 &bn, &dirclust, &blsize);
117 if (error)
118 goto err_norollback;
119 clusoffset = ddep->de_fndoffset;
120 if (dirclust != MSDOSFSROOT0)
121 clusoffset &= pmp->pm_crbomask;
122 if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)), blsize,
123 B_MODIFY0, &bp)) != 0) {
124 goto err_norollback;
125 }
126 ndep = bptoep(pmp, bp, clusoffset)((struct direntry *)(((char *)(bp)->b_data) + ((clusoffset
) & (pmp)->pm_crbomask)))
;
127
128 DE_EXTERNALIZE(ndep, dep)(memcpy((ndep)->deName, (dep)->de_Name, 11), (ndep)->
deAttributes = (dep)->de_Attributes, (ndep)->deCTimeHundredth
= (dep)->de_CHun, (*((u_int16_t *)((ndep)->deCTime)) =
((dep)->de_CTime)), (*((u_int16_t *)((ndep)->deCDate))
= ((dep)->de_CDate)), (*((u_int16_t *)((ndep)->deADate
)) = ((dep)->de_ADate)), (*((u_int16_t *)((ndep)->deMTime
)) = ((dep)->de_MTime)), (*((u_int16_t *)((ndep)->deMDate
)) = ((dep)->de_MDate)), (*((u_int16_t *)((ndep)->deStartCluster
)) = ((dep)->de_StartCluster)), (*((u_int32_t *)((ndep)->
deFileSize)) = (((dep)->de_Attributes & 0x10) ? 0 : (dep
)->de_FileSize)), (((dep)->de_pmp->pm_fatmask == 0x0fffffff
) ? (*((u_int16_t *)(((ndep))->deHighClust)) = (((dep))->
de_StartCluster >> 16)) : (*((u_int16_t *)(((ndep))->
deHighClust)) = (0))))
;
129
130 /*
131 * Now write the Win95 long name
132 */
133 if (ddep->de_fndcnt > 0) {
134 u_int8_t chksum = winChksum(ndep->deName);
135 u_char *un = cnp->cn_nameptr;
136 int unlen = cnp->cn_namelen;
137 u_long xhavecnt;
138
139 fndoffset = ddep->de_fndoffset;
140 xhavecnt = ddep->de_fndcnt + 1;
141
142 for(; wcnt < xhavecnt; wcnt++) {
143 if ((fndoffset & pmp->pm_crbomask) == 0) {
144 /* we should never get here if ddep is root
145 * directory */
146
147 if (async0)
148 (void) bdwrite(bp)bwrite(bp);
149 else if ((error = bwrite(bp)) != 0)
150 goto rollback;
151
152 fndoffset -= sizeof(struct direntry);
153 error = pcbmap(ddep,
154 de_cluster(pmp, fndoffset)((fndoffset) >> (pmp)->pm_cnshift),
155 &bn, 0, &blsize);
156 if (error)
157 goto rollback;
158
159 error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)),
160 blsize, B_MODIFY0, &bp);
161 if (error) {
162 goto rollback;
163 }
164 ndep = bptoep(pmp, bp,((struct direntry *)(((char *)(bp)->b_data) + ((fndoffset &
pmp->pm_crbomask) & (pmp)->pm_crbomask)))
165 fndoffset & pmp->pm_crbomask)((struct direntry *)(((char *)(bp)->b_data) + ((fndoffset &
pmp->pm_crbomask) & (pmp)->pm_crbomask)))
;
166 } else {
167 ndep--;
168 fndoffset -= sizeof(struct direntry);
169 }
170 if (!unix2winfn(un, unlen, (struct winentry *)ndep,
171 wcnt, chksum))
172 break;
173 }
174 }
175
176 if (async0)
177 bdwrite(bp)bwrite(bp);
178 else if ((error = bwrite(bp)) != 0)
179 goto rollback;
180
181 /*
182 * If they want us to return with the denode gotten.
183 */
184 if (depp) {
185 u_long diroffset = clusoffset;
186
187 if (dep->de_Attributes & ATTR_DIRECTORY0x10) {
188 dirclust = dep->de_StartCluster;
189 if (FAT32(pmp)(pmp->pm_fatmask == 0x0fffffff) && dirclust == pmp->pm_rootdirblk)
190 dirclust = MSDOSFSROOT0;
191 if (dirclust == MSDOSFSROOT0)
192 diroffset = MSDOSFSROOT_OFS0x1fffffff;
193 else
194 diroffset = 0;
195 }
196 error = deget(pmp, dirclust, diroffset, depp);
197 return error;
198 }
199
200 return 0;
201
202 rollback:
203 /*
204 * Mark all slots modified so far as deleted. Note that we
205 * can't just call removede(), since directory is not in
206 * consistent state.
207 */
208 fndoffset = ddep->de_fndoffset;
209 rberror = pcbmap(ddep, de_cluster(pmp, fndoffset)((fndoffset) >> (pmp)->pm_cnshift),
210 &bn, NULL((void*)0), &blsize);
211 if (rberror)
212 goto err_norollback;
213 if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)), blsize,
214 B_MODIFY0, &bp)) != 0) {
215 goto err_norollback;
216 }
217 ndep = bptoep(pmp, bp, clusoffset)((struct direntry *)(((char *)(bp)->b_data) + ((clusoffset
) & (pmp)->pm_crbomask)))
;
218
219 havecnt = ddep->de_fndcnt + 1;
220 for(i = wcnt; i <= havecnt; i++) {
221 /* mark entry as deleted */
222 ndep->deName[0] = SLOT_DELETED0xe5;
223
224 if ((fndoffset & pmp->pm_crbomask) == 0) {
225 /* we should never get here if ddep is root
226 * directory */
227
228 if (async0)
229 bdwrite(bp)bwrite(bp);
230 else if ((rberror = bwrite(bp)) != 0)
Although the value stored to 'rberror' is used in the enclosing expression, the value is never actually read from 'rberror'
231 goto err_norollback;
232
233 fndoffset -= sizeof(struct direntry);
234 rberror = pcbmap(ddep,
235 de_cluster(pmp, fndoffset)((fndoffset) >> (pmp)->pm_cnshift),
236 &bn, 0, &blsize);
237 if (rberror)
238 goto err_norollback;
239
240 rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)),
241 blsize, B_MODIFY0, &bp);
242 if (rberror) {
243 goto err_norollback;
244 }
245 ndep = bptoep(pmp, bp, fndoffset)((struct direntry *)(((char *)(bp)->b_data) + ((fndoffset)
& (pmp)->pm_crbomask)))
;
246 } else {
247 ndep--;
248 fndoffset -= sizeof(struct direntry);
249 }
250 }
251
252 /* ignore any further error */
253 if (async0)
254 (void) bdwrite(bp)bwrite(bp);
255 else
256 (void) bwrite(bp);
257
258 err_norollback:
259 return error;
260}
261
262/*
263 * Read in the disk block containing the directory entry (dirclu, dirofs)
264 * and return the address of the buf header, and the address of the
265 * directory entry within the block.
266 */
267int
268readep(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, struct mkfsbuf **bpp, struct direntry **epp)
269{
270 int error;
271 daddr_t bn;
272 int blsize;
273
274 blsize = pmp->pm_bpcluster;
275 if (dirclust == MSDOSFSROOT0
276 && de_blk(pmp, diroffset + blsize)((((((diroffset + blsize)) >> ((pmp))->pm_cnshift)) <<
((pmp)->pm_cnshift - (pmp)->pm_bnshift)))
> pmp->pm_rootdirsize)
277 blsize = de_bn2off(pmp, pmp->pm_rootdirsize)((pmp->pm_rootdirsize) << (pmp)->pm_bnshift) & pmp->pm_crbomask;
278 bn = detobn(pmp, dirclust, diroffset)((dirclust) == 0 ? (((((((((diroffset)))) >> ((((pmp)))
)->pm_cnshift)) << ((((pmp)))->pm_cnshift - (((pmp
)))->pm_bnshift))) + ((pmp))->pm_rootdirblk) : (((((dirclust
))-2) << ((((pmp)))->pm_cnshift - (((pmp)))->pm_bnshift
)) + ((pmp))->pm_firstcluster))
;
279 if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)), blsize,
280 0, bpp)) != 0) {
281 *bpp = NULL((void*)0);
282 return (error);
283 }
284 if (epp)
285 *epp = bptoep(pmp, *bpp, diroffset)((struct direntry *)(((char *)(*bpp)->b_data) + ((diroffset
) & (pmp)->pm_crbomask)))
;
286 return (0);
287}
288
289/*
290 * Read in the disk block containing the directory entry dep came from and
291 * return the address of the buf header, and the address of the directory
292 * entry within the block.
293 */
294int
295readde(struct denode *dep, struct mkfsbuf **bpp, struct direntry **epp)
296{
297 return (readep(dep->de_pmp, dep->de_dirclustde_key.dk_dirclust, dep->de_diroffsetde_key.dk_diroffset,
298 bpp, epp));
299}
300
301/*
302 * Create a unique DOS name in dvp
303 */
304int
305uniqdosname(struct denode *dep, struct componentname *cnp, u_char *cp)
306{
307 struct msdosfsmount *pmp = dep->de_pmp;
308 struct direntry *dentp;
309 int gen;
310 int blsize;
311 u_long cn;
312 daddr_t bn;
313 struct mkfsbuf *bp;
314 int error;
315
316 for (gen = 1;; gen++) {
317 /*
318 * Generate DOS name with generation number
319 */
320 if (!unix2dosfn(cnp->cn_nameptr, cp, cnp->cn_namelen, gen))
321 return gen == 1 ? EINVAL22 : EEXIST17;
322
323 /*
324 * Now look for a dir entry with this exact name
325 */
326 for (cn = error = 0; !error; cn++) {
327 if ((error = pcbmap(dep, cn, &bn, 0, &blsize)) != 0) {
328 if (error == E2BIG7) /* EOF reached and not found */
329 return 0;
330 return error;
331 }
332 error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn)((bn) << ((pmp)->pm_bnshift - 9)), blsize,
333 0, &bp);
334 if (error) {
335 return error;
336 }
337 for (dentp = (struct direntry *)bp->b_data;
338 (char *)dentp < (char *)bp->b_data + blsize;
339 dentp++) {
340 if (dentp->deName[0] == SLOT_EMPTY0x00) {
341 /*
342 * Last used entry and not found
343 */
344 brelse(bp, 0);
345 return 0;
346 }
347 /*
348 * Ignore volume labels and Win95 entries
349 */
350 if (dentp->deAttributes & ATTR_VOLUME0x08)
351 continue;
352 if (!memcmp(dentp->deName, cp, 11)) {
353 error = EEXIST17;
354 break;
355 }
356 }
357 brelse(bp, 0);
358 }
359 }
360}