The sym_is() compares a symbol in an attempt to automatically skip symbol
prefixes. It does this first by searching the real symbol with the normal
unprefixed symbol. But then it uses the length of the original symbol to
check the end of the substring instead of the length of the symbol it is
looking for. On non-prefixed arches, this is effectively the same thing,
so there is no problem. On prefixed-arches, since this is exceeds by just
one byte, a crash is rare and it is usually a NUL byte anyways. But every
once in a blue moon, you get the right page alignment and it segfaults.
For example, on the Blackfin arch, sym_is() will be called with the real
symbol "___mod_usb_device_table" as "symbol" when looking for the normal
symbol "__mod_usb_device_table" as "name". The substring will thus return
one byte into "symbol" and store it into "match". But then "match" will
be indexed with the length of "symbol" instead of "name" and so we will
exceed the storage. i.e. the code ends up doing:
char foo[] = "abc"; return foo[strlen(foo)+1] == '\0';
Signed-off-by: Mike Frysinger <[email protected]>
---
scripts/mod/file2alias.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 40e0045..1ffd1e4 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -726,7 +726,7 @@ static inline int sym_is(const char *symbol, const char *name)
match = strstr(symbol, name);
if (!match)
return 0;
- return match[strlen(symbol)] == '\0';
+ return match[strlen(name)] == '\0';
}
static void do_table(void *symval, unsigned long size,
--
1.6.5.3
On Thu, Dec 3, 2009 at 11:50 AM, Mike Frysinger <[email protected]> wrote:
> The sym_is() compares a symbol in an attempt to automatically skip symbol
> prefixes. It does this first by searching the real symbol with the normal
> unprefixed symbol. But then it uses the length of the original symbol to
> check the end of the substring instead of the length of the symbol it is
> looking for. On non-prefixed arches, this is effectively the same thing,
> so there is no problem. On prefixed-arches, since this is exceeds by just
> one byte, a crash is rare and it is usually a NUL byte anyways. But every
> once in a blue moon, you get the right page alignment and it segfaults.
>
> For example, on the Blackfin arch, sym_is() will be called with the real
> symbol "___mod_usb_device_table" as "symbol" when looking for the normal
> symbol "__mod_usb_device_table" as "name". The substring will thus return
> one byte into "symbol" and store it into "match". But then "match" will
> be indexed with the length of "symbol" instead of "name" and so we will
> exceed the storage. i.e. the code ends up doing:
> char foo[] = "abc"; return foo[strlen(foo)+1] == '\0';
>
> Signed-off-by: Mike Frysinger <[email protected]>
> ---
> scripts/mod/file2alias.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 40e0045..1ffd1e4 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -726,7 +726,7 @@ static inline int sym_is(const char *symbol, const char *name)
> match = strstr(symbol, name);
> if (!match)
> return 0;
> - return match[strlen(symbol)] == '\0';
> + return match[strlen(name)] == '\0';
> }
>
> static void do_table(void *symval, unsigned long size,
Nice catch!
Acked-by: WANG Cong <[email protected]>
On Thu, 3 Dec 2009 02:20:52 pm Mike Frysinger wrote:
> The sym_is() compares a symbol in an attempt to automatically skip symbol
> prefixes. It does this first by searching the real symbol with the normal
> unprefixed symbol. But then it uses the length of the original symbol to
> check the end of the substring instead of the length of the symbol it is
> looking for.
Thanks, applied.
Cheers,
Rusty.
On Thu, Dec 3, 2009 at 02:52, Rusty Russell wrote:
> On Thu, 3 Dec 2009 02:20:52 pm Mike Frysinger wrote:
>> The sym_is() compares a symbol in an attempt to automatically skip symbol
>> prefixes. It does this first by searching the real symbol with the normal
>> unprefixed symbol. But then it uses the length of the original symbol to
>> check the end of the substring instead of the length of the symbol it is
>> looking for.
>
> Thanks, applied.
was this going to be pushed up for 2.6.33 then or wait for 2.6.34 ?
just curious so i can check it off from my local pile ...
-mike
From: Mike Frysinger <[email protected]>
The sym_is() compares a symbol in an attempt to automatically skip symbol
prefixes. It does this first by searching the real symbol with the normal
unprefixed symbol. But then it uses the length of the original symbol to
check the end of the substring instead of the length of the symbol it is
looking for. On non-prefixed arches, this is effectively the same thing,
so there is no problem. On prefixed-arches, since this is exceeds by just
one byte, a crash is rare and it is usually a NUL byte anyways. But every
once in a blue moon, you get the right page alignment and it segfaults.
For example, on the Blackfin arch, sym_is() will be called with the real
symbol "___mod_usb_device_table" as "symbol" when looking for the normal
symbol "__mod_usb_device_table" as "name". The substring will thus return
one byte into "symbol" and store it into "match". But then "match" will
be indexed with the length of "symbol" instead of "name" and so we will
exceed the storage. i.e. the code ends up doing:
char foo[] = "abc"; return foo[strlen(foo)+1] == '\0';
Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Rusty Russell <[email protected]>
---
scripts/mod/file2alias.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 40e0045..1ffd1e4 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -726,7 +726,7 @@ static inline int sym_is(const char *symbol, const char *name)
match = strstr(symbol, name);
if (!match)
return 0;
- return match[strlen(symbol)] == '\0';
+ return match[strlen(name)] == '\0';
}
static void do_table(void *symval, unsigned long size,