init, fix initcall blacklist for modules
PATCH 1/1 init, fix initcall blacklist for modules
Sorry ... forgot to cc everyone on the last email.
P.
----8<----
sprint_symbol_no_offset() returns the string "function_name [module_name]" where [module_name] is not printed for built in kernel functions. This means that the initcall blacklisting code will now always fail when comparing module_init() function names. This patch resolves the issue by comparing to the length of the function_name.
--- init/main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
init/main.c +13 -1
@@ -708,14 +708,26 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) {struct blacklist_entry *entry;char fn_name[KSYM_SYMBOL_LEN ]; +char *space; +int length;if (list_empty (&blacklisted_initcalls))return false;sprint_symbol_no_offset (fn_name, (unsigned long )fn); +/* +* fn will be "function_name [module_name]" where [module_name] is not +* displayed for built-in initcall functions. Strip off the +* [module_name]. +*/ + space =strchrnul (fn_name,' ' ); +if (!space) + length =strlen (fn_name); +else + length = space - fn_name;list_for_each_entry (entry, &blacklisted_initcalls, next) { -if (!strcmp (fn_name, entry->buf)) { +if (!strncmp (fn_name, entry->buf, length)) {pr_debug ("initcall %s blacklisted\n" , fn_name);return true; }
Signature · 1 line
1.7.9.3
Quoted 9 lines · Prarit Bhargava
Sorry ... forgot to cc everyone on the last email.
P.
----8<----
sprint_symbol_no_offset()returns the string "function_name[module_name]" where [module_name] is not printed for built in kernel functions. This means that the initcall blacklisting code will now always fail when
I was and am pretty sure that %pf ends up using sprint_symbol_no_offset(), so I don't see how this is new. But maybe "now" doesn't refer to c8cdd2be21?
Quoted 32 lines
comparing
module_init()function names. This patch resolves the issue by comparing to the length of thefunction_name.Signed-off-by Prarit Bhargava <[email protected]>Cc Andrew Morton <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Yang Shi <[email protected]>Cc Ingo Molnar <[email protected]>Cc Mel Gorman <[email protected]>Cc Rasmus Villemoes <[email protected]>Cc Kees Cook <[email protected]>Cc Yaowei Bai <[email protected]>Cc Andrey Ryabinin <[email protected]>--- init/main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)init/main.c +2
-0@@ -708,14 +708,26 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) {struct blacklist_entry *entry;char fn_name[KSYM_SYMBOL_LEN ]; +char *space; +int length;if (list_empty (&blacklisted_initcalls))return false;sprint_symbol_no_offset (fn_name, (unsigned long )fn);
init/main.c static bool __init_or_module initcall_blacklisted(initcall_t fn) · line 727
Quoted 10 lines
init/main.c +10
-0+/* +* fn will be "function_name [module_name]" where [module_name] is not +* displayed for built-in initcall functions. Strip off the +* [module_name]. +*/ + space =strchrnul (fn_name,' ' ); +if (!space) + length =strlen (fn_name); +else + length = space - fn_name;
strchrnul never returns NULL, so this could just be 'length = strchrnul(fn_name, ' ') - fn_name;'. But I don't think that's what you want anyway: Suppose one has blacklisted "init_foobar", and the function pointer resolves to a completely unrelated "init_foo", we'll end up falsely also blacklisting that since we're just comparing prefixes.
May I suggest
strreplace(fn_name, ' ', '\0');
which also seems to match the comment a little better (and eliminates the extra variables and the hunk below).
init/main.c static bool __init_or_module initcall_blacklisted(initcall_t fn) · line 733
Quoted 6 lines
init/main.c +1
-1list_for_each_entry (entry, &blacklisted_initcalls, next) { -if (!strcmp (fn_name, entry->buf)) { +if (!strncmp (fn_name, entry->buf, length)) {pr_debug ("initcall %s blacklisted\n" , fn_name);return true; }
Rasmus
Quoted 8 lines · Rasmus Villemoes
Quoted 6 lines · Prarit Bhargava
Sorry ... forgot to cc everyone on the last email.
P.
----8<----
Quoted 7 lines
Quoted 3 lines
sprint_symbol_no_offset()returns the string "function_name[module_name]" where [module_name] is not printed for built in kernel functions. This means that the initcall blacklisting code will now always fail whenI was and am pretty sure that %pf ends up using
sprint_symbol_no_offset(), so I don't see how this is new. But maybe "now" doesn't refer toc8cdd2be21?
Oops. I can see how you read that that way. No, this isn't caused by or "Fixes:" c8cdd2be21. At some point "%pF" changed its behavior and blacklisting module_init() functions stopped working.
P.
Quoted 66 lines
Quoted 33 lines
comparing
module_init()function names. This patch resolves the issue by comparing to the length of thefunction_name.Signed-off-by Prarit Bhargava <[email protected]>Cc Andrew Morton <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Yang Shi <[email protected]>Cc Ingo Molnar <[email protected]>Cc Mel Gorman <[email protected]>Cc Rasmus Villemoes <[email protected]>Cc Kees Cook <[email protected]>Cc Yaowei Bai <[email protected]>Cc Andrey Ryabinin <[email protected]>--- init/main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)init/main.c +2
-0@@ -708,14 +708,26 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) {struct blacklist_entry *entry;char fn_name[KSYM_SYMBOL_LEN ]; +char *space; +int length;if (list_empty (&blacklisted_initcalls))return false;sprint_symbol_no_offset (fn_name, (unsigned long )fn);init/main.c static bool __init_or_module initcall_blacklisted(initcall_t fn) · line 727
Quoted 10 lines
init/main.c +10
-0+/* +* fn will be "function_name [module_name]" where [module_name] is not +* displayed for built-in initcall functions. Strip off the +* [module_name]. +*/ + space =strchrnul (fn_name,' ' ); +if (!space) + length =strlen (fn_name); +else + length = space - fn_name;strchrnul never returns NULL, so this could just be 'length =
strchrnul(fn_name, ' ')-fn_name;'. But I don't think that's what you want anyway: Suppose one has blacklisted "init_foobar", and the function pointer resolves to a completely unrelated "init_foo", we'll end up falsely also blacklisting that since we're just comparing prefixes.May I suggest
strreplace(fn_name, ' ', '\0');which also seems to match the comment a little better (and eliminates the extra variables and the hunk below).
init/main.c static bool __init_or_module initcall_blacklisted(initcall_t fn) · line 733
Quoted 6 lines
init/main.c +1
-1list_for_each_entry (entry, &blacklisted_initcalls, next) { -if (!strcmp (fn_name, entry->buf)) { +if (!strncmp (fn_name, entry->buf, length)) {pr_debug ("initcall %s blacklisted\n" , fn_name);return true; }Rasmus
Quoted 13 lines · On Tue, 14 Jun 2016 05:59:46 -0400 Prarit Bhargava <[email protected]> wrote:
Quoted 12 lines · Rasmus Villemoes
Quoted 9 lines · Prarit Bhargava
Sorry ... forgot to cc everyone on the last email.
P.
----8<----
sprint_symbol_no_offset()returns the string "function_name[module_name]" where [module_name] is not printed for built in kernel functions. This means that the initcall blacklisting code will now always fail when
Quoted 7 lines
Quoted 3 lines
I was and am pretty sure that %pf ends up using
sprint_symbol_no_offset(), so I don't see how this is new. But maybe "now" doesn't refer toc8cdd2be21?Oops. I can see how you read that that way. No, this isn't caused by or "Fixes:"
c8cdd2be21. At some point "%pF" changed its behavior and blacklistingmodule_init()functions stopped working.
Well can we please have a v2 with a complete changelog which identifies when the regression occurred? That will help in deciding which kernel versions need fixing.