Mail Archives: djgpp-workers/2000/08/29/14:29:46
On Mon, 28 Aug 2000 23:47:27 +0200, you wrote:
> > To test the robustness of symify I was going to corrupt some .exe
> > file. Again, I am open to suggestions on this.
>
> Write a program which inserts a 0xA0000 pointer dereference at random
> points of another program's source?
Hmmm, I don't follow what you mean. I have added checking to the
symify code so that it now exits gracefully if the program _being_
_debugged_ is corrupt, (ie nonsense values in the COFF headers). It's
the new code in symify I would like to excercise.
So far this is achieved by producing a garbage file, editing the first
two bytes to be 4C 01, and supplying this to symify when it is run on
a stack dump. The new symify will print an error message and exit,
whereas the existing version will usually bomb.
Attached are three patches to syms.c:
1) Replace calls to malloc() with xmalloc()
2) Fix a minor (non-bug) problem with compiler warnings
3) Introduce four new functions, these are:
bail(): Prints an error message to stderr and quits.
xfseek(): Wrapper for fseek(), quits upon file error.
xfread(): Wrapper for fread(), quits upon file error.
xmalloc_fread(): Wrapper for a combined xmalloc()/xfread() operation.
Function names can change if someone will suggest better alternatives.
The patches assume that the official syms.c is already fixed with the
patch previously posted to c.o.m.d by Eli.
Patch 1 follows:
============================================================
--- src/debug/common/syms.c~1 Sun Aug 27 19:50:32 2000
+++ src/debug/common/syms.c Sun Aug 27 19:51:36 2000
@@ -32,6 +32,8 @@
#include <debug/stab.h>
#include <debug/wild.h>
+void *xmalloc (size_t);
+
int undefined_symbol=0;
int syms_printwhy=0;
@@ -127,8 +129,7 @@
static char *symndup(char *s, int len)
{
char *rv;
- if(!(rv = malloc(len+1)))
- return (char *)NULL;
+ rv = xmalloc(len+1);
memcpy(rv,s,len);
rv[len] = 0;
return rv;
@@ -162,9 +163,9 @@
fseek(fd, ofs, 0);
fread(&f_fh, 1, FILHSZ, fd);
fread(&f_ah, 1, AOUTSZ, fd);
- f_sh = (SCNHDR *)malloc(f_fh.f_nscns * SCNHSZ);
- f_types = (char *)malloc(f_fh.f_nscns);
- f_lnno = (LINENO **)malloc(f_fh.f_nscns * sizeof(LINENO *));
+ f_sh = (SCNHDR *)xmalloc(f_fh.f_nscns * SCNHSZ);
+ f_types = (char *)xmalloc(f_fh.f_nscns);
+ f_lnno = (LINENO **)xmalloc(f_fh.f_nscns * sizeof(LINENO *));
fread(f_sh, f_fh.f_nscns, SCNHSZ, fd);
for (i=0; i<f_fh.f_nscns; i++)
@@ -178,7 +179,7 @@
if (f_sh[i].s_nlnno)
{
fseek(fd, ofs + f_sh[i].s_lnnoptr, 0L);
- f_lnno[i] = (LINENO *)malloc(f_sh[i].s_nlnno * LINESZ);
+ f_lnno[i] = (LINENO *)xmalloc(f_sh[i].s_nlnno * LINESZ);
fread(f_lnno[i], LINESZ, f_sh[i].s_nlnno, fd);
}
else
@@ -187,14 +188,14 @@
fseek(fd, ofs + f_fh.f_symptr + f_fh.f_nsyms * SYMESZ, 0);
fread(&strsize, 1, 4, fd);
- f_string_table = (char *)malloc(strsize);
+ f_string_table = (char *)xmalloc(strsize);
/* CWS note: must zero or pukes below. Does not fill from file. */
memset(f_string_table,0,strsize);
fread(f_string_table+4, 1, strsize-4, fd);
f_string_table[0] = 0;
fseek(fd, ofs+f_fh.f_symptr, 0);
- f_symtab = (SYMENT *)malloc(f_fh.f_nsyms * SYMESZ);
+ f_symtab = (SYMENT *)xmalloc(f_fh.f_nsyms * SYMESZ);
fread(f_symtab, SYMESZ, f_fh.f_nsyms, fd);
f_aux = (AUXENT *)f_symtab;
@@ -216,9 +217,9 @@
i += f_symtab[i].e_numaux;
}
- files = (FileNode *)malloc(num_files * sizeof(FileNode));
+ files = (FileNode *)xmalloc(num_files * sizeof(FileNode));
- syms = (SymNode *)malloc(num_syms * sizeof(SymNode));
+ syms = (SymNode *)xmalloc(num_syms * sizeof(SymNode));
f = s = f_pending = l_pending = i2_max = 0;
for (i=0; i<f_fh.f_nsyms; i++)
@@ -329,11 +330,11 @@
fseek(fd, ofs + sizeof(header) + header.tsize + header.dsize + header.txrel + header.dtrel, 0);
nsyms = header.symsize / sizeof(SYM_ENTRY);
- f_aoutsyms = (SYM_ENTRY *)malloc(header.symsize);
+ f_aoutsyms = (SYM_ENTRY *)xmalloc(header.symsize);
fread(f_aoutsyms, 1, header.symsize, fd);
fread(&string_table_length, 1, 4, fd);
- f_string_table = (char *)malloc(string_table_length);
+ f_string_table = (char *)xmalloc(string_table_length);
fread(f_string_table+4, 1, string_table_length-4, fd);
f_string_table[0] = 0;
@@ -370,9 +371,9 @@
}
}
- syms = (SymNode *)malloc(num_syms * sizeof(SymNode));
+ syms = (SymNode *)xmalloc(num_syms * sizeof(SymNode));
memset(syms, 0, num_syms * sizeof(SymNode));
- files = (FileNode *)malloc(num_files * sizeof(FileNode));
+ files = (FileNode *)xmalloc(num_files * sizeof(FileNode));
memset(files, 0, num_files * sizeof(FileNode));
f = s = 0;
@@ -453,7 +454,7 @@
case N_SO:
if (symn[strlen(symn)-1] == '/')
break;
- files[f].lines = (LINENO *)malloc(files[f].num_lines * sizeof(LINENO));
+ files[f].lines = (LINENO *)xmalloc(files[f].num_lines * sizeof(LINENO));
f++;
l = 0;
break;
@@ -502,7 +503,7 @@
{
process_file(fd, 0);
- syms_byname = (SymNode *)malloc(num_syms * sizeof(SymNode));
+ syms_byname = (SymNode *)xmalloc(num_syms * sizeof(SymNode));
memcpy(syms_byname, syms, num_syms * sizeof(SymNode));
qsort(syms_byname, num_syms, sizeof(SymNode), syms_sort_bn);
qsort(syms, num_syms, sizeof(SymNode), syms_sort_bv);
Patch 2 follows:
============================================================
--- src/debug/common/syms.c~2 Sun Aug 27 19:56:32 2000
+++ src/debug/common/syms.c Mon Aug 28 13:14:54 2000
@@ -153,7 +153,8 @@
static void process_coff(FILE *fd, long ofs)
{
- int i, f, s, f_pending;
+ unsigned int i;
+ int f, s, f_pending;
LINENO *l = NULL; /* CWS note: uninitialized? */
int l_pending;
unsigned long strsize;
Patch 3 follows:
============================================================
--- src/debug/common/syms.c~3 Mon Aug 28 13:16:18 2000
+++ src/debug/common/syms.c Mon Aug 28 23:24:56 2000
@@ -32,6 +32,8 @@
#include <debug/stab.h>
#include <debug/wild.h>
+#include <assert.h>
+
void *xmalloc (size_t);
int undefined_symbol=0;
@@ -151,6 +153,74 @@
return 1;
}
+/* bail(): Print MSG to stderr and quit */
+static void bail(const char *msg)
+{
+ assert(msg);
+
+ fprintf(stderr, "SYMIFY ERROR: %s\n", msg);
+ exit(EXIT_FAILURE);
+}
+
+/* xfseek(): Move the file pointer for FILE according to MODE,
+ * print an error message and bailout if the file operation fails.
+ * Return: 0 (success) always.
+ */
+static int xfseek(FILE *stream, long offset, int mode)
+{
+ assert(stream);
+ assert((mode==SEEK_SET) || (mode==SEEK_CUR) || (mode==SEEK_END));
+
+ /* Note that fseek's past the end of file will not fail in dos. */
+
+ if (fseek(stream, offset, mode))
+ bail("fseek failed");
+
+ return 0;
+}
+
+/* xfread(): Read NUMBER of objects, each of SIZE bytes, from FILE to BUFFER.
+ * print an error message and bailout if the file operation fails, or if less
+ * than NUMBER*SIZE bytes were read.
+ * Return: NUMBER always.
+ */
+static size_t xfread(void *buffer, size_t size, size_t number, FILE *stream)
+{
+ assert(buffer);
+ assert(stream);
+
+ if (fread(buffer, size, number, stream) == number)
+ return number;
+ else if (feof(stream))
+ bail("unexpected end of file");
+ else if (ferror(stream))
+ bail("error reading from file");
+ else
+ bail("fread failed");
+
+ return 0; /* dummy return */
+}
+
+/* xmalloc_fread(): Allocate a memory buffer to store NUMBER of objects,
+ * each of SIZE bytes, then fill the buffer by reading from FILE.
+ * print an error message and bailout if not enough memory available to
+ * allocate the buffer, or if a file error occurs, or if not enough bytes
+ * are read to fill the buffer.
+ * Return: a pointer to the newly allocated buffer.
+ */
+static void *xmalloc_fread(size_t size, size_t number, FILE *stream)
+{
+ void *buffer;
+
+ assert(stream);
+
+ buffer = xmalloc(size * number);
+
+ xfread(buffer, size, number, stream);
+
+ return buffer;
+}
+
static void process_coff(FILE *fd, long ofs)
{
unsigned int i;
@@ -161,13 +231,12 @@
char *name;
int i2_max;
- fseek(fd, ofs, 0);
- fread(&f_fh, 1, FILHSZ, fd);
- fread(&f_ah, 1, AOUTSZ, fd);
- f_sh = (SCNHDR *)xmalloc(f_fh.f_nscns * SCNHSZ);
+ xfseek(fd, ofs, 0);
+ xfread(&f_fh, FILHSZ, 1, fd);
+ xfread(&f_ah, AOUTSZ, 1, fd);
+ f_sh = xmalloc_fread(SCNHSZ, f_fh.f_nscns, fd);
f_types = (char *)xmalloc(f_fh.f_nscns);
f_lnno = (LINENO **)xmalloc(f_fh.f_nscns * sizeof(LINENO *));
- fread(f_sh, f_fh.f_nscns, SCNHSZ, fd);
for (i=0; i<f_fh.f_nscns; i++)
{
@@ -179,25 +248,23 @@
f_types[i] = 'B';
if (f_sh[i].s_nlnno)
{
- fseek(fd, ofs + f_sh[i].s_lnnoptr, 0L);
- f_lnno[i] = (LINENO *)xmalloc(f_sh[i].s_nlnno * LINESZ);
- fread(f_lnno[i], LINESZ, f_sh[i].s_nlnno, fd);
+ xfseek(fd, ofs + f_sh[i].s_lnnoptr, 0L);
+ f_lnno[i] = xmalloc_fread(LINESZ, f_sh[i].s_nlnno, fd);
}
else
f_lnno[i] = 0;
}
- fseek(fd, ofs + f_fh.f_symptr + f_fh.f_nsyms * SYMESZ, 0);
- fread(&strsize, 1, 4, fd);
+ xfseek(fd, ofs + f_fh.f_symptr + f_fh.f_nsyms * SYMESZ, 0);
+ xfread(&strsize, 4, 1, fd);
f_string_table = (char *)xmalloc(strsize);
/* CWS note: must zero or pukes below. Does not fill from file. */
memset(f_string_table,0,strsize);
- fread(f_string_table+4, 1, strsize-4, fd);
+ xfread(f_string_table+4, 1, strsize-4, fd);
f_string_table[0] = 0;
- fseek(fd, ofs+f_fh.f_symptr, 0);
- f_symtab = (SYMENT *)xmalloc(f_fh.f_nsyms * SYMESZ);
- fread(f_symtab, SYMESZ, f_fh.f_nsyms, fd);
+ xfseek(fd, ofs+f_fh.f_symptr, 0);
+ f_symtab = xmalloc_fread(SYMESZ, f_fh.f_nsyms, fd);
f_aux = (AUXENT *)f_symtab;
num_syms = num_files = 0;
@@ -326,17 +393,16 @@
unsigned long string_table_length;
int nsyms, i, f, s, l;
- fseek(fd, ofs, 0);
- fread(&header, 1, sizeof(header), fd);
+ xfseek(fd, ofs, 0);
+ xfread(&header, sizeof(header), 1, fd);
- fseek(fd, ofs + sizeof(header) + header.tsize + header.dsize + header.txrel + header.dtrel, 0);
+ xfseek(fd, ofs + sizeof(header) + header.tsize + header.dsize + header.txrel + header.dtrel, 0);
nsyms = header.symsize / sizeof(SYM_ENTRY);
- f_aoutsyms = (SYM_ENTRY *)xmalloc(header.symsize);
- fread(f_aoutsyms, 1, header.symsize, fd);
+ f_aoutsyms = xmalloc_fread(header.symsize, 1, fd);
- fread(&string_table_length, 1, 4, fd);
+ xfread(&string_table_length, 4, 1, fd);
f_string_table = (char *)xmalloc(string_table_length);
- fread(f_string_table+4, 1, string_table_length-4, fd);
+ xfread(f_string_table+4, 1, string_table_length-4, fd);
f_string_table[0] = 0;
num_files = num_syms = 0;
@@ -472,12 +538,12 @@
static void process_file(FILE *fd, long ofs)
{
short s, exe[2];
- fseek(fd, ofs, 0);
- fread(&s, 1, 2, fd);
+ xfseek(fd, ofs, 0);
+ xfread(&s, 2, 1, fd);
switch (s)
{
case 0x5a4d: /* .exe */
- fread(exe, 2, 2, fd);
+ xfread(exe, 2, 2, fd);
ofs += (long)exe[1] * 512L;
if (exe[0])
ofs += (long)exe[0] - 512L;
--
[please cc all replies, thanks]
- Raw text -