delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/08/29/14:29:46

From: Jason Green <mail AT jgreen4 DOT fsnet DOT co DOT uk>
To: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
Cc: djgpp-workers AT delorie DOT com
Subject: Re: Symify fixes
Date: Tue, 29 Aug 2000 19:27:08 +0100
Message-ID: <ttvnqs0p0rib0eja7eiijst64vbgp9tl1b@4ax.com>
References: <226lqssqgqp6i9nk82rvrqhl9aaia029e9 AT 4ax DOT com> <7458-Mon28Aug2000203504+0300-eliz AT is DOT elta DOT co DOT il> <ltflqs8ouggncaukmesirq7rsbsi4umrj5 AT 4ax DOT com> <8011-Mon28Aug2000234727+0300-eliz AT is DOT elta DOT co DOT il>
In-Reply-To: <8011-Mon28Aug2000234727+0300-eliz@is.elta.co.il>
X-Mailer: Forte Agent 1.7/32.534
MIME-Version: 1.0
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id OAA07815
Reply-To: djgpp-workers AT delorie DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019