Commit Graph

6234 Commits

Author SHA1 Message Date
Andrew Zaborowski 4d2176df29 handshake: Allow event handler to free handshake
Like in ap.c, allow the event callback to mark the handshake state as
destroyed, without causing invalid accesses after the callback has
returned.  In this case the crash was because try_handshake_complete
needed to access members of handshake_state after emitting the event,
as well as access the netdev, which also has been destroyed:

==257707== Invalid read of size 8
==257707==    at 0x408C85: try_handshake_complete (netdev.c:1487)
==257707==    by 0x408C85: try_handshake_complete (netdev.c:1480)
(...)
==257707==  Address 0x4e187e8 is 856 bytes inside a block of size 872 free'd
==257707==    at 0x484621F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==257707==    by 0x437887: ap_stop_handshake (ap.c:151)
==257707==    by 0x439793: ap_del_station (ap.c:316)
==257707==    by 0x43EA92: ap_station_disconnect (ap.c:3411)
==257707==    by 0x43EA92: ap_station_disconnect (ap.c:3399)
==257707==    by 0x454276: p2p_group_event (p2p.c:1006)
==257707==    by 0x439147: ap_event (ap.c:281)
==257707==    by 0x4393AB: ap_new_rsna (ap.c:390)
==257707==    by 0x4393AB: ap_handshake_event (ap.c:1010)
==257707==    by 0x408C7F: try_handshake_complete (netdev.c:1485)
==257707==    by 0x408C7F: try_handshake_complete (netdev.c:1480)
(...)
2022-01-21 08:51:49 -06:00
Andrew Zaborowski 079489bd66 ap: Don't defer ap_reset when ap_free called in event
Previously we added logic to defer doing anything in ap_free() to after
the AP event handler has returned so that ap_event() has a chance to
inform whoever called it that the ap_state has been freed.  But there's
also a chance that the event handler is destroying both the AP and the
netdev it runs on, so after the handler has returned we can't even use
netdev_get_wdev_id or netdev_get_ifindex.  The easiest solution seems to
be to call ap_reset() in ap_free() even if we're within an event handler
to ensure we no longer need any external objects.  Also make sure
ap_reset() can be called multiple times.

Another option would be to watch for NETDEV_WATCH_EVENT_DEL and remove
our reference to the netdev (because there's no need actually call
l_rtnl_ifaddr_delete or frame_watch_wdev_remove if the netdev was
destroyed -- frame_watch already tracks netdev removals), or to save
just the ifindex and the wdev id...
2022-01-21 08:51:04 -06:00
Denis Kenzior 4a3792da7e doc: Rename device-provisioning.txt
device-provisioning.txt is an API file, so name it accordingly.
2022-01-20 14:22:32 -06:00
James Prestwood 76b6aa66b3 dpp: fix dpp_offchannel_start corner cases
The purpose of this was to have a single utility to both cancel an
existing offchannel operation (if one exists) and start a new one.

The problem was the previous offchannel operation was being canceled
first which opened up the radio work queue to other items. This is
not desireable as, for example, a scan would end up breaking the
DPP protocol most likely.

Starting the new offchannel then canceling is the correct order of
operations but to do this required saving the new ID, canceling, then
setting offchannel_id to the new ID so dpp_presence_timeout wouldn't
overwrite the new ID to zero.

This also removes an explicit call to offchannel_cancel which is
already done by dpp_offchannel_start.
2022-01-20 14:19:56 -06:00
James Prestwood 8ce491fbb2 dpp: use own/peer naming rather than i/r
Several members are named based on initiator/responder (i/r)
terminology. Eventually both initiator and responder will be
supported so rename these members to use own/peer naming
instead.
2022-01-20 14:11:44 -06:00
James Prestwood 52fafd8f5b dpp-util: use ell/asn1-private.h for ASN1 generation
ASN1 parsing will soon be required which will need some utilities in
asn1-private.h. To avoid duplication include this private header and
replace the OID's with the defined structures as well as remove the
duplicated macros.
2022-01-20 13:59:37 -06:00
James Prestwood 73cd3578d9 station: fix OWE scan logic with autoconnect
station_set_scan_results takes an autoconnect flag which was being
set true in both regular/quick autoconnect scans. Since OWE networks
are processed after setting the scan results IWD could end up
connecting to a network before all the OWE hidden networks are
populated.

