diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-06-04 13:28:43 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-06-04 13:28:43 +0000 |
commit | c06391be0d468eba7944f150636ba879487d43ca (patch) | |
tree | ba42036eb656c1e05711fc08e3eccd6a42089136 /modutils/modprobe.c | |
parent | 3b79370a7ddf749f1a475b10b017170c644d283b (diff) | |
download | busybox-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.c | 175 |
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 | ||
47 | static struct dep_t *build_dep ( void ) | 47 | static 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 | } |