Avoid stack munching stdio implementations.

-Erik
This commit is contained in:
Eric Andersen
2002-06-04 13:28:43 +00:00
parent 3b79370a7d
commit c06391be0d

View File

@@ -9,13 +9,13 @@
*/ */
#include <sys/utsname.h> #include <sys/utsname.h>
#include <stdio.h>
#include <getopt.h> #include <getopt.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <syslog.h> #include <syslog.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h>
#include "busybox.h" #include "busybox.h"
@@ -46,11 +46,11 @@ static int autoclean, show_only, quiet, do_syslog, verbose;
static struct dep_t *build_dep ( void ) static struct dep_t *build_dep ( void )
{ {
int fd, n;
struct utsname un; struct utsname un;
FILE *f;
struct dep_t *first = 0; struct dep_t *first = 0;
struct dep_t *current = 0; struct dep_t *current = 0;
char buffer [4096]; char buffer[256];
char *filename = buffer; char *filename = buffer;
int continuation_line = 0; int continuation_line = 0;
@@ -58,21 +58,35 @@ static struct dep_t *build_dep ( void )
return 0; return 0;
// check for buffer overflow in following code // check for buffer overflow in following code
if ( xstrlen ( un. release ) > ( sizeof( buffer ) - 64 )) if ( xstrlen ( un.release ) > ( sizeof( buffer ) - 64 )) {
return 0; return 0;
}
strcpy ( filename, "/lib/modules/" ); strcpy ( filename, "/lib/modules/" );
strcat ( filename, un. release ); strcat ( filename, un.release );
strcat ( filename, "/modules.dep" ); strcat ( filename, "/modules.dep" );
f = fopen ( filename, "r" ); if ((fd = open ( filename, O_RDONLY )) < 0)
if ( !f )
return 0; return 0;
while ( fgets ( buffer, sizeof( buffer), f )) { while ( (n = read(fd, buffer, 255)) > 0) {
int l = xstrlen ( buffer ); int l;
char *p = 0; char *p = 0;
/* Jump through hoops to simulate how fgets() grabs just one line at a
* time... Don't use any stdio since modprobe gets called from a kernel
* thread and stdio junk can overflow the limited stack... */
p = strchr ( buffer, '\n' );
if (p) {
off_t offset;
/* Get the current file descriptor offset */
offset = lseek(fd, 0L, SEEK_CUR);
/* Set the file descriptor offset to right after the \n */
lseek(fd, offset-n+p-buffer+1, SEEK_SET);
*(p+1)='\0';
}
l = xstrlen ( buffer );
while ( isspace ( buffer [l-1] )) { while ( isspace ( buffer [l-1] )) {
buffer [l-1] = 0; buffer [l-1] = 0;
l--; l--;
@@ -105,10 +119,10 @@ static struct dep_t *build_dep ( void )
mod = xstrndup ( mods, col - mods - ext ); mod = xstrndup ( mods, col - mods - ext );
if ( !current ) { if ( !current ) {
first = current = (struct dep_t *) malloc ( sizeof ( struct dep_t )); first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
} }
else { else {
current-> m_next = (struct dep_t *) malloc ( sizeof ( struct dep_t )); current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
current = current-> m_next; current = current-> m_next;
} }
current-> m_module = mod; current-> m_module = mod;
@@ -164,79 +178,90 @@ static struct dep_t *build_dep ( void )
else else
continuation_line = 0; continuation_line = 0;
} }
fclose ( f ); close ( fd );
// alias parsing is not 100% correct (no correct handling of continuation lines within an alias) ! // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) !
f = fopen ( "/etc/modules.conf", "r" ); if ((fd = open ( "/etc/modules.conf", O_RDONLY )) < 0)
if ( !f ) if ((fd = open ( "/etc/conf.modules", O_RDONLY )) < 0)
f = fopen ( "/etc/conf.modules", "r" ); return first;
if ( f ) {
continuation_line = 0;
while ( fgets ( buffer, sizeof( buffer), f )) { continuation_line = 0;
int l; while ( read(fd, buffer, 255) > 0) {
char *p; int l;
char *p;
p = strchr ( buffer, '#' );
if ( p )
*p = 0;
l = xstrlen ( buffer );
while ( l && isspace ( buffer [l-1] )) { /* Jump through hoops to simulate how fgets() grabs just one line at a
buffer [l-1] = 0; * time... Don't use any stdio since modprobe gets called from a kernel
l--; * thread and stdio junk can overflow the limited stack... */
} p = strchr ( buffer, '\n' );
if (p) {
if ( l == 0 ) { off_t offset;
continuation_line = 0; /* Get the current file descriptor offset */
continue; offset = lseek(fd, 0L, SEEK_CUR);
} /* Set the file descriptor offset to right after the \n */
lseek(fd, offset-n+p-buffer+1, SEEK_SET);
if ( !continuation_line ) { *(p+1)='\0';
if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) { }
char *alias, *mod;
p = strchr ( buffer, '#' );
alias = buffer + 6; if ( p )
*p = 0;
while ( isspace ( *alias ))
alias++; l = xstrlen ( buffer );
mod = alias;
while ( !isspace ( *mod )) while ( l && isspace ( buffer [l-1] )) {
mod++; buffer [l-1] = 0;
*mod = 0; l--;
mod++; }
while ( isspace ( *mod ))
mod++; if ( l == 0 ) {
continuation_line = 0;
// fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod ); continue;
}
if ( !current ) {
first = current = (struct dep_t *) malloc ( sizeof ( struct dep_t )); if ( !continuation_line ) {
} if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) {
else { char *alias, *mod;
current-> m_next = (struct dep_t *) malloc ( sizeof ( struct dep_t ));
current = current-> m_next; alias = buffer + 6;
}
current-> m_module = xstrdup ( alias ); while ( isspace ( *alias ))
current-> m_isalias = 1; alias++;
mod = alias;
if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) { while ( !isspace ( *mod ))
current-> m_depcnt = 0; mod++;
current-> m_deparr = 0; *mod = 0;
} mod++;
else { while ( isspace ( *mod ))
current-> m_depcnt = 1; mod++;
current-> m_deparr = xmalloc ( 1 * sizeof( char * ));
current-> m_deparr[0] = xstrdup ( mod ); // fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod );
}
current-> m_next = 0; if ( !current ) {
} first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
} }
else {
current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
current = current-> m_next;
}
current-> m_module = xstrdup ( alias );
current-> m_isalias = 1;
if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) {
current-> m_depcnt = 0;
current-> m_deparr = 0;
}
else {
current-> m_depcnt = 1;
current-> m_deparr = xmalloc ( 1 * sizeof( char * ));
current-> m_deparr[0] = xstrdup ( mod );
}
current-> m_next = 0;
}
} }
fclose ( f );
} }
close ( fd );
return first; return first;
} }