If the sm object (or the handshake object) is NULL, don't call the
corresponding function.
0 0x7fb6cd37da80 in /lib64/libc.so.6
1 0x414764 in eapol_sm_destroy() at eapol.c:673
2 0x42e402 in ap_sta_free() at ap.c:97
3 0x439dbe in l_queue_clear() at /home/parallels/wrk/iwd/ell/queue.c:109
4 0x439e09 in l_queue_destroy() at /home/parallels/wrk/iwd/ell/queue.c:83
5 0x42e4bf in ap_reset() at ap.c:132
6 0x42e519 in ap_free() at ap.c:147
7 0x447456 in interface_instance_free() at /home/parallels/wrk/iwd/ell/dbus-service.c:513
8 0x449be0 in _dbus_object_tree_remove_interface() at /home/parallels/wrk/iwd/ell/dbus-service.c:1595
9 0x449ced in _dbus_object_tree_object_destroy() at /home/parallels/wrk/iwd/ell/dbus-service.c:787
10 0x40fb8c in device_free() at device.c:2717
11 0x405cdb in netdev_free() at netdev.c:605
12 0x439dbe in l_queue_clear() at /home/parallels/wrk/iwd/ell/queue.c:109
13 0x439e09 in l_queue_destroy() at /home/parallels/wrk/iwd/ell/queue.c:83
14 0x40aac2 in netdev_shutdown() at netdev.c:4483
15 0x403b75 in iwd_shutdown() at main.c:80
16 0x43d9f3 in signal_callback() at /home/parallels/wrk/iwd/ell/signal.c:83
17 0x43d4ee in l_main_iterate() at /home/parallels/wrk/iwd/ell/main.c:376
18 0x43d5ac in l_main_run() at /home/parallels/wrk/iwd/ell/main.c:419
19 0x40379b in main() at main.c:454
20 0x7fb6cd36788a in /lib64/libc.so.6
Until now network.c managed the list of network_info structs including
for known networks and networks that are seen in at least one device's
scan results, with the is_known flag to distinguish known networks.
Each time the list was processed though the code was either interested
in one subset of networks or the other. Split the list into a Known
Networks list and the list of other networks seen in scans. Move all
code related to Known Networks to knownnetworks.c, this simplifies
network.h. It also gets rid of network_info_get_known which actually
returned the list of all network_infos (not just for known networks),
which logically should have been private to network.c. Update device.c
and scan.c to use functions specific to Known Networks instead of
filtering the lists by the is_known flag.
This will also allow knownnetworks.c to export DBus objects and/or
properties for the Known Networks information because it now knows when
Known Networks are added, removed or modified by IWD.
The return value from network_connected is not checked and even if one
of the storage operations fails the function should probably continue
so only print a message on error.
If the device mode it toggled from 'ap' back to 'station' without actually
starting the access point ap_free attempts to zero out the psk, which
causes a crash because it had never been allocated (Start() never was
called). Since ap->psk is actually never used this was removed. Also added
a memset to zero out the pmk on cleanup.
This is the crash observed:
++++++++ backtrace ++++++++
0 0x7f6ffe978a80 in /lib64/libc.so.6
1 0x7f6ffe9d6766 in /lib64/libc.so.6
2 0x42dd51 in memset() at /usr/include/bits/string3.h:90
3 0x42ddd9 in ap_free() at src/ap.c:144
4 0x445ec6 in interface_instance_free() at ell/dbus-service.c:513
5 0x448650 in _dbus_object_tree_remove_interface() at ell/dbus-service.c:1595
6 0x40d980 in device_set_mode_sta() at src/device.c:2113
7 0x447d4c in properties_set() at ell/dbus-service.c:1861
8 0x448a33 in _dbus_object_tree_dispatch() at ell/dbus-service.c:1691
9 0x442587 in message_read_handler() at ell/dbus.c:285
10 0x43cac9 in io_callback() at ell/io.c:123
11 0x43bf5e in l_main_iterate() at ell/main.c:376
12 0x43c01c in l_main_run() at ell/main.c:419
13 0x40379d in main() at src/main.c:460
14 0x7f6ffe96288a in /lib64/libc.so.6
+++++++++++++++++++++++++++
- wsc module does not need nl80211 any longer, so remove it.
- Move wsc_init & wsc_exit declarations to iwd.h and remove wsc.h
- re-arrange how wsc_init & wsc_exit is called inside main.c.
The plugin_exit was in the wrong place, it should be triggered in case
genl creation fails. Also adhoc_exit was in the wrong sequence compared
to _init()
Rather than have device.c manage the creation/removal of
AP/AdHoc interfaces this new event was introduced. Now
anyone can listen for device events and if the mode changes
handle accordingly. This fixes potential memory leaks
in WSC when switching modes as well.
These will issue a JOIN/LEAVE_IBSS to the kernel. There is
a TODO regarding network configuration. For now, only the
SSID is configurable. This configuration is also required
for AP, but needs to be thought out. Since the current
AP Dbus API has nothing related to configuration items
such as freq/channel or RSN elements they are hard coded,
and will be for Ad-Hoc as well (for now).
Now that the device mode can be changed, netdev must check that
the iftype is correct before starting a connection or disconnecting.
netdev_connect, netdev_connect_wsc, and netdev_disconnect now check
that the iftype is station before continuing.
With the introduction of Ad-Hoc, its not as simple as choosing
aa/spa addresses when setting the keys. Since Ad-Hoc acts as
both the authenticator and supplicant we must check how the netdev
address relates to the particular handshake object as well as
choose the correct key depending on the value of the AA/SPA address.
802.11 states that the higher of the two addresses is to be used
to set the key for the Ad-Hoc connection.
A simple helper was added to choose the correct addressed based on
netdev type and handshake state. netdev_set_tk also checks that
aa > spa in the handshake object when in Ad-Hoc mode. If this is
true then the keys from that handshake are used, otherwise return
and the other handshake key will be used (aa will be > spa).
The station/ap mode behaves exactly the same as before.
For Ad-Hoc networks, the kernel takes care of auth/assoc
and issues a NEW_STATION event when that is complete. This
provides a way to notify when NEW_STATION events occur as
well as forward the MAC of the station to Ad-Hoc.
The two new API's added:
- netdev_station_watch_add()
- netdev_station_watch_remove()
When the EAPOL-Key data field is encrypted using AES Wrap, check
that the data field is large enough before calculating the expected
plaintext length.
Previously, if the encrypted data field was smaller than 8 bytes, an
integer underflow would occur when calculating the expected plaintext
data length. This would cause iwd to try to allocate a huge amount of
memory, which causes it to abort and terminate. If the data field was
equal to 8 bytes, iwd would try to allocate 0 bytes of memory, making
l_new return NULL, which subsequently causes iwd to crash on a NULL
pointer deference.
Reported-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
triggered flag was being reset to false in all cases. However, due to
how scan_finished logic works, it should have remained true if no more
commands were left to be sent (e.g. the scan was finished).
Having hidden SSIDs or SSIDs with non-UTF8 characters around make iwd
flood the logs with messages. Make iwd less verbose and show these
messages with enabled debug output only.
In addition, the periodic scan can now alternate between the
active or passive modes. The active mode is enabled by existence of
the known hidden networks and observation of them in the
previous scan result.
To support an auto-connect for the hidden networks and having
a limited number of SSIDs that can be appended into a probe
request, introduced a concept of a command batch. Now, scan request
may consist of a series of commands. The commands in the batch
are triggered sequentially. Once we are notified about the
results from a previous command, a consequent command in the
batch is triggered. The collective results are reported once
the batch is complete. On a command failure, the batch
processing is canceled and scan request is removed
Rework the logic slightly to simplify the need for error labels. Also
the connect_pending variable might not have been properly reset to NULL
in case of error, so make sure we reset it prior to calling into
network_connect_new_hidden_network
1) Change signature of process_bss to return a confirmation
that bss has been added to a network otherwise we can
discard it.
2) Implements logic for the discovery and connection to
a hidden network.
This removes the need for duplicate code in AP/netdev for issuing
a DEL_STATION command. Now AP can issue a DEL_STATION with
netdev_del_station, and specify to either disassociate or deauth
depending on state.
If netdev fails to set the keys, there was no way for device/ap to
know. A new handshake event was added for this. The key setting
failure function was also fixed to support both AP/station iftypes.
It will now automatically send either a disconnect or del_station
depending on the interface type.
In similar manner, netdev_handshake_failed was also modified to
support both AP/station iftypes. Now, any handshake event listeners
should call netdev_handshake_failed upon a handshake failure
event, including AP.
If device is already disconnected or in autoconnect mode, don't return
an error if .Disconnect is called. Instead simply silently return
success after disabling autoconnect.
==1058== 231 (32 direct, 199 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 10
==1058== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1058== by 0x452472: l_malloc (util.c:62)
==1058== by 0x456324: l_settings_new (settings.c:83)
==1058== by 0x427D45: storage_network_open (storage.c:262)
==1058== by 0x42806C: network_settings_load (network.c:75)
==1058== by 0x428C2F: network_autoconnect (network.c:490)
==1058== by 0x4104E9: device_autoconnect_next (device.c:194)
==1058== by 0x410E38: device_set_scan_results (device.c:393)
==1058== by 0x410EFA: new_scan_results (device.c:414)
==1058== by 0x424A6D: scan_finished (scan.c:1012)
==1058== by 0x424B88: get_scan_done (scan.c:1038)
==1058== by 0x45DC67: destroy_request (genl.c:134)
This is a fixup for the AP code merge. wsc.c never registered
for handshake events, so in case of failure it was never calling
netdev_handshake_failed, which caused a double free.
Many APs don't send properly zerod key_iv elements in EAPoL-Key frames.
In the past iwd has complained, but this broken behavior is so
prevalent, that it is likely a lost cause.
This patch takes out these warnings
Right now iwd uses Control Port over NL80211 feature if the kernel /
driver supports it. On some kernels this feature is still buggy, so add
an iwd.conf entry to allow the user to override id.
For now the default is to disable this feature until it is more stable.
Now, a user can setup an AP as follows:
- Set device "Mode" to ap (ap interface will appear on bus)
- call "Start()" on AP interface
Issuing "Stop()" on the AP interface will stop and cleanup
the internal AP structures, but the AP interface will remain
up. To shutdown completely the device Mode must be switched
back to station. If the AP interface is running, the Mode can
directly be switched to station without calling Stop; this
has the same effect and will take down the AP interface.
Some of the PEAP server implementation brake the protocol
and don’t set the M flag for the first packet during the
fragmented transmission. To stay compatible with such
devices, we relax this requirement in iwd.
This patch allows alternating between the passive and active
scans taking into consideration an existence of the known
hidden networks and previous observation of them in the scan
results, as well as an ability to randomize the MAC address.
The state of scan is split between the two variables sc->state
and sc->start_cmd_id. Not checking start_cmd_id used to cause
sending a scan request while periodic scan was just triggered
resulting in EBUSY.
Instead of manually sending a deauth/disassociate to a station
during an error or removal, the kernel can do it automatically
with DEL_STATION by including the MGMT_SUBTYPE attribute. This
removes the need for ap_error_deauth_sta and introduces
ap_deauthenticate_sta. Now AP can be explicit when it chooses
to deauth or disassociate.
All handshake packet handling has been removed from ap and
moved to eapol. After association, the AP registers a new
authenticator state machine which handles the AP side of
the handshake. AP will receive a handshake event once the
4-way handshake is complete.
Includes:
- support for handling ptk 2/4 and 4/4. Also sending 1/4 and 3/4.
- new API to register an authenticator SM. This automatically
sends 1/4 to kick off authentication with an sta.
These checks allow both a station and authenticator to use
the same netdev key install functions. For NEW_KEY and
SET_STATION, the iftype is checked and either handshake->aa
or ->spa is used as the station address for the KEY/STATION
commands. Also, in the failure cases, a disconnect command
is issued only if the iftype is station as this doesn't
apply to AP.
Handshake related netdev events were removed in favor of
handshake events. Now events will be emitted on the handshake
object related to the 4-way handshake and key settings. Events
are:
HANDSHAKE_EVENT_STARTED
HANDSHAKE_EVENT_SETTING_KEYS
HANDSHAKE_EVENT_COMPLETE
HANDSHAKE_EVENT_FAILED
Right now, since netdev only operates in station mode, nothing
listens for COMPLETE/FAILED, as device/wsc gets notified by the
connect_cb when the connection was successful. The COMPLETE/
FAILED were added in preperation for AP moving into eapol/netdev.
==1057== 32 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1057== at 0x4C2AF0F: malloc (vg_replace_malloc.c:299)
==1057== by 0x15E9A2: l_malloc (util.c:62)
==1057== by 0x15EA9D: l_memdup (util.c:121)
==1057== by 0x133D9A: network_set_psk (network.c:350)
==1057== by 0x13BD29: wsc_try_credentials (wsc.c:136)
==1057== by 0x13C121: wsc_connect_cb (wsc.c:220)
==1057== by 0x110FAF: netdev_connect_failed (netdev.c:525)
==1057== by 0x16AAF4: process_unicast (genl.c:390)
==1057== by 0x16AF03: received_data (genl.c:509)
==1057== by 0x166CB6: io_callback (io.c:123)
==1057== by 0x16580D: l_main_iterate (main.c:376)
==1057== by 0x16594B: l_main_run (main.c:423)
load_settings ensures that ttls->eap is correctly initialized. So this
code should be treated as an error condition.
We also do not support EAP chaining, so remove that logic as well
dbus_init() currently does not check for the g_dbus object being
properly initialized and this leads to crashes when dbus is not yet
running.
Ensure g_dbus is properly initialized and return false otherwise.
In this case the caller can understand that something went wrong and
stop the initialization procedure.
Program received signal SIGSEGV, Segmentation fault.
0x00005555555bc089 in l_dbus_add_service_watch (dbus=0x0,
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
1621 if (!dbus->name_cache)
(gdb) bt
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
user_data=0x0) at ell/plugin.c:115
function=0x5555555b40fd <plugin_start>,
user_data=0x0) at ell/queue.c:441
version=0x0) at ell/plugin.c:201
src/plugin.c:82
src/main.c:417
When the response structure is generated, not all of the memory was
initialized to 0.
==1045== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==1045== at 0x5134D52: send (in /lib64/libc-2.25.so)
==1045== by 0x168AB5: l_checksum_update (checksum.c:338)
==1045== by 0x186777: tls_write_mac (tls-record.c:58)
==1045== by 0x1869D1: tls_tx_record_plaintext (tls-record.c:120)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
==1045== Syscall param sendmsg(msg.msg_iov[0]) points to uninitialised byte(s)
==1045== at 0x5134E3B: sendmsg (in /lib64/libc-2.25.so)
==1045== by 0x17F691: operate_cipher (cipher.c:356)
==1045== by 0x17F9D8: l_cipher_encrypt (cipher.c:446)
==1045== by 0x186BAA: tls_tx_record_plaintext (tls-record.c:152)
==1045== by 0x186DEA: tls_tx_record (tls-record.c:201)
==1045== by 0x185A3B: l_tls_write (tls.c:2064)
==1045== by 0x14584F: eap_ttls_eap_tx_packet (eap-ttls.c:321)
==1045== by 0x14236C: eap_send_response (eap.c:165)
==1045== by 0x147904: eap_mschapv2_send_response (eap-mschapv2.c:468)
==1045== by 0x147A10: eap_mschapv2_handle_challenge (eap-mschapv2.c:492)
==1045== by 0x147E9A: eap_mschapv2_handle_request (eap-mschapv2.c:615)
==1045== by 0x142693: __eap_handle_request (eap.c:240)
==1045== Address 0x1ffeffe7f9 is on thread 1's stack
==1045== in frame #4, created by tls_tx_record (tls-record.c:177)
==1045== Uninitialised value was created by a stack allocation
==1045== at 0x1477AE: eap_mschapv2_send_response (eap-mschapv2.c:443)
==1045==
Since PEAP & TTLS expect to use eap_check_settings recursively, make
them use a private version of that API that does not perform cleanup and
can contain side-effects.
eap_check_settings itself will guarantee that no side effects happen on
error. It is meant to be used by code outside of the eap subsystem.
Missing secrets are freed by eap_send_agent_req() even in case of
failure, so it was erroneous to try to free them on error.
==1048== Invalid read of size 8
==1048== at 0x1603EC: l_queue_clear (queue.c:101)
==1048== by 0x1603B8: l_queue_destroy (queue.c:82)
==1048== by 0x135328: network_connect_8021x (network.c:943)
==1048== by 0x1354C4: network_connect (network.c:987)
==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690)
==1048== by 0x16D32A: message_read_handler (dbus.c:285)
==1048== by 0x166EC3: io_callback (io.c:123)
==1048== by 0x165A1A: l_main_iterate (main.c:376)
==1048== by 0x165B58: l_main_run (main.c:423)
==1048== by 0x1102DA: main (main.c:458)
==1048== Address 0x5461850 is 0 bytes inside a block of size 24 free'd
==1048== at 0x4C2C13B: free (vg_replace_malloc.c:530)
==1048== by 0x15ED03: l_free (util.c:136)
==1048== by 0x1603C4: l_queue_destroy (queue.c:83)
==1048== by 0x134BD5: eap_secret_request_free (network.c:719)
==1048== by 0x134EF9: eap_send_agent_req (network.c:817)
==1048== by 0x1352F7: network_connect_8021x (network.c:936)
==1048== by 0x1354C4: network_connect (network.c:987)
==1048== by 0x178DD2: _dbus_object_tree_dispatch (dbus-service.c:1690)
==1048== by 0x16D32A: message_read_handler (dbus.c:285)
==1048== by 0x166EC3: io_callback (io.c:123)
==1048== by 0x165A1A: l_main_iterate (main.c:376)
==1048== by 0x165B58: l_main_run (main.c:423)