Bug 154336 - abuse of va_args, SEGV.
abuse of va_args, SEGV.
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: NetworkManager (Show other bugs)
4
All Linux
medium Severity medium
: ---
: ---
Assigned To: Dan Williams
:
Depends On:
Blocks: FC4Blocker
  Show dependency treegraph
 
Reported: 2005-04-10 05:47 EDT by David Woodhouse
Modified: 2007-11-30 17:11 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-05-05 14:55:36 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
patch to remove varargs from nm_completion functions (16.27 KB, patch)
2005-04-21 14:49 EDT, Peter Jones
no flags Details | Diff

  None (edit)
Description David Woodhouse 2005-04-10 05:47:53 EDT
Description of problem:
Recent versions of NetworkManager fail to connect to the wireless network using
a prism54 adapter. First they fail to spot the access point, and then if you
force them to connect to the appropriate network using NetworkManagerInfo, they
segfault.

Starting program:
/home/dwmw2/working/pkgs/NetworkManager/devel/NetworkManager-0.4/src/NetworkManager
--no-daemon
[Thread debugging using libthread_db enabled]
[New Thread 805460256 (LWP 4653)]
NetworkManager: <information>   starting...
Detaching after fork from child process 4656.
Detaching after fork from child process 4657.
Detaching after fork from child process 4663.
Detaching after fork from child process 4673.
NetworkManager: <information>   eth1: Driver 'prism54' does not support wireless
scanning.
        NetworkManager will not be able to fully use the card.
NetworkManager: <information>   eth1: Driver support level for 'prism54' is
fully-supported
[New Thread 815949024 (LWP 4720)]
NetworkManager: <information>   nm_device_new(): waiting for device's worker
thread to start
NetworkManager: nm_completion_boolean_test: assertion `condition != NULL'
failedNetworkManager: <information>   nm_device_new(): device's worker thread
started, continuing.
NetworkManager: <information>   Now managing wireless device 'eth1'.
Detaching after fork from child process 4721.
Detaching after fork from child process 4722.
NetworkManager: <information>   eth0: Driver 'gem' does not support carrier
detection.
        You must switch to it manually.
NetworkManager: <information>   eth0: Driver support level for 'gem' is
fully-supported
[New Thread 826434784 (LWP 4723)]
NetworkManager: <information>   nm_device_new(): waiting for device's worker
thread to start
NetworkManager: nm_completion_boolean_test: assertion `condition != NULL'
failedNetworkManager: <information>   nm_device_new(): device's worker thread
started, continuing.
NetworkManager: <information>   Now managing wired device 'eth0'.
Detaching after fork from child process 4724.
Detaching after fork from child process 4725.
Detaching after fork from child process 4726.
Detaching after fork from child process 4727.
Detaching after fork from child process 4728.
Detaching after fork from child process 4729.
NetworkManager: <information>   named started with pid 4729
[New Thread 836945120 (LWP 4730)]
Detaching after fork from child process 4734.
NetworkManager: <information>   Updating allowed wireless network lists.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 4735.
Detaching after fork from child process 4736.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 4737.
Detaching after fork from child process 4738.
NetworkManager: <debug info>    [1113125946.912156]  (): NetworkManagerInfo
triggered update of wireless network 'Baythorne Wavelan'
NetworkManager: <information>   FORCE: device
'/org/freedesktop/NetworkManager/Devices/eth1', network 'Baythorne Wavelan'
Detaching after fork from child process 4739.
Detaching after fork from child process 4740.
NetworkManager: <debug info>    [1113125948.983093]  (): Forcing AP 'Baythorne
Wavelan'
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: <information>   Activation (eth1/wireless): found access point
'Baythorne Wavelan' to use.
NetworkManager: <information>   Activation (eth1/wireless): access point
'Baythorne Wavelan' is encrypted, and a key exists.  No new key needed.
NetworkManager: <information>   Activation (eth1/wireless): using essid
'Baythorne Wavelan', with Shared Key authentication.
NetworkManager: nm_device_get_frequency: assertion `dev != NULL' failed
NetworkManager: nm_device_wireless_is_associated: assertion `dev != NULL'
failedNetworkManager: nm_device_get_essid: assertion `dev != NULL' failed
NetworkManager: nm_device_activation_should_cancel: assertion `dev != NULL' failed

Program received signal SIGSEGV, Segmentation fault.
---Type <return> to continue, or q <return> to quit---
[Switching to Thread 815949024 (LWP 4720)]
nm_dwwfl_test (tries=Variable "tries" is not available.
) at NetworkManagerDevice.c:1925
1925            if ((cur_freq == *last_freq) && assoc && !strcmp (essid, cur_essid))
(gdb) p last_freq
$1 = (double *) 0x0
(gdb) bt
#0  nm_dwwfl_test (tries=Variable "tries" is not available.
) at NetworkManagerDevice.c:1925
#1  0x1001a69c in nm_v_wait_for_completion_or_timeout (max_tries=-1,
max_time=Variable "max_time" is not available.
)
    at NetworkManagerUtils.c:541
