Subject: fixes for size(1) and strip(1)
To: netbsd-current-users <current-users@sun-lamp.cs.berkeley.edu>
From: Mats Wichmann <mats@netcom.com>
List: current-users
Date: 11/18/1993 12:04:14
Here are some fixes to size(1) and strip(1):

1.  size(1) forgets to close the file when it detects a bad one.
2.  strip(1) shouldn't abort when processing a file and it detects
    an error (rationale: nm and size don't do this either).
3.  strip(1) doesn't free the memory it has allocated.
4.  added a very simple minded check so strip(1) doesn't dump core on
    bad files.

*** usr.bin/size/size.c-	Sun Nov  7 11:09:53 1993
--- usr.bin/size/size.c	Thu Nov 18 20:22:52 1993
***************
*** 97,102 ****
--- 97,103 ----
  	}
  	if (read(fd, &head, sizeof(head)) != sizeof(head) || N_BADMAG(head)) {
  		err("%s: not in a.out format", name);
+ 		(void)close(fd);
  		return (1);
  	}
  	(void)close(fd);
*** usr.bin/strip/strip.c-	Sun Nov  7 11:10:06 1993
--- usr.bin/strip/strip.c	Thu Nov 18 21:14:37 1993
***************
*** 59,66 ****
  #define	strx	n_un.n_strx
  
  void err __P((const char *fmt, ...));
! void s_stab __P((const char *, int, EXEC *));
! void s_sym __P((const char *, int, EXEC *));
  void usage __P((void));
  
  int xflag = 0;
--- 59,66 ----
  #define	strx	n_un.n_strx
  
  void err __P((const char *fmt, ...));
! int s_stab __P((const char *, int, EXEC *));
! int s_sym __P((const char *, int, EXEC *));
  void usage __P((void));
  
  int xflag = 0;
***************
*** 71,78 ****
  {
  	register int fd, nb;
  	EXEC head;
! 	void (*sfcn)__P((const char *, int, EXEC *));
! 	int ch;
  	char *fn;
  
  	sfcn = s_sym;
--- 71,78 ----
  {
  	register int fd, nb;
  	EXEC head;
! 	int (*sfcn)__P((const char *, int, EXEC *));
! 	int ch, errors;
  	char *fn;
  
  	sfcn = s_sym;
***************
*** 91,114 ****
  	argc -= optind;
  	argv += optind;
  
  	while (fn = *argv++) {
! 		if ((fd = open(fn, O_RDWR)) < 0 ||
! 		    (nb = read(fd, &head, sizeof(EXEC))) == -1) {
  			err("%s: %s", fn, strerror(errno));
  			continue;
  		}
  		if (nb != sizeof(EXEC) || N_BADMAG(head)) {
  			err("%s: %s", fn, strerror(EFTYPE));
  			continue;
  		}
! 		sfcn(fn, fd, &head);
! 		if (close(fd))
  			err("%s: %s", fn, strerror(errno));
  	}
! 	exit(0);
  }
  
! void
  s_sym(fn, fd, ep)
  	const char *fn;
  	int fd;
--- 91,125 ----
  	argc -= optind;
  	argv += optind;
  
+ 	errors = 0;
  	while (fn = *argv++) {
! 		if ((fd = open(fn, O_RDWR)) < 0) {
! 			errors |= 1;
  			err("%s: %s", fn, strerror(errno));
  			continue;
  		}
+ 		if ((nb = read(fd, &head, sizeof(EXEC))) == -1) {
+ 			errors |= 1;
+ 			err("%s: %s", fn, strerror(errno));
+ 			(void)close(fd);
+ 			continue;
+ 		}
  		if (nb != sizeof(EXEC) || N_BADMAG(head)) {
+ 			errors |= 1;
  			err("%s: %s", fn, strerror(EFTYPE));
+ 			(void)close(fd);
  			continue;
  		}
! 		errors |= sfcn(fn, fd, &head);
! 		if (close(fd)) {
! 			errors |= 1;
  			err("%s: %s", fn, strerror(errno));
+ 		}
  	}
! 	exit(errors);
  }
  
! int
  s_sym(fn, fd, ep)
  	const char *fn;
  	int fd;
***************
*** 118,124 ****
  
  	/* If no symbols or data/text relocation info, quit. */
  	if (!ep->a_syms && !ep->a_trsize && !ep->a_drsize)
! 		return;
  
  	/*
  	 * New file size is the header plus text and data segments; OMAGIC
--- 129,135 ----
  
  	/* If no symbols or data/text relocation info, quit. */
  	if (!ep->a_syms && !ep->a_trsize && !ep->a_drsize)
! 		return 0;
  
  	/*
  	 * New file size is the header plus text and data segments; OMAGIC
***************
*** 133,143 ****
  	/* Rewrite the header and truncate the file. */
  	if (lseek(fd, 0L, SEEK_SET) == -1 ||
  	    write(fd, ep, sizeof(EXEC)) != sizeof(EXEC) ||
! 	    ftruncate(fd, fsize))
  		err("%s: %s", fn, strerror(errno)); 
  }
  
! void
  s_stab(fn, fd, ep)
  	const char *fn;
  	int fd;
