kconfig: undefined symbols can crash dependency loop detection
PATCH 1/1 kconfig: undefined symbols can crash dependency loop detection
The Kconfig
config FOO
bool "FOO" if BAR
select BAR
has a dependency loop involving an undefined symbol BAR. This causes a segfault in sym_check_print_recursive() as it assumes all symbols have a non-null 'prop', which is not the case for undefined symbols. This is a proposed fix.
--- scripts/kconfig/symbol.c | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-)
scripts/kconfig/symbol.c +28 -4
@@ -5,6 +5,7 @@#include <ctype.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <regex.h> #include <sys/utsname.h>
@@ -972,6 +973,10 @@ static void sym_check_print_recursive(struct symbol *last_sym)struct menu *menu =NULL ;struct property *prop;struct dep_stack cv_stack; +const char *filename; +int lineno; +char undef_msg_buf[100 ]; +int snprintf_size;if (sym_is_choice_value (last_sym)) {dep_stack_insert (&cv_stack, last_sym);
@@ -1001,18 +1006,37 @@ static void sym_check_print_recursive(struct symbol *last_sym)break ; } } + +if (prop) { + filename = prop->file->name; + lineno = prop->lineno; + }else { +/* The dependency loop involves an undefined symbol. +* Checking sym->name is probably unnecessary here, but +* just to be on the safe side. */ + snprintf_size =snprintf (undef_msg_buf, +sizeof (undef_msg_buf), +"<no file, %s is undefined>" , + sym->name ? sym->name : +"<choice>" ); +if (snprintf_size >sizeof (undef_msg_buf)) + undef_msg_buf[sizeof (undef_msg_buf) -1 ] ='\0' ; + filename = undef_msg_buf; + lineno =0 ; + } +if (stack->sym == last_sym)fprintf (stderr,"%s:%d:error: recursive dependency detected!\n" , - prop->file->name, prop->lineno); + filename, lineno);if (stack->expr) {fprintf (stderr,"%s:%d:\tsymbol %s %s value contains %s\n" , - prop->file->name, prop->lineno, + filename, lineno, sym->name ? sym->name :"<choice>" ,prop_get_type_name (prop->type), next_sym->name ? next_sym->name :"<choice>" ); }else if (stack->prop) {fprintf (stderr,"%s:%d:\tsymbol %s depends on %s\n" , - prop->file->name, prop->lineno, + filename, lineno, sym->name ? sym->name :"<choice>" , next_sym->name ? next_sym->name :"<choice>" ); }else if (sym_is_choice (sym)) {
@@ -1027,7 +1051,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) next_sym->name ? next_sym->name : "<choice>"); }else {fprintf (stderr,"%s:%d:\tsymbol %s is selected by %s\n" , - prop->file->name, prop->lineno, + filename, lineno, sym->name ? sym->name :"<choice>" , next_sym->name ? next_sym->name :"<choice>" ); }
Signature · 1 line
1.7.0.4
Quoted 50 lines · Ulf Magnusson
The
Kconfigconfig FOO
bool "FOO" if BAR
select BARhas a dependency loop involving an undefined symbol BAR. This causes a segfault in
sym_check_print_recursive()as it assumes all symbols have a non-null 'prop', which is not the case for undefined symbols. This is a proposed fix.Signed-off-by Ulf Magnusson <[email protected]>--- scripts/kconfig/symbol.c | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-)scripts/kconfig/symbol.c +12
-0@@ -5,6 +5,7 @@#include <ctype.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <regex.h> #include <sys/utsname.h> @@ -972,6 +973,10 @@ static void sym_check_print_recursive(struct symbol *last_sym)struct menu *menu =NULL ;struct property *prop;struct dep_stack cv_stack; +const char *filename; +int lineno; +char undef_msg_buf[100 ]; +int snprintf_size;if (sym_is_choice_value (last_sym)) {dep_stack_insert (&cv_stack, last_sym);@@ -1001,18 +1006,37 @@ static void sym_check_print_recursive(struct symbol *last_sym)break ; } } + +if (prop) { + filename = prop->file->name; + lineno = prop->lineno; + }else { +/* The dependency loop involves an undefined symbol. +* Checking sym->name is probably unnecessary here, but
scripts/kconfig/symbol.c static void sym_check_print_recursive(struct symbol *last_sym) · line 1025
Quoted 10 lines
scripts/kconfig/symbol.c +10
-0+* just to be on the safe side. */ + snprintf_size =snprintf (undef_msg_buf, +sizeof (undef_msg_buf), +"<no file, %s is undefined>" , + sym->name ? sym->name : +"<choice>" ); +if (snprintf_size >sizeof (undef_msg_buf)) + undef_msg_buf[sizeof (undef_msg_buf) -1 ] ='\0' ; + filename = undef_msg_buf; + lineno =0 ;
Good catch. But as this handles a corner case involving a severely borken Kconfig file, I would simply do
filename = "<unknown>";
lineno = 0;
and be done with it.
Michal
Quoted 59 lines · Michal Marek
Quoted 58 lines · Ulf Magnusson
The
Kconfigconfig FOO
bool "FOO" if BAR
select BARhas a dependency loop involving an undefined symbol BAR. This causes a segfault in
sym_check_print_recursive()as it assumes all symbols have a non-null 'prop', which is not the case for undefined symbols. This is a proposed fix.Signed-off-by Ulf Magnusson <[email protected]>--- scripts/kconfig/symbol.c | 32 ++++++++++++++++++++++++++++---- 1 files changed, 28 insertions(+), 4 deletions(-)scripts/kconfig/symbol.c +20
-0@@ -5,6 +5,7 @@#include <ctype.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <regex.h> #include <sys/utsname.h> @@ -972,6 +973,10 @@ static void sym_check_print_recursive(struct symbol *last_sym)struct menu *menu =NULL ;struct property *prop;struct dep_stack cv_stack; +const char *filename; +int lineno; +char undef_msg_buf[100 ]; +int snprintf_size;if (sym_is_choice_value (last_sym)) {dep_stack_insert (&cv_stack, last_sym);@@ -1001,18 +1006,37 @@ static void sym_check_print_recursive(struct symbol *last_sym)break ; } } + +if (prop) { + filename = prop->file->name; + lineno = prop->lineno; + }else { +/* The dependency loop involves an undefined symbol. +* Checking sym->name is probably unnecessary here, but +* just to be on the safe side. */ + snprintf_size =snprintf (undef_msg_buf, +sizeof (undef_msg_buf), +"<no file, %s is undefined>" , + sym->name ? sym->name : +"<choice>" ); +if (snprintf_size >sizeof (undef_msg_buf)) + undef_msg_buf[sizeof (undef_msg_buf) -1 ] ='\0' ;
Quoted 9 lines
scripts/kconfig/symbol.c static void sym_check_print_recursive(struct symbol *last_sym) · line 1025
Quoted 2 lines
scripts/kconfig/symbol.c +2
-0+ filename = undef_msg_buf; + lineno =0 ;Good catch. But as this handles a corner case involving a severely borken
Kconfigfile, I would simply do
filename = "<unknown>";
lineno = 0;
and be done with it.
Yeah, it probably isn't very likely to occur in practise, though it would also happen if a symbol selects an undefined symbol it depends on via an enclosing menu or if.
Pick whatever version you prefer :)
/Ulf