Subject: loadfile_*() returns an incorrect errno?
To: None <tech-install@NetBSD.org>
From: Tetsuya Isaki <isaki@par.odn.ne.jp>
List: tech-install
Date: 11/18/2007 16:58:02
In fdloadfile() (in sys/lib/libsa/loadfile.c),
loadfile_*() returns -1 and sets global variable errno,
if error happened. But loadfile_*() returns -1 without
setting errno, if read() is short.
Therefore, fdloadfile() may return error code 0 (= success)
when read() in loadfile_*() is short.
I think that loadfile_*() should always set errno when
returns -1. So, how about the attached patch? But I'm
not sure whether ESHORT is good.
P.S. May I do a style fix in sys/lib/libsa?
---
Tetsuya Isaki <isaki@par.odn.ne.jp / isaki@NetBSD.org>
Index: sys/lib/libsa/loadfile_aout.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/loadfile_aout.c,v
retrieving revision 1.9
diff -u -r1.9 loadfile_aout.c
--- sys/lib/libsa/loadfile_aout.c 5 Jun 2007 08:48:50 -0000 1.9
+++ sys/lib/libsa/loadfile_aout.c 10 Nov 2007 12:49:50 -0000
@@ -105,6 +105,7 @@
paddr_t offset = marks[MARK_START];
u_long magic = N_GETMAGIC(*x);
int sub;
+ ssize_t nr;
/* some ports dont use the offset */
offset = offset;
@@ -144,8 +145,13 @@
if (flags & LOAD_TEXT) {
PROGRESS(("%ld", x->a_text));
- if (READ(fd, maxp, x->a_text - sub) !=
- (ssize_t)(x->a_text - sub)) {
+ nr = READ(fd, maxp, x->a_text - sub);
+ if (nr == -1) {
+ WARN(("read text"));
+ return 1;
+ }
+ if (nr != (ssize_t)(x->a_text - sub)) {
+ errno = ESHORT;
WARN(("read text"));
return 1;
}
@@ -180,7 +186,13 @@
PROGRESS(("+%ld", x->a_data));
marks[MARK_DATA] = LOADADDR(maxp);
- if (READ(fd, maxp, x->a_data) != (ssize_t)x->a_data) {
+ nr = READ(fd, maxp, x->a_data);
+ if (nr == -1) {
+ WARN(("read data"));
+ return 1;
+ }
+ if (nr != (ssize_t)x->a_data) {
+ errno = ESHORT;
WARN(("read data"));
return 1;
}
@@ -225,7 +237,13 @@
if (flags & LOAD_SYM) {
PROGRESS(("+[%ld", x->a_syms));
- if (READ(fd, maxp, x->a_syms) != (ssize_t)x->a_syms) {
+ nr = READ(fd, maxp, x->a_syms);
+ if (nr == -1) {
+ WARN(("read symbols"));
+ return 1;
+ }
+ if (nr != (ssize_t)x->a_syms) {
+ errno = ESHORT;
WARN(("read symbols"));
return 1;
}
@@ -238,7 +256,13 @@
if (flags & (LOAD_SYM|COUNT_SYM))
maxp += x->a_syms;
- if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
+ nr = read(fd, &cc, sizeof(cc));
+ if (nr == -1) {
+ WARN(("read string table"));
+ return 1;
+ }
+ if (nr != sizeof(cc)) {
+ errno = ESHORT;
WARN(("read string table"));
return 1;
}
@@ -260,7 +284,13 @@
}
if (flags & LOAD_SYM) {
- if (READ(fd, maxp, cc) != cc) {
+ nr = READ(fd, maxp, cc);
+ if (nr == -1) {
+ WARN(("read strings"));
+ return 1;
+ }
+ if (nr != cc) {
+ errno = ESHORT;
WARN(("read strings"));
return 1;
}
Index: sys/lib/libsa/loadfile_ecoff.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/loadfile_ecoff.c,v
retrieving revision 1.8
diff -u -r1.8 loadfile_ecoff.c
--- sys/lib/libsa/loadfile_ecoff.c 6 Jun 2007 07:56:39 -0000 1.8
+++ sys/lib/libsa/loadfile_ecoff.c 10 Nov 2007 12:49:50 -0000
@@ -66,6 +66,7 @@
{
paddr_t offset = marks[MARK_START];
paddr_t minp = ~0, maxp = 0, pos;
+ ssize_t nr;
/* some ports dont use the offset */
offset = offset;
@@ -79,8 +80,12 @@
if (coff->a.tsize != 0) {
if (flags & LOAD_TEXT) {
PROGRESS(("%lu", coff->a.tsize));
- if (READ(fd, coff->a.text_start, coff->a.tsize) !=
- coff->a.tsize) {
+ nr = READ(fd, coff->a.text_start, coff->a.tsize);
+ if (nr == -1) {
+ return 1;
+ }
+ if (nr != coff->a.tsize) {
+ errno = ESHORT;
return 1;
}
}
@@ -104,8 +109,13 @@
if (coff->a.dsize != 0) {
if (flags & LOAD_DATA) {
PROGRESS(("+%lu", coff->a.dsize));
- if (READ(fd, coff->a.data_start, coff->a.dsize) !=
- coff->a.dsize) {
+ nr = READ(fd, coff->a.data_start, coff->a.dsize);
+ if (nr == -1) {
+ WARN(("read data"));
+ return 1;
+ }
+ if (nr != coff->a.dsize) {
+ errno = ESHORT;
WARN(("read data"));
return 1;
}
Index: sys/lib/libsa/loadfile_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/loadfile_elf32.c,v
retrieving revision 1.17
diff -u -r1.17 loadfile_elf32.c
--- sys/lib/libsa/loadfile_elf32.c 5 Jun 2007 08:48:50 -0000 1.17
+++ sys/lib/libsa/loadfile_elf32.c 10 Nov 2007 12:49:50 -0000
@@ -276,6 +276,7 @@
int first;
paddr_t minp = ~0, maxp = 0, pos = 0;
paddr_t offset = marks[MARK_START], shpp, elfp = 0;
+ ssize_t nr;
/* some ports dont use the offset */
offset = offset;
@@ -289,7 +290,13 @@
WARN(("lseek phdr"));
goto freephdr;
}
- if (read(fd, phdr, sz) != sz) {
+ nr = read(fd, phdr, sz);
+ if (nr == -1) {
+ WARN(("read program headers"));
+ goto freephdr;
+ }
+ if (nr != sz) {
+ errno = ESHORT;
WARN(("read program headers"));
goto freephdr;
}
@@ -329,8 +336,13 @@
WARN(("lseek text"));
goto freephdr;
}
- if (READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz) !=
- (ssize_t)phdr[i].p_filesz) {
+ nr = READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz);
+ if (nr == -1) {
+ WARN(("read text error"));
+ goto freephdr;
+ }
+ if (nr != (ssize_t)phdr[i].p_filesz) {
+ errno = ESHORT;
WARN(("read text"));
goto freephdr;
}
@@ -380,7 +392,13 @@
shp = ALLOC(sz);
- if (read(fd, shp, sz) != sz) {
+ nr = read(fd, shp, sz);
+ if (nr == -1) {
+ WARN(("read section headers"));
+ goto freeshp;
+ }
+ if (nr != sz) {
+ errno = ESHORT;
WARN(("read section headers"));
goto freeshp;
}
@@ -422,8 +440,13 @@
WARN(("lseek symbols"));
goto freeshp;
}
- if (READ(fd, maxp, shp[i].sh_size) !=
- (ssize_t)shp[i].sh_size) {
+ nr = READ(fd, maxp, shp[i].sh_size);
+ if (nr == -1) {
+ WARN(("read symbols"));
+ goto freeshp;
+ }
+ if (nr != (ssize_t)shp[i].sh_size) {
+ errno = ESHORT;
WARN(("read symbols"));
goto freeshp;
}
Index: sys/lib/libsa/saerrno.h
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/saerrno.h,v
retrieving revision 1.9
diff -u -r1.9 saerrno.h
--- sys/lib/libsa/saerrno.h 11 Dec 2005 12:24:46 -0000 1.9
+++ sys/lib/libsa/saerrno.h 10 Nov 2007 12:49:50 -0000
@@ -48,4 +48,5 @@
#define EWCK (ELAST+10) /* write check error */
#define EECC (ELAST+11) /* uncorrectable ecc error */
#define EHER (ELAST+12) /* hard error */
-#define ESALAST (ELAST+12) /* */
+#define ESHORT (ELAST+13) /* short read */
+#define ESALAST (ELAST+13) /* */