#2  0x40044284 in ?? ()
#3  0x1001a9b4 in nm_wait_for_timeout (max_time=Variable "max_time" is not
available.
) at NetworkManagerUtils.c:588
#4  0x100162c0 in nm_device_activate (user_data=Variable "user_data" is not
available.
)
    at NetworkManagerDevice.c:1984
#5  0x44044482 in ?? ()
#6  0x0f7b3a9c in g_child_watch_add () from /usr/lib/libglib-2.0.so.0
#7  0x0f7b08d4 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#8  0x0f7b4bac in g_main_context_check () from /usr/lib/libglib-2.0.so.0
#9  0x0f7b5004 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#10 0x10012b50 in nm_device_worker (user_data=Variable "user_data" is not available.
) at NetworkManagerDevice.c:501
#11 0x0f7d57f0 in g_static_private_free () from /usr/lib/libglib-2.0.so.0
#12 0x0fd65868 in start_thread () from /lib/libpthread.so.0
#13 0x0f7d57f0 in g_static_private_free () from /usr/lib/libglib-2.0.so.0
#14 0x00000000 in ?? ()
Comment 1 David Woodhouse 2005-04-10 05:50:34 EDT
Another SEGV with pointers from va_args if I switch to an orinoco card. I wonder
if I should be blaming the compiler?

Starting program:
/home/dwmw2/working/pkgs/NetworkManager/devel/NetworkManager-0.4/src/NetworkManager
--no-daemon
[Thread debugging using libthread_db enabled]
[New Thread 805460256 (LWP 4850)]
NetworkManager: <information>   starting...
Detaching after fork from child process 4853.
Detaching after fork from child process 4854.
Detaching after fork from child process 4860.
Detaching after fork from child process 4870.
NetworkManager: <information>   eth0: Driver 'gem' does not support carrier
detection.
        You must switch to it manually.
NetworkManager: <information>   eth0: Driver support level for 'gem' is
fully-supported
[New Thread 815949024 (LWP 4920)]
NetworkManager: <information>   nm_device_new(): waiting for device's worker
thread to start
NetworkManager: nm_completion_boolean_test: assertion `condition != NULL'
failedNetworkManager: <information>   nm_device_new(): device's worker thread
started, continuing.
NetworkManager: <information>   Now managing wired device 'eth0'.
Detaching after fork from child process 4921.
Detaching after fork from child process 4922.
Detaching after fork from child process 4923.
Detaching after fork from child process 4924.
Detaching after fork from child process 4925.
Detaching after fork from child process 4926.
NetworkManager: <information>   named started with pid 4926
[New Thread 826459360 (LWP 4927)]
Detaching after fork from child process 4931.
NetworkManager: <information>   Updating allowed wireless network lists.
NetworkManager: <debug info>    [1113126492.102754]  (): New device added (hal
udi is '/org/freedesktop/Hal/devices/pcmcia_342_2').
NetworkManager: <debug info>    [1113126492.956778]  (): New device added (hal
udi is '/org/freedesktop/Hal/devices/net_00_02_2d_07_a4_2a').
NetworkManager: <information>   eth1: Driver '(null)' does not support wireless
scanning.
        NetworkManager will not be able to fully use the card.
NetworkManager: <information>   eth1: Driver '(null)' does not support wireless
scanning.
        NetworkManager will not be able to fully use the card.
[New Thread 836945120 (LWP 4974)]
NetworkManager: <information>   nm_device_new(): waiting for device's worker
thread to start
NetworkManager: nm_completion_boolean_test: assertion `condition != NULL'
failedNetworkManager: <information>   nm_device_new(): device's worker thread
started, continuing.
NetworkManager: <information>   Now managing wireless device 'eth1'.
Detaching after fork from child process 4996.
Detaching after fork from child process 4997.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5073.
Detaching after fork from child process 5074.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5075.
Detaching after fork from child process 5076.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5077.
Detaching after fork from child process 5078.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5079.
Detaching after fork from child process 5080.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5081.
Detaching after fork from child process 5082.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5083.
Detaching after fork from child process 5084.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5085.
Detaching after fork from child process 5086.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5087.
Detaching after fork from child process 5088.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
NetworkManager: <information>   Activation (eth1) IP configuration/DHCP
unsuccessful!  Ending activation...
NetworkManager: <information>   Activation (eth1) ended.
NetworkManager: <information>   Activation (eth1) failed for access point ((none))
Detaching after fork from child process 5090.
Detaching after fork from child process 5091.
NetworkManager: <information>       SWITCH: best device changed
NetworkManager: <information>   Activation (eth1) started...
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)

