* [PATCH] dbus: Fix subpath comparisons in object tree walk
@ 2018-08-15 4:02 Andrew Zaborowski
2018-08-15 16:55 ` Denis Kenzior
0 siblings, 1 reply; 5+ messages in thread
From: Andrew Zaborowski @ 2018-08-15 4:02 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]
By only using strncmp(child->subpath, path, len) we'd only check that
child->subpath had path as its prefix in makepath_recurse. As a
result, if an object at /ab was added first and at /a second, the
second object would not get a new node created and strangely none of
our tests or users have caught this.
---
ell/dbus-service.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index 43c7a5c..cd9d402 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -649,7 +649,8 @@ static struct object_node *makepath_recurse(struct object_node *node,
child = node->children;
while (child) {
- if (!strncmp(child->subpath, path, end - path))
+ if (!memcmp(child->subpath, path, end - path) &&
+ child->subpath[end - path] == '\0')
goto done;
child = child->next;
@@ -690,7 +691,8 @@ static struct object_node *lookup_recurse(struct object_node *node,
child = node->children;
while (child) {
- if (!strncmp(child->subpath, path, end - path))
+ if (!memcmp(child->subpath, path, end - path) &&
+ child->subpath[end - path] == '\0')
return lookup_recurse(child->node, end);
child = child->next;
--
2.14.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] dbus: Fix subpath comparisons in object tree walk
2018-08-15 4:02 [PATCH] dbus: Fix subpath comparisons in object tree walk Andrew Zaborowski
@ 2018-08-15 16:55 ` Denis Kenzior
2018-08-15 19:22 ` Andrew Zaborowski
0 siblings, 1 reply; 5+ messages in thread
From: Denis Kenzior @ 2018-08-15 16:55 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 1667 bytes --]
Hi Andrew,
On 08/14/2018 11:02 PM, Andrew Zaborowski wrote:
> By only using strncmp(child->subpath, path, len) we'd only check that
> child->subpath had path as its prefix in makepath_recurse. As a
> result, if an object at /ab was added first and at /a second, the
> second object would not get a new node created and strangely none of
> our tests or users have caught this.
Funny. How'd you catch this?
Also can we have a unit test please?
> ---
> ell/dbus-service.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/ell/dbus-service.c b/ell/dbus-service.c
> index 43c7a5c..cd9d402 100644
> --- a/ell/dbus-service.c
> +++ b/ell/dbus-service.c
> @@ -649,7 +649,8 @@ static struct object_node *makepath_recurse(struct object_node *node,
> child = node->children;
>
> while (child) {
> - if (!strncmp(child->subpath, path, end - path))
> + if (!memcmp(child->subpath, path, end - path) &&
> + child->subpath[end - path] == '\0')
Hmm, is memcmp safe here? What if child->subpath is smaller than end -
path bytes? Might be a good idea to make a unit test specifically for
this and make sure ASAN/valgrind are happy.
> goto done;
>
> child = child->next;
> @@ -690,7 +691,8 @@ static struct object_node *lookup_recurse(struct object_node *node,
> child = node->children;
>
> while (child) {
> - if (!strncmp(child->subpath, path, end - path))
> + if (!memcmp(child->subpath, path, end - path) &&
> + child->subpath[end - path] == '\0')
> return lookup_recurse(child->node, end);
>
> child = child->next;
>
Regards,
-Denis
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] dbus: Fix subpath comparisons in object tree walk
2018-08-15 16:55 ` Denis Kenzior
@ 2018-08-15 19:22 ` Andrew Zaborowski
2018-08-15 20:44 ` Denis Kenzior
0 siblings, 1 reply; 5+ messages in thread
From: Andrew Zaborowski @ 2018-08-15 19:22 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 2115 bytes --]
Hi Denis,
On 15 August 2018 at 18:55, Denis Kenzior <denkenz@gmail.com> wrote:
> On 08/14/2018 11:02 PM, Andrew Zaborowski wrote:
>> By only using strncmp(child->subpath, path, len) we'd only check that
>> child->subpath had path as its prefix in makepath_recurse. As a
>> result, if an object at /ab was added first and at /a second, the
>> second object would not get a new node created and strangely none of
>> our tests or users have caught this.
>
>
> Funny. How'd you catch this?
I think we didn't see this in IWD because our adapters and devices are
registered with numerical paths in growing order, and networks have
one of the _open, _psk, _8021x suffixes. Now that we have known
networks and adapters at the same level in the tree registering
/6f322d574c414e3639_psk followed by /6 would cause problems.
>
> Also can we have a unit test please?
It's unlikely that this problem comes back in the exact same form, but
ok, let's add a test that registers thousands of objects with random
paths including prefixes of existing paths etc.
>
>> ---
>> ell/dbus-service.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/ell/dbus-service.c b/ell/dbus-service.c
>> index 43c7a5c..cd9d402 100644
>> --- a/ell/dbus-service.c
>> +++ b/ell/dbus-service.c
>> @@ -649,7 +649,8 @@ static struct object_node *makepath_recurse(struct
>> object_node *node,
>> child = node->children;
>> while (child) {
>> - if (!strncmp(child->subpath, path, end - path))
>> + if (!memcmp(child->subpath, path, end - path) &&
>> + child->subpath[end - path] == '\0')
>
>
> Hmm, is memcmp safe here? What if child->subpath is smaller than end - path
> bytes? Might be a good idea to make a unit test specifically for this and
> make sure ASAN/valgrind are happy.
If child->subpath is shorter the memcmp will stop at the \0 character
because "path" will have a different character at the same position
but I'll make sure valgrind is happy with the test.
Best regards
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] dbus: Fix subpath comparisons in object tree walk
2018-08-15 19:22 ` Andrew Zaborowski
@ 2018-08-15 20:44 ` Denis Kenzior
2018-08-16 1:12 ` Andrew Zaborowski
0 siblings, 1 reply; 5+ messages in thread
From: Denis Kenzior @ 2018-08-15 20:44 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 4952 bytes --]
Hi Andrew,
On 08/15/2018 02:22 PM, Andrew Zaborowski wrote:
> Hi Denis,
>
> On 15 August 2018 at 18:55, Denis Kenzior <denkenz@gmail.com> wrote:
>> On 08/14/2018 11:02 PM, Andrew Zaborowski wrote:
>>> By only using strncmp(child->subpath, path, len) we'd only check that
>>> child->subpath had path as its prefix in makepath_recurse. As a
>>> result, if an object at /ab was added first and at /a second, the
>>> second object would not get a new node created and strangely none of
>>> our tests or users have caught this.
>>
>>
>> Funny. How'd you catch this?
>
> I think we didn't see this in IWD because our adapters and devices are
> registered with numerical paths in growing order, and networks have
> one of the _open, _psk, _8021x suffixes. Now that we have known
> networks and adapters at the same level in the tree registering
> /6f322d574c414e3639_psk followed by /6 would cause problems.
>
Right. So we might need to hot-fix this soon.
>>
>> Also can we have a unit test please?
>
> It's unlikely that this problem comes back in the exact same form, but
> ok, let's add a test that registers thousands of objects with random
> paths including prefixes of existing paths etc.
>
Not sure that random paths are good. We need something that is
repeatable...
>>
>>> ---
>>> ell/dbus-service.c | 6 ++++--
>>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/ell/dbus-service.c b/ell/dbus-service.c
>>> index 43c7a5c..cd9d402 100644
>>> --- a/ell/dbus-service.c
>>> +++ b/ell/dbus-service.c
>>> @@ -649,7 +649,8 @@ static struct object_node *makepath_recurse(struct
>>> object_node *node,
>>> child = node->children;
>>> while (child) {
>>> - if (!strncmp(child->subpath, path, end - path))
>>> + if (!memcmp(child->subpath, path, end - path) &&
>>> + child->subpath[end - path] == '\0')
>>
>>
>> Hmm, is memcmp safe here? What if child->subpath is smaller than end - path
>> bytes? Might be a good idea to make a unit test specifically for this and
>> make sure ASAN/valgrind are happy.
>
> If child->subpath is shorter the memcmp will stop at the \0 character
> because "path" will have a different character at the same position
> but I'll make sure valgrind is happy with the test.
>
FYI, I don't think memcmp works this way:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char *str1 = "foo";
char *str2 = "foobar";
return memcmp(str1, str2, strlen(str2));
}
gcc -O3 -fsanitize=undefined -fsanitize=address -o foo foo.c
denkenz(a)localhost ~ $ ./foo
=================================================================
==2423==ERROR: AddressSanitizer: global-buffer-overflow on address
0x557ae18f2aa4 at pc 0x7f8fb0838cc4 bp 0x7ffc3b8f5e40 sp 0x7ffc3b8f55e8
READ of size 6 at 0x557ae18f2aa4 thread T0
#0 0x7f8fb0838cc3
(/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xafcc3)
#1 0x7f8faf6c3ed9 in __libc_start_main (/lib64/libc.so.6+0x20ed9)
#2 0x557ae18f28c9 in _start (/home/denkenz/foo+0x8c9)
0x557ae18f2aa4 is located 0 bytes to the right of global variable
'*.LC1' defined in 'foo.c' (0x557ae18f2aa0) of size 4
'*.LC1' is ascii string 'foo'
SUMMARY: AddressSanitizer: global-buffer-overflow
(/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xafcc3)
Shadow bytes around the buggy address:
0x0aafdc316500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316540: 00 00 00 00 00 00 00 00 00 00 00 00 07 f9 f9 f9
=>0x0aafdc316550: f9 f9 f9 f9[04]f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0aafdc316560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc316590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aafdc3165a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==2423==ABORTING
Regards,
-Denis
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] dbus: Fix subpath comparisons in object tree walk
2018-08-15 20:44 ` Denis Kenzior
@ 2018-08-16 1:12 ` Andrew Zaborowski
0 siblings, 0 replies; 5+ messages in thread
From: Andrew Zaborowski @ 2018-08-16 1:12 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 2991 bytes --]
On 15 August 2018 at 22:44, Denis Kenzior <denkenz@gmail.com> wrote:
> Hi Andrew,
>
> On 08/15/2018 02:22 PM, Andrew Zaborowski wrote:
>> On 15 August 2018 at 18:55, Denis Kenzior <denkenz@gmail.com> wrote:
>>> Also can we have a unit test please?
>>
>> It's unlikely that this problem comes back in the exact same form, but
>> ok, let's add a test that registers thousands of objects with random
>> paths including prefixes of existing paths etc.
>>
>
> Not sure that random paths are good. We need something that is
> repeatable...
Yes, I was thinking of hardcoding the seed for the random sequence
using srandom+random -- although it's not clear to me that it's
guaranteed to generate the same sequence across all implementations,
srand48+lrand48 on the other hand does seem to guarantee this.
>
>>>
>>>> ---
>>>> ell/dbus-service.c | 6 ++++--
>>>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/ell/dbus-service.c b/ell/dbus-service.c
>>>> index 43c7a5c..cd9d402 100644
>>>> --- a/ell/dbus-service.c
>>>> +++ b/ell/dbus-service.c
>>>> @@ -649,7 +649,8 @@ static struct object_node *makepath_recurse(struct
>>>> object_node *node,
>>>> child = node->children;
>>>> while (child) {
>>>> - if (!strncmp(child->subpath, path, end - path))
>>>> + if (!memcmp(child->subpath, path, end - path) &&
>>>> + child->subpath[end - path] == '\0')
>>>
>>>
>>>
>>> Hmm, is memcmp safe here? What if child->subpath is smaller than end -
>>> path
>>> bytes? Might be a good idea to make a unit test specifically for this
>>> and
>>> make sure ASAN/valgrind are happy.
>>
>>
>> If child->subpath is shorter the memcmp will stop at the \0 character
>> because "path" will have a different character at the same position
>> but I'll make sure valgrind is happy with the test.
>>
>
> FYI, I don't think memcmp works this way:
>
> #include <stdio.h>
> #include <string.h>
>
> int main(int argc, char **argv)
> {
> char *str1 = "foo";
> char *str2 = "foobar";
>
> return memcmp(str1, str2, strlen(str2));
> }
>
> gcc -O3 -fsanitize=undefined -fsanitize=address -o foo foo.c
>
> denkenz(a)localhost ~ $ ./foo
> =================================================================
> ==2423==ERROR: AddressSanitizer: global-buffer-overflow on address
> 0x557ae18f2aa4 at pc 0x7f8fb0838cc4 bp 0x7ffc3b8f5e40 sp 0x7ffc3b8f55e8
> READ of size 6 at 0x557ae18f2aa4 thread T0
> #0 0x7f8fb0838cc3
> (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4+0xafcc3)
> #1 0x7f8faf6c3ed9 in __libc_start_main (/lib64/libc.so.6+0x20ed9)
> #2 0x557ae18f28c9 in _start (/home/denkenz/foo+0x8c9)
Ok, then let me go back to strncmp although a simple local
implementation of memcmp might be faster here.
I wasn't able to run the unit tests with ASAN so far and valgrind had
no complaints.
Best regards
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-08-16 1:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-15 4:02 [PATCH] dbus: Fix subpath comparisons in object tree walk Andrew Zaborowski
2018-08-15 16:55 ` Denis Kenzior
2018-08-15 19:22 ` Andrew Zaborowski
2018-08-15 20:44 ` Denis Kenzior
2018-08-16 1:12 ` Andrew Zaborowski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.