ref: 3e124e1f13b945a020d973052069b9d3b673d814
parent: ce76af64fe93cfe5103cf9b5f44693d8aebef24c
author: cinap_lenrek <[email protected]>
date: Sun May 31 08:58:13 EDT 2015
libdisk: error handling, sanity checks - make sure disk file is an actual file and not a directory, log or empty file - sanity check: file has to be at least one sector to be a disk - simplify error handling using freedisk()
--- a/sys/src/libdisk/disk.c
+++ b/sys/src/libdisk/disk.c
@@ -209,14 +209,25 @@
}
static Disk*
+freedisk(Disk *d)
+{
+ if(d->fd >= 0)
+ close(d->fd);
+ if(d->wfd >= 0)
+ close(d->wfd);
+ if(d->ctlfd >= 0)
+ close(d->ctlfd);
+ free(d);
+ return nil;
+}
+
+static Disk*
openfile(Disk *disk)
{
Dir *d;
- if((d = dirfstat(disk->fd)) == nil){
- free(disk);
- return nil;
- }
+ if((d = dirfstat(disk->fd)) == nil)
+ return freedisk(disk);
disk->secsize = 512;
disk->size = d->length;
@@ -224,6 +235,11 @@
disk->offset = 0;
free(d);
+ if(disk->secs == 0){
+ werrstr("file too small to be a disk");
+ return freedisk(disk);
+ }
+
findgeometry(disk);
return mkwidth(disk);
}
@@ -274,6 +290,7 @@
{
char *p, *q;
Disk *d;
+ Dir *s;
d = mallocz(sizeof(*d), 1);
if(d == nil)
@@ -284,10 +301,17 @@
d->fd = open(disk, OREAD);
if(d->fd < 0) {
- werrstr("cannot open disk file");
- free(d);
- return nil;
+ werrstr("cannot open disk file: %r");
+ return freedisk(d);
}
+ if((s = dirfstat(d->fd)) == nil)
+ return freedisk(d);
+ if((s->mode & (DMDIR|DMAPPEND)) != 0){
+ free(s);
+ werrstr("not a disk file: %s", disk);
+ return freedisk(d);
+ }
+ free(s);
if(rdonly == 0) {
d->wfd = open(disk, OWRITE);
@@ -299,12 +323,8 @@
return openfile(d);
p = malloc(strlen(disk) + 4); /* 4: slop for "ctl\0" */
- if(p == nil) {
- close(d->wfd);
- close(d->fd);
- free(d);
- return nil;
- }
+ if(p == nil)
+ return freedisk(d);
strcpy(p, disk);
/* check for floppy(3) disk */
@@ -334,12 +354,8 @@
d->type = Tsd;
d->part = strdup(disk+(q-p));
if(d->part == nil){
- close(d->ctlfd);
- close(d->wfd);
- close(d->fd);
free(p);
- free(d);
- return nil;
+ return freedisk(d);
}
return opensd(d);
}