To fix this regular/quick autoconnect results will set the flag to
false, then process OWE networks, then start autoconnect. If any
OWE network scans are pending station_autoconnect_start will fail
but will pick back up after the hidden OWE scan.
2022-01-20 13:54:14 -06:00
James Prestwood ac78076663 eap-pwd: add length checks for fragmented packets 2022-01-20 13:49:32 -06:00
James Prestwood e500511490 test-runner: set --show-leak-kinds=all
This enables leak checks starting in main() which were previously
ignored.
2022-01-19 17:17:26 -06:00
James Prestwood f70c0cb2f9 dpp: free nl80211 object on exit 2022-01-19 17:17:26 -06:00
James Prestwood c3b18c44e0 auto-t: roam test to simulate reported crash
During investigation another separate crash was found. The original is
caused by a disconnect event coming in after a neighbor report scan
was completed (roam failed) during the full roam scan.

The second crash is caused by a disconnect coming in during a full
roam scan when no neighbor report scan was ever issued.
2022-01-19 16:37:51 -06:00
James Prestwood 301a55c8c3 auto-t: hostapd.py: add remove_neighbor() 2022-01-19 16:37:51 -06:00
James Prestwood 2c6bb735ac station: send debug "roam-scan-triggered" event 2022-01-19 16:37:51 -06:00
Denis Kenzior 62978ef0fb scan: Allow scan_cancel for finished requests
scan_request_failed and scan_finished remove the finished scan_request
from the request queue right away, before calling the callback.  This
breaks those clients that rely on scan_cancel working on such requests
(i.e. to force the destroy callback to be invoked synchronously, see
a0911ca778 ("station: Make sure roam_scan_id is always canceled").

Fix this by removing the scan_request from the request queue after
invoking the callback.  Also provide a re-entrancy guard that will make
sure that the scan_request isn't removed in scan_cancel itself.
2022-01-19 16:37:21 -06:00
Denis Kenzior bef550df81 scan: Simplify scan_finished
There are similar operations being performed but with different
callbacks and userdata, depending on whether 'sr' is NULL or not.
Optimize the function flow slightly to make if-else unnecessary.

While here, update the comment.  periodic scans are now scheduled only
based on the periodic timeout timer.
2022-01-19 16:37:21 -06:00
Denis Kenzior 1fd6aba43c scan: Remove redundant call
l_queue_remove is already called in scan_request_failed.
2022-01-19 16:37:21 -06:00
Denis Kenzior c125d2b003 scan: Move triggered variable to scan_request 2022-01-19 16:37:21 -06:00
Denis Kenzior 6051a14952 scan: Don't callback on SCAN_ABORTED
If periodic scan is active and we receive a SCAN_ABORTED event, we would
still invoke the periodic scan callback with an error.  This is rather
pointless since the periodic scan callback cannot do anything useful
with this information.  Fix that.
2022-01-19 16:37:21 -06:00
Denis Kenzior 280620d7ac scan: Remove unreachable code
We should never reach a point where NEW_SCAN_RESULTS or SCAN_ABORTED are
received before a corresponding TRIGGER_SCAN is received.  Even if this
does happen, there's no harm from processing the commands anyway.
2022-01-19 16:37:21 -06:00
Denis Kenzior c4c86ea1df scan: Move 'started' to scan_request
This makes it a little easier to book-keep the started variable.  Since
scan_request already has a 'passive' bit-field, there should be no
storage penalty.
2022-01-19 16:37:21 -06:00
Denis Kenzior af375a1cde scan: Don't crash on scan_cancel
If scan_cancel is called on a scan_request that is 'finished' but with
the GET_SCAN command still in flight, it will trigger a crash as
follows:
Received Deauthentication event, reason: 2, from_ap: true
src/station.c:station_disconnect_event() 11
src/station.c:station_disassociated() 11
src/station.c:station_reset_connection_state() 11
src/station.c:station_roam_state_clear() 11
src/scan.c:scan_cancel() Trying to cancel scan id 6 for wdev 200000002
src/scan.c:scan_cancel() Scan is at the top of the queue, but not triggered
src/scan.c:get_scan_done() get_scan_done
Aborting (signal 11) [/home/denkenz/iwd-master/src/iwd]
++++++++ backtrace ++++++++
 #0  0x7f9871aef3f0 in /lib64/libc.so.6
 #1  0x41f470 in station_roam_scan_notify() at /home/denkenz/iwd-master/src/station.c:2285
 #2  0x43936a in scan_finished() at /home/denkenz/iwd-master/src/scan.c:1709
 #3  0x439495 in get_scan_done() at /home/denkenz/iwd-master/src/scan.c:1739
 #4  0x4bdef5 in destroy_request() at /home/denkenz/iwd-master/ell/genl.c:676
 #5  0x4c070b in l_genl_family_cancel() at /home/denkenz/iwd-master/ell/genl.c:1960
 #6  0x437069 in scan_cancel() at /home/denkenz/iwd-master/src/scan.c:842
 #7  0x41dc2e in station_roam_state_clear() at /home/denkenz/iwd-master/src/station.c:1594
 #8  0x41dd2b in station_reset_connection_state() at /home/denkenz/iwd-master/src/station.c:1619
 #9  0x41dea4 in station_disassociated() at /home/denkenz/iwd-master/src/station.c:1644

The happens because get_scan_done callback is still called as a result of
l_genl_cancel.  Add a re-entrancy guard in the form of 'canceled'
variable in struct scan_request.  If set, get_scan_done will skip invoking
scan_finished.

It isn't clear what 'l_queue_peek_head() == results->sr' check was trying
to accomplish.  If GET_SCAN dump was scheduled, then it should be
reported.  Drop it.
2022-01-19 16:37:21 -06:00
Denis Kenzior e1593df4bd scan: Call scan_finished if results->sr is NULL
results->sr is set to NULL for 'opportunistic' scans which were
triggered externally.  See scan_notify() for details.  However,
get_scan_done would only invoke scan_finished (and thus the periodic
scan callback sc->sp.callback) only if the scan queue was empty.  It
should do so in all cases.
2022-01-19 16:37:21 -06:00
James Prestwood 188d09af42 dpp-util: fix dpp_point_to_asn1 compressed type
The point type was being hard coded to 0x3 (BIT1) which may have resulted
in the peer subtracting Y from P when reading in the point (depending on
if Y was odd or not).

Instead set the compressed type to whatever avoids the subtraction which
both saves IWD from needing to do it, as well as the peer.
2022-01-18 15:01:59 -06:00
Denis Kenzior 44a7bc640b scan: Remove work_started variable
With the introduction of wiphy_radio_work_is_running we no longer need
to track this separately.
2022-01-18 13:04:12 -06:00
Denis Kenzior b20774a55f station: Add some additional debugs 2022-01-14 16:30:26 -06:00
Denis Kenzior 9d0c5222aa AUTHORS: Mention Diederik's contributions 2022-01-14 12:47:31 -06:00
Diederik de Haas a5495978b7 dpp: fix 2 spelling errors 2022-01-14 12:46:56 -06:00
Diederik de Haas 8a09cd3472 doc: fix overriden -> overridden 2022-01-14 12:46:16 -06:00
Denis Kenzior 60e0a5073a anqputil: Avoid potential overflow
When checking that the length is valid, avoid potentially overflowing
    'anqp + l_get_le16(anqp + 2)'
2022-01-14 12:08:01 -06:00
Denis Kenzior d2ca0c4f18 dpp-util: Avoid potential overflow
When checking that the length is valid, avoid potentially overflowing
'iter->pos + len'
2022-01-14 12:07:57 -06:00
Denis Kenzior eddcc4c5b6 erp: Fix off by one error
The intent of this check is to make sure that at least 2 bytes are
available for reading.  However, the unintended consequence is that tags
with a zero length at the end of input would be rejected.

While here, rework the check to be more resistant to potential
overflow conditions.
2022-01-14 10:22:41 -06:00
Denis Kenzior 938e056896 erp: Avoid potential overflow
When checking that the length is valid, avoid potentially overflowing
'start + len'
2022-01-14 09:49:47 -06:00
Denis Kenzior 5e9178b9de wscutil: Avoid potential overflow
When checking that the length is valid, avoid potentially overflowing
'start + len'
2022-01-14 09:49:47 -06:00
Denis Kenzior 22faf3482c eap-ttls: Avoid potential overflow
When checking that the length is valid, avoid potentially overflowing
'start + len'
2022-01-14 09:49:47 -06:00
Denis Kenzior 01960ec66e erp: Fix comment that is > 80 chars wide 2022-01-14 09:49:47 -06:00
James Prestwood b7b0b4eb02 auto-t: improve testDPP reliablity
First disconnect wpa_supplicant to make sure it wont miss frames if
it decides to connect. Also alter the order of things for the
configurator test so autoconnect doesn't start until after hostapd
is up (avoids additional scanning and delays)
2022-01-12 12:46:27 -06:00
James Prestwood c5fb68bb2e auto-t: wpas.py: add disconnect() 2022-01-12 12:46:24 -06:00
James Prestwood 627e54eb20 auto-t: wpas.py: increase timeout for auth protocol
Sometimes wpa_supplicant takes some time to respond to the initial
presence anouncements.
2022-01-12 12:46:21 -06:00
James Prestwood bbfcdf0ac7 dpp: stop periodic scanning when starting DPP 2022-01-12 12:46:18 -06:00
James Prestwood 34348fcb42 scan: don't print notification if sc is not found
If this scan is not for any IWD wdev's don't print
2022-01-12 12:46:15 -06:00
James Prestwood ceb6da81b3 dpp: support retransmitting frames with no ACK
The DPP spec says nothing about how to handle re-transmits but it
was found in testing this can happen relatively easily for a few
reasons.

If the configurator requests a channel switch but does not get onto
the new channel quick enough the enrollee may have already sent the
authenticate response and it was missed. Also by nature of how the
kernel goes offchannel there are moments in time between ROC when
the card is idle and not receiving any frames.

Only frames where there was no ACK will be retransmitted. If the
peer received the frame and dropped it resending the same frame wont
do any good.
2022-01-12 12:45:05 -06:00
James Prestwood 2435adc33b nl80211util: support ATTR_FRAME in parse_attrs() 2022-01-12 12:44:56 -06:00
James Prestwood 7a3d4dabb1 auto-t: add a few more DPP tests
This adds 3 more tests:
 - Channel switch during authentication
 - Scan after configuring
 - Retransmit auth frames
2022-01-12 10:05:16 -06:00
James Prestwood 692d137a21 auto-t: wpas.py: add configurator_remove
wpa_supplicant has a limited number of configurator IDs, and its
good practice to remove them after we are done.
2022-01-12 10:05:13 -06:00
James Prestwood 0b36f497c5 auto-t: wpas.py: add freq argument to configurator_start
This forces the configurator to request a new channel during the
authentication protocol.
2022-01-12 10:05:11 -06:00
James Prestwood 9aae6e2c16 dpp: pass dpp_sm to dpp_send_frame
The SM has the wdev_id already, so rather than using that or looking
up just pass the dpp_sm directly.
2022-01-12 09:38:06 -06:00
James Prestwood fc61e5fe46 dpp: rework order of operations after being configured
Now the result is sent immediately. Prior a connect attempt or
scan could have started, potentially losing this frame. In addition
the offchannel operation is cancelled after sending the result
which will allow the subsequent connect or scan to happen much
faster since it doesn't have to wait for ROC to expire.
2022-01-12 09:33:57 -06:00
James Prestwood 94afeabc18 dpp: put no station device print behind else if
The previous (incorrect) else was removed since it ended up
printing in most cases since the if clause returned. This should
have been an else if conditional from the start and only print if the
station device was not found.
2022-01-12 09:32:37 -06:00
James Prestwood 0c8d3f106a dpp: don't send StartEnrollee reply until offchannel starts
IWD may be in the middle of some long operation, e.g. scanning.
If the URI is returned before IWD is ready, a configurator could
start sending frames and IWD either wont receive them, or will
be unable to respond quickly.
2022-01-12 09:32:13 -06:00
James Prestwood c78573b468 auto-t: wpas.py: read DPP event until expected result
Controlling wpa_supplicant/hostapd from a text based interface is
problematic in that there is no way of knowing if an event corresponds
to a request. In certain cases if wpa_s/hostapd is sending out multiple
events and we make a request, a random event may come back after the
request, but before the actual result.

To fix this, at least for this specific case, we can continue to read
from the socket until the result is numeric.
2022-01-12 09:27:45 -06:00