---Type <return> to continue, or q <return> to quit---
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 836945120 (LWP 4974)]
nm_wa_test (tries=1, args=0x31e2b120) at NetworkManagerDevice.c:2297
2297            *err = TRUE;
(gdb) p err
$1 = (gboolean *) 0xf332ae0
(gdb) bt
#0  nm_wa_test (tries=1, args=0x31e2b120) at NetworkManagerDevice.c:2297
#1  0x1001a678 in nm_v_wait_for_completion_or_timeout (max_tries=-1,
    max_time=0x0, interval_usecs=20000, test_func=0x10015230 <nm_wa_test>,
    action_func=0, args=0x31e2b120) at NetworkManagerUtils.c:528
#2  0x44044482 in ?? ()
#3  0x1001a91c in nm_wait_for_completion (max_tries=Variable "max_tries" is not
available.
)
    at NetworkManagerUtils.c:572
#4  0x10016020 in nm_device_activate (user_data=Variable "user_data" is not
available.
)
    at NetworkManagerDevice.c:2404
#5  0x44044482 in ?? ()
#6  0x0f7b3a9c in g_child_watch_add () from /usr/lib/libglib-2.0.so.0
#7  0x0f7b08d4 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#8  0x0f7b4bac in g_main_context_check () from /usr/lib/libglib-2.0.so.0
#9  0x0f7b5004 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#10 0x10012b50 in nm_device_worker (user_data=Variable "user_data" is not available.
) at NetworkManagerDevice.c:501
#11 0x0f7d57f0 in g_static_private_free () from /usr/lib/libglib-2.0.so.0
#12 0x0fd65868 in start_thread () from /lib/libpthread.so.0
#13 0x0f7d57f0 in g_static_private_free () from /usr/lib/libglib-2.0.so.0
#14 0x00000000 in ?? ()
(gdb)
Comment 2 David Woodhouse 2005-04-10 06:09:10 EDT
Something is scribbling on the arguments to nm_wa_test() between the first and
second calls to 'test_func' in nm_v_wait_for_completion_or_timeout().

NetworkManager: <information>   nm_device_activate_wireless:2406 calls
nm_wa_test with NULL, 0x1004fbe0, 0x30a25140, 0x30a25144
NetworkManager: <information>   nm_v_wait_for_completion_or_timeout:528 calls
test_func, try 0 args 0x30a25120
NetworkManager: <information>   nm_wa_test, 0x1004fbe0 0x30a25140 0x30a25144
NetworkManager: <information>   Activation (eth1/wireless): waiting for access
point. (attempt 0)
NetworkManager: <information>   nm_v_wait_for_completion_or_timeout:528 calls
test_func, try 1 args 0x30a25120
NetworkManager: <information>   nm_wa_test, 0x81 (nil) (nil)
NetworkManager: nm_wa_test: assertion `best_ap != NULL' failed
Comment 3 David Woodhouse 2005-04-10 13:29:15 EDT
It isn't the compiler, it's the code. Says the man page for va_arg:

       If  ap is passed to a function that uses va_arg(ap,type) then the value
       of ap is undefined after the return of that function.

Hence the value of 'args' is undefined by the time you go round the loop in
nm_v_wait_for_completion_or_timeout() for a second time. 

This evil hack makes it work for me for now... don't try this at home.

--- NetworkManagerUtils.c       6 Apr 2005 16:45:48 -0000       1.33
+++ NetworkManagerUtils.c       10 Apr 2005 17:28:23 -0000
@@ -655,6 +655,7 @@
        int try;
        gboolean finished = FALSE;
        struct timeval finish_time;
+       typeof(*args) args_copy = *args;

        g_return_if_fail (test_func || action_func);

@@ -672,6 +673,7 @@
                try++;
                if (test_func)
                {
+                       *args = args_copy;
                        finished = (*test_func)(try, args);
                        if (finished)
                                break;
@@ -684,6 +686,7 @@
                syslog (LOG_INFO, "sleeping or %d usecs", interval_usecs);
 #endif
                g_usleep(interval_usecs);
+               *args = args_copy;
                if (action_func)
                        finished = (*action_func)(try, args);
        }
Comment 4 Dan Williams 2005-04-11 08:02:07 EDT
Peter: so how do we fix this for all the other occurances of varargs stuff?
Comment 5 David Woodhouse 2005-04-11 08:06:45 EDT
First thing that comes to mind is to use a 'void *' instead of a va_list as the
second argument to your action_func and test_func, which is actually a pointer
to a structure containing the arguments. 
Comment 6 Peter Jones 2005-04-21 14:49:50 EDT
Created attachment 113482 [details]
patch to remove varargs from nm_completion functions

'void *' is probably a better solution for the long term.  A patch is attached.


I do wish somebody would fix varargs to actually be useful instead of being lip
service on variable arguments plus inklings towards a gross performance hack.
Comment 7 Colin Walters 2005-04-21 15:16:36 EDT
+       typeof(*args) args_copy = *args;

Use G_VA_COPY.
Comment 8 Dan Williams 2005-05-05 14:55:36 EDT
Has been merged into 0.4-10.cvs20050404 and pushed through beehive.

Note You need to log in before you can comment on or make changes to this bug.