You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have debugged issue a bit and it seems method name of first ("Hello") method on this interface is somehow "corrupted" right after creation of interface descriptor.
Right after:
-- instead "Hello" there is "org.freedesktop.DBus"
Valgrind doesn't complain when sssd is run inside.
If all other methods in initializer are commented out then "Hello" method has correct name in interface decriptor. Add second method - name of frist is "corrupted".
(I put "corrupted" in "" because it doesn't seem to be memory corruption in the sense of buffer overflow or such)
Breakpoint 1, sbus_server_setup_interface (server=0x942260) at /shared/workspace/sssd/src/sbus/server/sbus_server_interface.c:387
... step after bus variable is initialized ...
(gdb) p bus.methods[0] = {name = 0x7f974e127a92 "Hello", handler = {type = SBUS_HANDLER_SYNC, ...}
(gdb) p &bus.methods[0] = (const struct sbus_method *) 0x7fffbb5327d0
... step after paths variable is initialized ...
(gdb) p &paths = (struct sbus_path (*)[2]) 0x7fffbb5327d0
(gdb) p bus.methods[0]$4 = {name = 0x7f974e127b53 "/org/freedesktop/DBus", handler = {type = (unknown: 3142787664), ...}
It seems to be some error in gcc because bus.methods and paths are on the same address. paths overwrites bus.methods that is why we see corrupted name of the method.
Alexey, will you please report bug against gcc and move this forward with them?
tl,dr: problem is bus.methods pointer is assigned to the address of temporary "anonymous" variable located on stack. Naturally, compiler is eligible to re-use stack as soon as this variable goes out of scope.
*** Detailed explanation ***
Invoking gcc -E results in the following bus initialization code (formatted for readability):
struct sbus_interface bus =
({ sbus_interface(
"org.freedesktop.DBus",
((void *)0),
(((const struct sbus_method[])
{
({
/* ... compile time check of function signature omitted */ ;
sbus_method_sync(/* ... full list of params omitted */);
}),
...
Here sbus_method_sync() is a function that returns instance of struct sbus_method by value.
Then array composed of those values on stack is passed as third argument to the fucntion sbus_interface()
Then sbus_interface() stores this pointer in bus.methods field. But as soon as sbus_interface() returns, this temporary array goes out of scope and compiler is fully eligible to re-use stack that was occupied by this array.
This is the reason you see in your test that bus.methods points to paths (and in my test I see that bus.methods points to ... bus itself).
I guess recent version of gcc in Fedora Rawhide makes smarter use of stack and so we now hit by this bug. Before it worked "by luck".
-- sbus_signal() returns struct by value.
The same with properties.
This issue can be fixed with minimal effort either by making sbus_method/sbus_signal/etc factory methods to return object on heap or by changing sbus_interface() function to take const ptrs and copying content. As far as I understand this code is executed only once during initialization, so performance is not an issue. But I am not sure if any of those solutions are fine in overall context of sbus component.
What worries me that there seems to be no easy way to check other "macro-generated" parts of code for similar problems...
I see. You are correct. Using block to return value inside those macros limits scope of the returned pointers. Running gcc with -03 actually hides this problem so it is not reproducible with rawhide rpms.
I see. You are correct. Using block to return value inside those macros limits scope of the returned pointers. Running gcc with -03 actually hides this problem so it is not reproducible with rawhide rpms.
Not sure how did you test that but I can easily reproduce on rawhide with -O2 and -O3
and infopipe does not work even with -O1 or -O0
Cloned from Pagure issue: https://pagure.io/SSSD/sssd/issue/3924
Most of intg-tests started to fail on Fedora Rawhide CI machine recently.
Logs inspection results in the following possible reasons for fails:
I have debugged issue a bit and it seems method name of first ("Hello") method on this interface is somehow "corrupted" right after creation of interface descriptor.
Right after:
descriptor contains following method names:
-- instead "Hello" there is "org.freedesktop.DBus"
Valgrind doesn't complain when
sssd
is run inside.If all other methods in initializer are commented out then "Hello" method has correct name in interface decriptor. Add second method - name of frist is "corrupted".
(I put "corrupted" in "" because it doesn't seem to be memory corruption in the sense of buffer overflow or such)
Comments
Comment from pbrezina at 2019-01-29 10:36:52
It seems to be some error in gcc because
bus.methods
andpaths
are on the same address.paths
overwritesbus.methods
that is why we see corrupted name of the method.Alexey, will you please report bug against gcc and move this forward with them?
Thank you.
Comment from atikhonov at 2019-01-30 14:56:51
Metadata Update from @atikhonov:
Comment from atikhonov at 2019-01-30 17:48:17
I do not think it is error in gcc.
tl,dr: problem is
bus.methods
pointer is assigned to the address of temporary "anonymous" variable located on stack. Naturally, compiler is eligible to re-use stack as soon as this variable goes out of scope.*** Detailed explanation ***
Invoking gcc -E results in the following bus initialization code (formatted for readability):
Here
sbus_method_sync()
is a function that returns instance ofstruct sbus_method
by value.Then array composed of those values on stack is passed as third argument to the fucntion
sbus_interface()
Then
sbus_interface()
stores this pointer inbus.methods
field. But as soon assbus_interface()
returns, this temporary array goes out of scope and compiler is fully eligible to re-use stack that was occupied by this array.This is the reason you see in your test that
bus.methods
points topaths
(and in my test I see thatbus.methods
points to ...bus
itself).I guess recent version of gcc in Fedora Rawhide makes smarter use of stack and so we now hit by this bug. Before it worked "by luck".
Comment from atikhonov at 2019-01-30 17:48:47
Metadata Update from @atikhonov:
Comment from atikhonov at 2019-01-30 17:58:26
Metadata Update from @atikhonov:
Comment from atikhonov at 2019-01-31 10:10:29
Actually, problem is the same with other params of
sbus_interface()
:--
sbus_signal()
returns struct by value.The same with
properties
.This issue can be fixed with minimal effort either by making
sbus_method
/sbus_signal
/etc factory methods to return object on heap or by changingsbus_interface()
function to take const ptrs and copying content. As far as I understand this code is executed only once during initialization, so performance is not an issue. But I am not sure if any of those solutions are fine in overall context of sbus component.What worries me that there seems to be no easy way to check other "macro-generated" parts of code for similar problems...
Comment from pbrezina at 2019-01-31 14:07:17
I see. You are correct. Using block to return value inside those macros limits scope of the returned pointers. Running gcc with
-03
actually hides this problem so it is not reproducible with rawhide rpms.I will provide a fix.
Comment from lslebodn at 2019-02-02 22:42:58
Not sure how did you test that but I can easily reproduce on rawhide with
-O2
and-O3
and infopipe does not work even with
-O1
or-O0
Comment from jhrozek at 2019-02-04 11:03:23
Metadata Update from @jhrozek:
Comment from jhrozek at 2019-02-05 22:14:47
Also not strictly needed but somewhat related:
Comment from jhrozek at 2019-02-05 22:14:48
Metadata Update from @jhrozek:
Comment from jhrozek at 2019-02-05 22:15:04
Metadata Update from @jhrozek:
The text was updated successfully, but these errors were encountered: