Subject: Opus 400 - ld misses a couple overflow checks (#400) Index: bin/ld.c 2.11BSD Description: The linker ('ld') fails to print an error in some cases when the base segment of an overlaid program (or kernel) overflows 64kb. Repeat-By: Place too many drivers into the base segment of the kernel. If the size of the kernel base segment wraps 64kb no error will be given by 'ld'. Rather 'netbind' (which performs the symbol cross checking between the kernel and networking images) will print out many undefined symbols with garbage names. Fix: Tim Shoppa encountered this problem and provided the fix. There were two places in 'ld' which were missing the check for the base segment size overflowing. 'ld' would catch those size errors which caused the base segment to be between 56kb and 64kb but the checks for the size wrapping around 64k (0) were missing. Not content to simply fix ld.c (and this being update #400 which I felt called for at least a little extra effort on my part ;-)) the data size of 'ld' was reduced by rearranging the error message strings passed to the 'add()' function. Also, to continue the migration of the manpages (to the source directory of the program they belong to) the manpage for ld(1) was moved into the ld/ source directory. Originally there were plans for a more elaborate "celebration" of "Opus 400" (the 400th update to 2.11 since its release) but alas, dealing with SoilRus at work has drained the creative effort lately on the 2BSD front. Perhaps later in the year 2.11 will receive the attention it deserves. To install this update cut where indicated, saving to a file (/tmp/400) and then: cd /tmp sh 400 patch -p0 < 400.patch chmod +x 400.sh ./400.sh 400.sh is a one line shell script which relocates 'ld.1' from the /usr/src/man/man1 directory to the src/bin/ld directory - you can, if so inclined simply run the 'mv' manually. Then: cd /usr/src/bin/ld make clean make install make clean As always this and previous updates to 2.11BSD are available via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. =============================cut here============================= #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # 400.patch # 400.sh # This archive created: Sat Jan 24 22:14:20 1998 export PATH; PATH=/bin:/usr/bin:$PATH if test -f '400.patch' then echo shar: "will not over-write existing file '400.patch'" else sed 's/^Z//' << \SHAR_EOF > '400.patch' Z*** /usr/src/bin/ld/ld.c.old Fri Oct 31 22:56:47 1997 Z--- /usr/src/bin/ld/ld.c Sat Jan 24 20:39:49 1998 Z*************** Z*** 1,8 **** Z #if defined(DOSCCS) && !defined(lint) Z! static char *sccsid = "@(#)ld.c 4.5 1997/10/31"; Z #endif Z Z /* Z * 4.5 1997/10/31 - sms Z * Minor cleanup. Use unistd.h and stdlib.h instead of local definitions. Z * Correct comment about number of VM pages. Z--- 1,15 ---- Z #if defined(DOSCCS) && !defined(lint) Z! static char *sccsid = "@(#)ld.c 4.6 1998/01/19"; Z #endif Z Z /* Z+ * 4.6 1998/01/19 - Tim Shoppa (shoppa@triumf.ca) Z+ * Minor bug fix: when tsize was being incremented by THUNKSZ, Z+ * no check was being made for 16-bit overflow. Fix was to Z+ * call add(). Same was done for the round up to the nearest Z+ * 0100 on tsize. Modify add()'s error reporting to reduce memory Z+ * usage - sms. Z+ * Z * 4.5 1997/10/31 - sms Z * Minor cleanup. Use unistd.h and stdlib.h instead of local definitions. Z * Correct comment about number of VM pages. Z*************** Z*** 938,946 **** Z } Z Z if (libflg==0 || ndef) { Z! tsize = add(tsize,filhdr.e.a_text,"text overflow"); Z! dsize = add(dsize,filhdr.e.a_data,"data overflow"); Z! bsize = add(bsize,filhdr.e.a_bss,"bss overflow"); Z ssize += nlocal; Z return (1); Z } Z--- 945,953 ---- Z } Z Z if (libflg==0 || ndef) { Z! tsize = add(tsize,filhdr.e.a_text,"text"); Z! dsize = add(dsize,filhdr.e.a_data,"data"); Z! bsize = add(bsize,filhdr.e.a_bss,"bss"); Z ssize += nlocal; Z return (1); Z } Z*************** Z*** 1030,1036 **** Z sp->n_value = csize; Z sp->n_type = N_EXT+N_COMM; Z VMMODIFY(seg); Z! csize = add(csize, t, "bss overflow"); Z } Z } Z } Z--- 1037,1043 ---- Z sp->n_value = csize; Z sp->n_type = N_EXT+N_COMM; Z VMMODIFY(seg); Z! csize = add(csize, t, "bss"); Z } Z } Z } Z*************** Z*** 1046,1052 **** Z sp->sovalue = sp->n_value; Z sp->n_value = tsize; Z VMMODIFY(seg); Z! tsize += THUNKSIZ; Z if (trace) Z printf("relocating %.*s in overlay %d from %o to %o\n", Z NNAMESIZE,sp->n_name,sp->n_ovly, Z--- 1053,1059 ---- Z sp->sovalue = sp->n_value; Z sp->n_value = tsize; Z VMMODIFY(seg); Z! tsize = add(tsize, THUNKSIZ, "text"); Z if (trace) Z printf("relocating %.*s in overlay %d from %o to %o\n", Z NNAMESIZE,sp->n_name,sp->n_ovly, Z*************** Z*** 1058,1064 **** Z * Now set symbols to their final value Z */ Z if (nflag || iflag) Z! tsize = (tsize + 077) & ~077; Z ttsize = tsize; Z if (numov) { Z register int i; Z--- 1065,1071 ---- Z * Now set symbols to their final value Z */ Z if (nflag || iflag) Z! tsize = add(tsize, 077, "text") & ~077; Z ttsize = tsize; Z if (numov) { Z register int i; Z*************** Z*** 1141,1147 **** Z } Z if (sflag || xflag) Z ssize = 0; Z! bsize = add(bsize, csize, "bss overflow"); Z nsym = ssize / (sizeof cursym); Z } Z Z--- 1148,1154 ---- Z } Z if (sflag || xflag) Z ssize = 0; Z! bsize = add(bsize, csize, "bss"); Z nsym = ssize / (sizeof cursym); Z } Z Z*************** Z*** 2004,2013 **** Z char *s; Z { Z long r; Z Z r = (long)(u_int)a + (u_int)b; Z if (r >= 0200000) Z! error(1,s); Z return(r); Z } Z Z--- 2011,2026 ---- Z char *s; Z { Z long r; Z+ register char *ap; Z Z r = (long)(u_int)a + (u_int)b; Z if (r >= 0200000) Z! { Z! ap = (char *)alloca(strlen(s) + 1 + sizeof (" overflow")); Z! strcpy(ap, s); Z! strcat(ap, " overflow"); Z! error(1, ap); Z! } Z return(r); Z } Z Z*** /usr/src/bin/ld/Makefile.old Thu Jan 19 21:55:45 1995 Z--- /usr/src/bin/ld/Makefile Sat Jan 24 21:41:21 1998 Z*************** Z*** 1,19 **** Z! # Version 2.1 January 19, 1994 Z Z SRCS= ld.c Z OBJS= ld.o Z CFLAGS= -O -I../ar -DNUM_VM_PAGES=20 Z Z! all: ld Z Z ld: ${OBJS} Z cc -i -o ld ${OBJS} -lvmf Z Z! install: Z install -c -s -o bin -g bin -m 755 ld ${DESTDIR}/bin/ld Z Z lint: Z lint -havx -I../ar ${SRCS} Z Z clean: Z! rm -f *.o *.0 ld Z--- 1,25 ---- Z! # Version 2.2 January 24, 1998 Z Z SRCS= ld.c Z OBJS= ld.o Z+ MAN= ld.0 Z+ MANSRC= ld.1 Z CFLAGS= -O -I../ar -DNUM_VM_PAGES=20 Z Z! all: ld ld.0 Z Z ld: ${OBJS} Z cc -i -o ld ${OBJS} -lvmf Z Z! install: all Z install -c -s -o bin -g bin -m 755 ld ${DESTDIR}/bin/ld Z+ install -c -o bin -g bin -m 444 ${MAN} ${DESTDIR}/usr/man/cat1 Z Z lint: Z lint -havx -I../ar ${SRCS} Z Z clean: Z! rm -f ${OBJS} ${MAN} ld Z! Z! ${MAN}: ${MANSRC} Z! /usr/man/manroff ${MANSRC} > ${MAN} Z*** /usr/src/man/man1/Makefile.old Fri Jun 27 20:19:13 1997 Z--- /usr/src/man/man1/Makefile Sat Jan 24 20:44:46 1998 Z*************** Z*** 14,20 **** Z # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED Z # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. Z # Z! # @(#)Makefile 1.8 (2.11BSD) 1997/6/27 Z # Z MDIR= /usr/man/cat1 Z SRCS= adb.1 addbib.1 apply.1 apropos.1 as.1 at.1 atq.1 atrm.1 \ Z--- 14,20 ---- Z # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED Z # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. Z # Z! # @(#)Makefile 1.9 (2.11BSD) 1998/1/24 Z # Z MDIR= /usr/man/cat1 Z SRCS= adb.1 addbib.1 apply.1 apropos.1 as.1 at.1 atq.1 atrm.1 \ Z*************** Z*** 25,31 **** Z efl.1 eqn.1 error.1 ex.1 expand.1 expr.1 f77.1 false.1 file.1 \ Z find.1 fmt.1 fold.1 fpr.1 from.1 fsplit.1 gcore.1 \ Z graph.1 grep.1 head.1 hostid.1 indent.1 \ Z! intro.1 iostat.1 join.1 kill.1 last.1 lastcomm.1 ld.1 \ Z learn.1 leave.1 lex.1 lint.1 lisp.1 ln.1 logger.1 login.1 \ Z look.1 lookbib.1 lorder.1 lpq.1 lpr.1 lprm.1 lptest.1 ls.1 \ Z lxref.1 m4.1 mail.1 make.1 man.1 mesg.1 mkdep.1 mkdir.1 mkstr.1 \ Z--- 25,31 ---- Z efl.1 eqn.1 error.1 ex.1 expand.1 expr.1 f77.1 false.1 file.1 \ Z find.1 fmt.1 fold.1 fpr.1 from.1 fsplit.1 gcore.1 \ Z graph.1 grep.1 head.1 hostid.1 indent.1 \ Z! intro.1 iostat.1 join.1 kill.1 last.1 lastcomm.1 \ Z learn.1 leave.1 lex.1 lint.1 lisp.1 ln.1 logger.1 login.1 \ Z look.1 lookbib.1 lorder.1 lpq.1 lpr.1 lprm.1 lptest.1 ls.1 \ Z lxref.1 m4.1 mail.1 make.1 man.1 mesg.1 mkdep.1 mkdir.1 mkstr.1 \ Z*************** Z*** 53,59 **** Z efl.0 eqn.0 error.0 ex.0 expand.0 expr.0 f77.0 false.0 file.0 \ Z find.0 fmt.0 fold.0 fpr.0 from.0 fsplit.0 gcore.0 \ Z graph.0 grep.0 head.0 hostid.0 indent.0 \ Z! intro.0 iostat.0 join.0 kill.0 last.0 lastcomm.0 ld.0 \ Z learn.0 leave.0 lex.0 lint.0 lisp.0 ln.0 logger.0 login.0 \ Z look.0 lookbib.0 lorder.0 lpq.0 lpr.0 lprm.0 lptest.0 ls.0 \ Z lxref.0 m4.0 mail.0 make.0 man.0 mesg.0 mkdep.0 mkdir.0 mkstr.0 \ Z--- 53,59 ---- Z efl.0 eqn.0 error.0 ex.0 expand.0 expr.0 f77.0 false.0 file.0 \ Z find.0 fmt.0 fold.0 fpr.0 from.0 fsplit.0 gcore.0 \ Z graph.0 grep.0 head.0 hostid.0 indent.0 \ Z! intro.0 iostat.0 join.0 kill.0 last.0 lastcomm.0 \ Z learn.0 leave.0 lex.0 lint.0 lisp.0 ln.0 logger.0 login.0 \ Z look.0 lookbib.0 lorder.0 lpq.0 lpr.0 lprm.0 lptest.0 ls.0 \ Z lxref.0 m4.0 mail.0 make.0 man.0 mesg.0 mkdep.0 mkdir.0 mkstr.0 \ Z*** /VERSION.old Sat Jan 3 22:25:30 1998 Z--- /VERSION Sat Jan 24 20:13:15 1998 Z*************** Z*** 1,5 **** Z! Current Patch Level: 399 Z! Date: January 3, 1998 Z Z 2.11 BSD Z ============ Z--- 1,5 ---- Z! Current Patch Level: 400 Z! Date: January 24, 1998 Z Z 2.11 BSD Z ============ SHAR_EOF chmod 644 '400.patch' fi if test -f '400.sh' then echo shar: "will not over-write existing file '400.sh'" else sed 's/^Z//' << \SHAR_EOF > '400.sh' Z#!/bin/sh -x Z Zmv /usr/src/man/man1/ld.1 /usr/src/bin/ld/ld.1 Zexit 0 SHAR_EOF chmod 755 '400.sh' fi exit 0 # End of shell archive