--- 144,157 ----
  	/* Rewrite the header and truncate the file. */
  	if (lseek(fd, 0L, SEEK_SET) == -1 ||
  	    write(fd, ep, sizeof(EXEC)) != sizeof(EXEC) ||
! 	    ftruncate(fd, fsize)) {
  		err("%s: %s", fn, strerror(errno)); 
+ 		return 1;
+ 	}
+ 	return 0;
  }
  
! int
  s_stab(fn, fd, ep)
  	const char *fn;
  	int fd;
***************
*** 151,163 ****
  
  	/* Quit if no symbols. */
  	if (ep->a_syms == 0)
! 		return;
  
  	/* Map the file. */
  	if (fstat(fd, &sb) ||
  	    (ep = (EXEC *)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
! 	    MAP_FILE | MAP_SHARED, fd, (off_t)0)) == (EXEC *)-1)
  		err("%s: %s", fn, strerror(errno));
  
  	/*
  	 * Initialize old and new symbol pointers.  They both point to the
--- 165,185 ----
  
  	/* Quit if no symbols. */
  	if (ep->a_syms == 0)
! 		return 0;
  
  	/* Map the file. */
  	if (fstat(fd, &sb) ||
  	    (ep = (EXEC *)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
! 	    MAP_FILE | MAP_SHARED, fd, (off_t)0)) == (EXEC *)-1) {
  		err("%s: %s", fn, strerror(errno));
+ 		return 1;
+ 	}
+ 
+ 	if (N_SYMOFF(*ep) >= sb.st_size) {
+ 		err("%s: bad symbol table", fn);
+ 		munmap((caddr_t)ep, sb.st_size);
+ 		return 1;
+ 	}
  
  	/*
  	 * Initialize old and new symbol pointers.  They both point to the
***************
*** 172,179 ****
  	 * of the string table.
  	 */
  	strbase = (char *)ep + N_STROFF(*ep);
! 	if ((nstrbase = malloc((u_int)*(u_long *)strbase)) == NULL)
! 		err("%s", strerror(errno));
  	nstr = nstrbase + sizeof(u_long);
  
  	/*
--- 194,204 ----
  	 * of the string table.
  	 */
  	strbase = (char *)ep + N_STROFF(*ep);
! 	if ((nstrbase = malloc((u_int)*(u_long *)strbase)) == NULL) {
! 		err("%s", strerror(ENOMEM));
! 		munmap((caddr_t)ep, sb.st_size);
! 		return 1;
! 	}
  	nstr = nstrbase + sizeof(u_long);
  
  	/*
***************
*** 191,197 ****
                               (sym->n_type & ~N_EXT) == N_FN ||
                               strcmp(p, "gcc_compiled.") == 0 ||
                               strcmp(p, "gcc2_compiled.") == 0 ||
!                              strcmp(p, "___gnu_compiled_c") == 0)) {
                                  continue;
                          }
  			len = strlen(p) + 1;
--- 216,222 ----
                               (sym->n_type & ~N_EXT) == N_FN ||
                               strcmp(p, "gcc_compiled.") == 0 ||
                               strcmp(p, "gcc2_compiled.") == 0 ||
!                              strncmp(p, "___gnu_compiled_", 16) == 0)) {
                                  continue;
                          }
  			len = strlen(p) + 1;
***************
*** 211,227 ****
  	 * at the address past the last symbol entry.
  	 */
  	bcopy(nstrbase, (void *)nsym, len);
  
  	/* Truncate to the current length. */
! 	if (ftruncate(fd, (char *)nsym + len - (char *)ep))
  		err("%s: %s", fn, strerror(errno));
  	munmap((caddr_t)ep, sb.st_size);
  }
  
  void
  usage()
  {
! 	(void)fprintf(stderr, "usage: strip [-d] file ...\n");
  	exit(1);
  }
  
--- 236,258 ----
  	 * at the address past the last symbol entry.
  	 */
  	bcopy(nstrbase, (void *)nsym, len);
+ 	free(nstrbase);
  
  	/* Truncate to the current length. */
! 	if (ftruncate(fd, (char *)nsym + len - (char *)ep)) {
! 		munmap((caddr_t)ep, sb.st_size);
  		err("%s: %s", fn, strerror(errno));
+ 		return 1;
+ 	}
+ 
  	munmap((caddr_t)ep, sb.st_size);
+ 	return 0;
  }
  
  void
  usage()
  {
! 	(void)fprintf(stderr, "usage: strip [-dx] file ...\n");
  	exit(1);
  }
  
***************
*** 250,254 ****
  	(void)vfprintf(stderr, fmt, ap);
  	va_end(ap);
  	(void)fprintf(stderr, "\n");
- 	exit(1);
  }
--- 281,284 ----

-- 
thomas@mathematik.uni-Bremen.de | Centrum fuer Complexe Systeme & Visualisierung
Thomas Eberhardt                | Universitaet Bremen, FB 3, Bibliothekstr. 1
Koelner Str. 4, D-28327 Bremen  | D-28359 Bremen, Germany
Home Phone: +49 421 472527      | FAX: +49 421 218-4236, Office: 218-4823

------------------------------------------------------------------------------