aboutsummaryrefslogtreecommitdiff
path: root/modutils/modprobe.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-04 13:28:43 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-04 13:28:43 +0000
commitc06391be0d468eba7944f150636ba879487d43ca (patch)
treeba42036eb656c1e05711fc08e3eccd6a42089136 /modutils/modprobe.c
parent3b79370a7ddf749f1a475b10b017170c644d283b (diff)
downloadbusybox-w32-c06391be0d468eba7944f150636ba879487d43ca.tar.gz
busybox-w32-c06391be0d468eba7944f150636ba879487d43ca.tar.bz2
busybox-w32-c06391be0d468eba7944f150636ba879487d43ca.zip
Avoid stack munching stdio implementations.
-Erik
Diffstat (limited to 'modutils/modprobe.c')
-rw-r--r--modutils/modprobe.c175
1 files changed, 100 insertions, 75 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 6a3e06df4..a72028fa2 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -9,13 +9,13 @@
9 */ 9 */
10 10
11#include <sys/utsname.h> 11#include <sys/utsname.h>
12#include <stdio.h>
13#include <getopt.h> 12#include <getopt.h>
14#include <stdlib.h> 13#include <stdlib.h>
15#include <unistd.h> 14#include <unistd.h>
16#include <syslog.h> 15#include <syslog.h>
17#include <string.h> 16#include <string.h>
18#include <ctype.h> 17#include <ctype.h>
18#include <fcntl.h>
19#include "busybox.h" 19#include "busybox.h"
20 20
21 21
@@ -46,11 +46,11 @@ static int autoclean, show_only, quiet, do_syslog, verbose;
46 46
47static struct dep_t *build_dep ( void ) 47static struct dep_t *build_dep ( void )
48{ 48{
49 int fd, n;
49 struct utsname un; 50 struct utsname un;
50 FILE *f;
51 struct dep_t *first = 0; 51 struct dep_t *first = 0;
52 struct dep_t *current = 0; 52 struct dep_t *current = 0;
53 char buffer [4096]; 53 char buffer[256];
54 char *filename = buffer; 54 char *filename = buffer;
55 int continuation_line = 0; 55 int continuation_line = 0;
56 56
@@ -58,21 +58,35 @@ static struct dep_t *build_dep ( void )
58 return 0; 58 return 0;
59 59
60 // check for buffer overflow in following code 60 // check for buffer overflow in following code
61 if ( xstrlen ( un. release ) > ( sizeof( buffer ) - 64 )) 61 if ( xstrlen ( un.release ) > ( sizeof( buffer ) - 64 )) {
62 return 0; 62 return 0;
63 }
63 64
64 strcpy ( filename, "/lib/modules/" ); 65 strcpy ( filename, "/lib/modules/" );
65 strcat ( filename, un. release ); 66 strcat ( filename, un.release );
66 strcat ( filename, "/modules.dep" ); 67 strcat ( filename, "/modules.dep" );
67 68
68 f = fopen ( filename, "r" ); 69 if ((fd = open ( filename, O_RDONLY )) < 0)
69 if ( !f )
70 return 0; 70 return 0;
71 71
72 while ( fgets ( buffer, sizeof( buffer), f )) { 72 while ( (n = read(fd, buffer, 255)) > 0) {
73 int l = xstrlen ( buffer ); 73 int l;
74 char *p = 0; 74 char *p = 0;
75 75
76 /* Jump through hoops to simulate how fgets() grabs just one line at a
77 * time... Don't use any stdio since modprobe gets called from a kernel
78 * thread and stdio junk can overflow the limited stack... */
79 p = strchr ( buffer, '\n' );
80 if (p) {
81 off_t offset;
82 /* Get the current file descriptor offset */
83 offset = lseek(fd, 0L, SEEK_CUR);
84 /* Set the file descriptor offset to right after the \n */
85 lseek(fd, offset-n+p-buffer+1, SEEK_SET);
86 *(p+1)='\0';
87 }
88
89 l = xstrlen ( buffer );
76 while ( isspace ( buffer [l-1] )) { 90 while ( isspace ( buffer [l-1] )) {
77 buffer [l-1] = 0; 91 buffer [l-1] = 0;
78 l--; 92 l--;
@@ -105,10 +119,10 @@ static struct dep_t *build_dep ( void )
105 mod = xstrndup ( mods, col - mods - ext ); 119 mod = xstrndup ( mods, col - mods - ext );
106 120
107 if ( !current ) { 121 if ( !current ) {
108 first = current = (struct dep_t *) malloc ( sizeof ( struct dep_t )); 122 first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
109 } 123 }
110 else { 124 else {
111 current-> m_next = (struct dep_t *) malloc ( sizeof ( struct dep_t )); 125 current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
112 current = current-> m_next; 126 current = current-> m_next;
113 } 127 }
114 current-> m_module = mod; 128 current-> m_module = mod;
@@ -164,79 +178,90 @@ static struct dep_t *build_dep ( void )
164 else 178 else
165 continuation_line = 0; 179 continuation_line = 0;
166 } 180 }
167 fclose ( f ); 181 close ( fd );
168 182
169 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) ! 183 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) !
170 184
171 f = fopen ( "/etc/modules.conf", "r" ); 185 if ((fd = open ( "/etc/modules.conf", O_RDONLY )) < 0)
172 if ( !f ) 186 if ((fd = open ( "/etc/conf.modules", O_RDONLY )) < 0)
173 f = fopen ( "/etc/conf.modules", "r" ); 187 return first;
174 if ( f ) {
175 continuation_line = 0;
176 188
177 while ( fgets ( buffer, sizeof( buffer), f )) { 189 continuation_line = 0;
178 int l; 190 while ( read(fd, buffer, 255) > 0) {
179 char *p; 191 int l;
180 192 char *p;
181 p = strchr ( buffer, '#' );
182 if ( p )
183 *p = 0;
184
185 l = xstrlen ( buffer );
186 193
187 while ( l && isspace ( buffer [l-1] )) { 194 /* Jump through hoops to simulate how fgets() grabs just one line at a
188 buffer [l-1] = 0; 195 * time... Don't use any stdio since modprobe gets called from a kernel
189 l--; 196 * thread and stdio junk can overflow the limited stack... */
190 } 197 p = strchr ( buffer, '\n' );
191 198 if (p) {
192 if ( l == 0 ) { 199 off_t offset;
193 continuation_line = 0; 200 /* Get the current file descriptor offset */
194 continue; 201 offset = lseek(fd, 0L, SEEK_CUR);
195 } 202 /* Set the file descriptor offset to right after the \n */
203 lseek(fd, offset-n+p-buffer+1, SEEK_SET);
204 *(p+1)='\0';
205 }
206
207 p = strchr ( buffer, '#' );
208 if ( p )
209 *p = 0;
196 210
197 if ( !continuation_line ) { 211 l = xstrlen ( buffer );
198 if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) { 212
199 char *alias, *mod; 213 while ( l && isspace ( buffer [l-1] )) {
214 buffer [l-1] = 0;
215 l--;
216 }
217
218 if ( l == 0 ) {
219 continuation_line = 0;
220 continue;
221 }
222
223 if ( !continuation_line ) {
224 if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) {
225 char *alias, *mod;
200 226
201 alias = buffer + 6; 227 alias = buffer + 6;
202 228
203 while ( isspace ( *alias )) 229 while ( isspace ( *alias ))
204 alias++; 230 alias++;
205 mod = alias; 231 mod = alias;
206 while ( !isspace ( *mod )) 232 while ( !isspace ( *mod ))
207 mod++; 233 mod++;
208 *mod = 0; 234 *mod = 0;
235 mod++;
236 while ( isspace ( *mod ))
209 mod++; 237 mod++;
210 while ( isspace ( *mod )) 238
211 mod++;
212
213// fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod ); 239// fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod );
214 240
215 if ( !current ) { 241 if ( !current ) {
216 first = current = (struct dep_t *) malloc ( sizeof ( struct dep_t )); 242 first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
217 } 243 }
218 else { 244 else {
219 current-> m_next = (struct dep_t *) malloc ( sizeof ( struct dep_t )); 245 current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
220 current = current-> m_next; 246 current = current-> m_next;
221 } 247 }
222 current-> m_module = xstrdup ( alias ); 248 current-> m_module = xstrdup ( alias );
223 current-> m_isalias = 1; 249 current-> m_isalias = 1;
224 250
225 if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) { 251 if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) {
226 current-> m_depcnt = 0; 252 current-> m_depcnt = 0;
227 current-> m_deparr = 0; 253 current-> m_deparr = 0;
228 } 254 }
229 else { 255 else {
230 current-> m_depcnt = 1; 256 current-> m_depcnt = 1;
231 current-> m_deparr = xmalloc ( 1 * sizeof( char * )); 257 current-> m_deparr = xmalloc ( 1 * sizeof( char * ));
232 current-> m_deparr[0] = xstrdup ( mod ); 258 current-> m_deparr[0] = xstrdup ( mod );
233 } 259 }
234 current-> m_next = 0; 260 current-> m_next = 0;
235 } 261 }
236 }
237 } 262 }
238 fclose ( f );
239 } 263 }
264 close ( fd );
240 265
241 return first; 266 return first;
242} 267}