diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-01 15:17:08 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-05-01 15:17:08 +0000 |
commit | c512cf16e5e0d40d559688e6706696f82182a693 (patch) | |
tree | 58e4693bf79fbf8418b29d9f10ff44e6492cb08a /sys/src/cmd/dossrv | |
parent | 88181e1c5c8d19e61c76b93620abcbc7c2e57481 (diff) |
dossrv: better error handling and sanity checking in dosfs()
check error for devread() and do some sanity checking
on the constants and dont leak the Dosbpb when error.
Diffstat (limited to 'sys/src/cmd/dossrv')
-rw-r--r-- | sys/src/cmd/dossrv/dosfs.c | 9 | ||||
-rw-r--r-- | sys/src/cmd/dossrv/dossubs.c | 52 | ||||
-rw-r--r-- | sys/src/cmd/dossrv/xfile.c | 2 |
3 files changed, 43 insertions, 20 deletions
diff --git a/sys/src/cmd/dossrv/dosfs.c b/sys/src/cmd/dossrv/dosfs.c index 3acd0ea33..51aa6191a 100644 --- a/sys/src/cmd/dossrv/dosfs.c +++ b/sys/src/cmd/dossrv/dosfs.c @@ -45,9 +45,12 @@ rattach(void) root->xf = xf = getxfs(req->uname, req->aname); if(!xf) goto error; - if(xf->fmt == 0 && dosfs(xf) < 0){ - errno = Eformat; - goto error; + if(xf->fmt == 0){ + if(dosfs(xf) < 0){ + errno = Eformat; + goto error; + } + xf->fmt = 1; } root->qid.type = QTDIR; root->qid.path = 0; diff --git a/sys/src/cmd/dossrv/dossubs.c b/sys/src/cmd/dossrv/dossubs.c index eaabcd8bb..00b65ae00 100644 --- a/sys/src/cmd/dossrv/dossubs.c +++ b/sys/src/cmd/dossrv/dossubs.c @@ -41,7 +41,7 @@ dosfs(Xfs *xf) { Iosect *p1; Fatinfo *fi; - uchar buf[512]; + uchar buf[512]; Dosboot *b; Dosboot32 *b32; Dosbpb *bp; @@ -73,28 +73,31 @@ dosfs(Xfs *xf) isdos['&'] = 1; } - /* don't use getsect() before we we determinted real values */ - xf->sectsize = 512; - xf->sect2trk = 9; - devread(xf, 0, buf, sizeof(buf)); + /* don't use getsect() before determining sector size */ + if(devread(xf, 0, buf, sizeof(buf)) < 0) + return -1; if(!isdosfs(buf)) return -1; - b = (Dosboot*)buf; - - xf->sectsize = GSHORT(b->sectsize); - if(xf->sectsize < 32) + bp = malloc(sizeof(Dosbpb)); + if(bp == nil) return -1; + memset(bp, 0, sizeof(Dosbpb)); /* clear lock */ + b = (Dosboot*)buf; + xf->sectsize = GSHORT(b->sectsize); + if(xf->sectsize < 32){ + if(chatty) + fprint(2, "sectsize %d\n", xf->sectsize); + goto badfmt; + } xf->sect2trk = GSHORT(b->trksize); - if(xf->sect2trk < 1) - return -1; - - bp = malloc(sizeof(Dosbpb)); - memset(bp, 0, sizeof(Dosbpb)); /* clear lock */ - xf->ptr = bp; - xf->fmt = 1; + if(xf->sect2trk == 0){ + if(chatty) + fprint(2, "sect2trk %d\n", xf->sect2trk); + goto badfmt; + } bp->clustsize = b->clustsize; bp->nresrv = GSHORT(b->nresrv); bp->nfats = b->nfats; @@ -117,7 +120,7 @@ dosfs(Xfs *xf) if(bp->fatsize == 0){ if(chatty) fprint(2, "fatsize 0\n"); - return -1; + goto badfmt; } bp->dataaddr = bp->fataddr + bp->nfats*bp->fatsize; bp->rootaddr = 0; @@ -164,6 +167,16 @@ dosfs(Xfs *xf) bp->dataaddr = bp->rootaddr + (bp->rootsize*DOSDIRSIZE + xf->sectsize-1)/xf->sectsize; bp->freeptr = FATRESRV; } + if(bp->clustsize == 0){ + if(chatty) + fprint(2, "clustsize 0\n"); + goto badfmt; + } + if(bp->volsize < bp->dataaddr){ + if(chatty) + fprint(2, "volsize < dataaddr\n"); + goto badfmt; + } bp->fatclusters = FATRESRV + (bp->volsize - bp->dataaddr)/bp->clustsize; if(xf->isfat32) @@ -178,7 +191,12 @@ dosfs(Xfs *xf) chat("fat %d: %lld...", i, bp->fataddr+i*bp->fatsize); chat("root: %lld...", bp->rootaddr); chat("data: %lld...", bp->dataaddr); + + xf->ptr = bp; return 0; +badfmt: + free(bp); + return -1; } /* diff --git a/sys/src/cmd/dossrv/xfile.c b/sys/src/cmd/dossrv/xfile.c index 5a4c4c1f1..4855b7ac1 100644 --- a/sys/src/cmd/dossrv/xfile.c +++ b/sys/src/cmd/dossrv/xfile.c @@ -109,6 +109,8 @@ getxfs(char *user, char *name) fxf->qid = dqid; fxf->dev = fd; fxf->fmt = 0; + fxf->sectsize = 0; + fxf->sect2trk = 0; fxf->offset = offset; fxf->ptr = nil; fxf->isfat32 = 0; |