9
9
10
10
#include <stdarg.h>
11
11
12
+ #include <linux/ctype.h>
12
13
#include <linux/efi.h>
13
14
#include <linux/kernel.h>
14
15
#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
15
16
#include <asm/efi.h>
17
+ #include <asm/setup.h>
16
18
17
19
#include "efistub.h"
18
20
@@ -217,22 +219,33 @@ char *efi_convert_cmdline(efi_loaded_image_t *image,
217
219
unsigned long cmdline_addr = 0 ;
218
220
int options_chars = efi_table_attr (image , load_options_size ) / 2 ;
219
221
const u16 * options = efi_table_attr (image , load_options );
220
- int options_bytes = 0 ; /* UTF-8 bytes */
222
+ int options_bytes = 0 , safe_options_bytes = 0 ; /* UTF-8 bytes */
223
+ bool in_quote = false;
221
224
efi_status_t status ;
222
225
223
226
if (options ) {
224
227
s2 = options ;
225
- while (options_chars -- ) {
228
+ while (options_bytes < COMMAND_LINE_SIZE && options_chars -- ) {
226
229
u16 c = * s2 ++ ;
227
230
228
- if (c == L'\0' || c == L'\n' )
229
- break ;
231
+ if (c < 0x80 ) {
232
+ if (c == L'\0' || c == L'\n' )
233
+ break ;
234
+ if (c == L'"' )
235
+ in_quote = !in_quote ;
236
+ else if (!in_quote && isspace ((char )c ))
237
+ safe_options_bytes = options_bytes ;
238
+
239
+ options_bytes ++ ;
240
+ continue ;
241
+ }
242
+
230
243
/*
231
244
* Get the number of UTF-8 bytes corresponding to a
232
245
* UTF-16 character.
233
246
* The first part handles everything in the BMP.
234
247
*/
235
- options_bytes += 1 + ( c >= 0x80 ) + (c >= 0x800 );
248
+ options_bytes += 2 + (c >= 0x800 );
236
249
/*
237
250
* Add one more byte for valid surrogate pairs. Invalid
238
251
* surrogates will be replaced with 0xfffd and take up
@@ -253,6 +266,11 @@ char *efi_convert_cmdline(efi_loaded_image_t *image,
253
266
}
254
267
}
255
268
}
269
+ if (options_bytes >= COMMAND_LINE_SIZE ) {
270
+ options_bytes = safe_options_bytes ;
271
+ efi_err ("Command line is too long: truncated to %d bytes\n" ,
272
+ options_bytes );
273
+ }
256
274
}
257
275
258
276
options_bytes ++ ; /* NUL termination */
0 commit comments