diff -ru ld.so-1.9.2/Config.mk ld.so-1.9.2-fixed/Config.mk --- ld.so-1.9.2/Config.mk Tue Mar 18 18:41:08 1997 +++ ld.so-1.9.2-fixed/Config.mk Fri Jul 18 01:09:43 1997 @@ -2,7 +2,7 @@ #ARCH = m68k #ARCH = sparc #DEBUG = true -#AOUT_SUPPORT = true +AOUT_SUPPORT = true LDSO_ADDR = 62f00020 LDSO_ENTRY = "0x$(LDSO_ADDR)" @@ -19,8 +19,8 @@ RANLIB = ranlib ifeq ($(ARCH),i386) -AOUTCC = /usr/i486-linuxaout/bin/gcc -#AOUTCC = gcc -b i486-linuxaout +#AOUTCC = /usr/i486-linuxaout/bin/gcc +AOUTCC = gcc -b i486-linuxaout AOUTLD = /usr/i486-linuxaout/bin/ld -m i386linux endif ifeq ($(ARCH),m68k) diff -ru ld.so-1.9.2/d-link/boot1.c ld.so-1.9.2-fixed/d-link/boot1.c --- ld.so-1.9.2/d-link/boot1.c Tue Mar 18 18:01:16 1997 +++ ld.so-1.9.2-fixed/d-link/boot1.c Fri Jul 18 01:05:14 1997 @@ -114,10 +114,12 @@ #define ALLOW_ZERO_PLTGOT +#define ELF_LDSO_IMAGE "/lib/ld-linux.so.1" + static char * _dl_malloc_addr, *_dl_mmap_zero; char * _dl_library_path = 0; /* Where we look for libraries */ char *_dl_preload = 0; /* Things to be loaded before the libs. */ -char *_dl_progname = "/lib/ld-linux.so.1"; +char *_dl_progname = ELF_LDSO_IMAGE; static char * _dl_not_lazy = 0; static char * _dl_warn = 0; /* Used by ldd */ static char * _dl_trace_loaded_objects = 0; @@ -171,6 +173,45 @@ #endif /* + * Stop argv0 overflowing vsprintf, but also try to stop false positives + * We obey the following rule + * + * If namesize < 256 keep + * If name from last / < 256 use that + * else use ELF_LDSO_IMAGE + * + * This ensures /very/long/stupid/nfs/path/we/often/get/foobarcmd + * comes out at least as. + * + * foobarcmd: someerror + * + * Even if we fix vsprintf to be vsnprintf (which we should), this + * ought to be kept to help make real size limited errors clearer. + */ + +static char *argv_remap(char *ptr) +{ + char *tmp; + if(strlen(ptr)<256) + return ptr; + if(!*ptr) + return ptr; + tmp=ptr+strlen(ptr)-1; + /* + * Walk back down the chain until we find a slash + */ + while(tmp>=ptr && *tmp!='/') + tmp--; + /* + * No slash, or too long after slash and Im not playing so nyah + */ + if(*tmp!='/') + return ELF_LDSO_IMAGE; + if(strlen(tmp)>256) /* Not off by 1 .. strlen includes the / */ + return ELF_LDSO_IMAGE; + return tmp+1; +} +/* * This stub function is used by some debuggers. The idea is that they * can set an internal breakpoint on it, so that we are notified when the * address mapping is changed in some way. @@ -507,7 +548,7 @@ } if (argv[0]) - _dl_progname = argv[0]; + _dl_progname = argv_remap(argv[0]); /* Now we need to figure out what kind of options are selected. Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */ Only in ld.so-1.9.2-fixed/d-link: boot1.c.orig Only in ld.so-1.9.2/d-link: ld-linux.so Only in ld.so-1.9.2/d-link/libdl: libdl.so diff -ru ld.so-1.9.2/d-link/vsprintf.c ld.so-1.9.2-fixed/d-link/vsprintf.c --- ld.so-1.9.2/d-link/vsprintf.c Wed Oct 9 12:17:21 1996 +++ ld.so-1.9.2-fixed/d-link/vsprintf.c Mon Jul 21 01:16:35 1997 @@ -127,11 +127,13 @@ int qualifier; /* 'h', 'l', or 'L' for integer fields */ char buf[1024]; + char *endbuf; va_list(args); va_start(args, fmt); + endbuf=buf+1023; - for (str=buf ; *fmt ; ++fmt) { + for (str=buf ; *fmt && str < endbuf ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; @@ -191,10 +193,11 @@ switch (*fmt) { case 'c': if (!(flags & LEFT)) - while (--field_width > 0) + while (--field_width > 0 && str < endbuf) *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) + if (str < endbuf) + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0 && str < endbuf) *str++ = ' '; continue; @@ -206,11 +209,11 @@ len = _dl_strlen(s); if (!(flags & LEFT)) - while (len < field_width--) + while (len < field_width-- && str < endbuf) *str++ = ' '; - for (i = 0; i < len; ++i) + for (i = 0; i < len && str < endbuf; ++i) *str++ = *s++; - while (len < field_width--) + while (len < field_width-- && str < endbuf) *str++ = ' '; continue; @@ -219,9 +222,12 @@ field_width = 2*sizeof(void *); flags |= ZEROPAD; } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); + + if (field_width <= endbuf-str){ + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + } continue; @@ -254,9 +260,9 @@ default: if (*fmt != '%') - *str++ = '%'; + if (str < endbuf) *str++ = '%'; if (*fmt) - *str++ = *fmt; + if (str < endbuf) *str++ = *fmt; else --fmt; continue; @@ -272,7 +278,17 @@ num = va_arg(args, int); else num = va_arg(args, unsigned int); - str = number(str, num, base, field_width, precision, flags); + if (field_width != -1) { + if (field_width <= endbuf-str) { + str = number(str, num, base, + field_width, precision, flags); + } + }else{ + if (100 <= endbuf-str) { + str = number(str, num, base, + field_width, precision, flags); + } + } } *str = '\0'; _dl_write(fd, buf, str-buf); diff -ru ld.so-1.9.2/ld-so/fdprintf.c ld.so-1.9.2-fixed/ld-so/fdprintf.c --- ld.so-1.9.2/ld-so/fdprintf.c Sat May 25 22:07:21 1996 +++ ld.so-1.9.2-fixed/ld-so/fdprintf.c Mon Jul 21 01:01:45 1997 @@ -9,7 +9,7 @@ #include #include -extern int vsprintf(char * buf, const char * fmt, va_list args); +extern int vsnprintf(char * buf, size_t size, const char * fmt, va_list args); int fdprintf(int fd, const char *fmt, ...) { @@ -18,7 +18,7 @@ char buf[1024]; va_start(args, fmt); - i=vsprintf(buf,fmt,args); + i=vsnprintf(buf,1024, fmt,args); va_end(args); write(fd, buf, i); diff -ru ld.so-1.9.2/ld-so/ld.so.c ld.so-1.9.2-fixed/ld-so/ld.so.c --- ld.so-1.9.2/ld-so/ld.so.c Mon Jan 6 20:51:06 1997 +++ ld.so-1.9.2-fixed/ld-so/ld.so.c Sun Jul 20 23:29:35 1997 @@ -149,6 +149,46 @@ } #endif +/* + * Stop argv0 overflowing vsprintf, but also try to stop false positives + * We obey the following rule + * + * If namesize < 256 keep + * If name from last / < 256 use that + * else use LDSO_NAME + * + * This ensures /very/long/stupid/nfs/path/we/often/get/foobarcmd + * comes out at least as. + * + * foobarcmd: someerror + * + * Even if we fix vsprintf to be vsnprintf (which we should), this + * ought to be kept to help make real size limited errors clearer. + */ + +static char *argv_remap(char *ptr) +{ + char *tmp; + if(strlen(ptr)<256) + return ptr; + if(!*ptr) + return ptr; + tmp=ptr+strlen(ptr)-1; + /* + * Walk back down the chain until we find a slash + */ + while(tmp>=ptr && *tmp!='/') + tmp--; + /* + * No slash, or too long after slash and Im not playing so nyah + */ + if(*tmp!='/') + return LDSO_IMAGE; + if(strlen(tmp)>256) /* Not off by 1 .. strlen includes the / */ + return LDSO_IMAGE; + return tmp+1; +} + void shared_loader(int func, ...) { @@ -205,12 +245,14 @@ save_mapinfo(mapinfo); #endif argv0 = va_arg(ap, char *); + argv0 = argv_remap(argv0); __environ = va_arg(ap, char **); __SHARED_LIBRARIES__ = va_arg(ap, struct libentry **); _SHARABLE_CONFLICTS__ = va_arg(ap, struct fixuplist *); if (func == FUNC_LINK_AND_CALLBACK) callback = va_arg(ap, callbackptr); va_end(ap); + break; default: /* you want me to do what? */ @@ -226,7 +268,8 @@ /* find out who we are, in case somebody wants to know */ if (!argv0 && !(argv0 = getenv(LDD_ARGV0))) argv0 = LDSO_IMAGE; - + argv0=argv_remap(argv0); + /* hmm, you want your own configuration, do you? */ if (getuid() == geteuid() && getgid() == getegid()) { @@ -322,6 +365,11 @@ .text section. This is passed to ldpreload() below */ if (preload || callback) { + if(nlibs==10) + { + fdprintf(2, "%s: too many preloads\n",argv0); + exit(EXIT_FATAL); + } libs[nlibs] = alloca(strlen(buffer)+1); strcpy(libs[nlibs], buffer); nlibs++; Only in ld.so-1.9.2-fixed/ld-so: ld.so.c.orig diff -ru ld.so-1.9.2/ld-so/strerror.c ld.so-1.9.2-fixed/ld-so/strerror.c --- ld.so-1.9.2/ld-so/strerror.c Sat May 25 13:30:33 1996 +++ ld.so-1.9.2-fixed/ld-so/strerror.c Mon Jul 21 01:04:52 1997 @@ -41,12 +41,12 @@ if (errnum < 0 || errnum >= _sys_nerr) { - static char unknown_error[] = "Unknown error 000000000000000000000"; + static char unknown_error[36] = "Unknown error 000000000000000000000"; static char fmt[] = "Unknown error %d"; #ifdef __linux__ - sprintf(unknown_error, fmt, errnum); + snprintf(unknown_error, 36, fmt, errnum); #else - size_t len = sprintf(unknown_error, fmt, errnum); + size_t len = snprintf(unknown_error, 36, fmt, errnum); if (len < sizeof(fmt) - 2) return NULL; unknown_error[len] = '\0'; diff -ru ld.so-1.9.2/ld-so/vsprintf.c ld.so-1.9.2-fixed/ld-so/vsprintf.c --- ld.so-1.9.2/ld-so/vsprintf.c Sat May 25 22:07:18 1996 +++ ld.so-1.9.2-fixed/ld-so/vsprintf.c Mon Jul 21 01:11:20 1997 @@ -104,13 +104,14 @@ return str; } -int vsprintf(char *buf, const char *fmt, va_list args) +int vsnprintf(char *buf, size_t maxsize, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; + char *endbuf; int flags; /* flags to number() */ @@ -119,7 +120,10 @@ number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ - for (str=buf ; *fmt ; ++fmt) { + if (maxsize == 0) return 0; + endbuf = buf + maxsize - 1; + + for (str=buf ; *fmt && str < endbuf ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; @@ -179,10 +183,11 @@ switch (*fmt) { case 'c': if (!(flags & LEFT)) - while (--field_width > 0) + while (--field_width > 0 && str < endbuf) *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) + if (str < endbuf) + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0 && str < endbuf) *str++ = ' '; continue; @@ -194,11 +199,11 @@ len = strlen(s); if (!(flags & LEFT)) - while (len < field_width--) + while (len < field_width-- && str < endbuf) *str++ = ' '; - for (i = 0; i < len; ++i) + for (i = 0; i < len && str < endbuf; ++i) *str++ = *s++; - while (len < field_width--) + while (len < field_width-- && str < endbuf) *str++ = ' '; continue; @@ -207,9 +212,12 @@ field_width = 2*sizeof(void *); flags |= ZEROPAD; } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); + + if (field_width <= endbuf-str){ + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + } continue; @@ -242,9 +250,9 @@ default: if (*fmt != '%') - *str++ = '%'; + if (str < endbuf) *str++ = '%'; if (*fmt) - *str++ = *fmt; + if (str < endbuf) *str++ = *fmt; else --fmt; continue; @@ -260,19 +268,29 @@ num = va_arg(args, int); else num = va_arg(args, unsigned int); - str = number(str, num, base, field_width, precision, flags); + if (field_width != -1) { + if (field_width <= endbuf-str) { + str = number(str, num, base, + field_width, precision, flags); + } + }else{ + if (100 <= endbuf-str) { + str = number(str, num, base, + field_width, precision, flags); + } + } } *str = '\0'; return str-buf; } -int sprintf(char * buf, const char *fmt, ...) +int snprintf(char * buf, size_t size, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); - i=vsprintf(buf,fmt,args); + i=vsnprintf(buf,size,fmt,args); va_end(args); return i; } Only in ld.so-1.9.2/man: ld.so.info Only in ld.so-1.9.2/test: etestf Only in ld.so-1.9.2/test: etesti Only in ld.so-1.9.2/util: elf-ok Only in ld.so-1.9.2/util: ldconfig Only in ld.so-1.9.2/util: ldd Only in ld.so-1.9.2/util: lddstub