Hi,
On 06/06/18 06:01, Sven Eckelmann wrote:
Hi Antonio,
On Dienstag, 5. Juni 2018 20:31:31 CEST Sven Eckelmann wrote:
cfg80211_get_station is not initializing the memory given as parameter sinfo. The caller has to handle it. Otherwise the filled parameter may be set incorrectly and thus uninitialized memory is used to identify the throughput to an neighbor.
Hm, have to rewrite the commit message to something better. Maybe to something like:
batadv_v_elp_get_throughput is calling cfg80211_get_station with a pointer (sinfo) to some uninitialized memory on the stack. But most of the implementations behind cfg80211_get_station will not initialize sinfo to zero before manipulating it. For example, the member &struct station_info.filled is often only modified by using a read (of possibly uninitialized/random memory), an OR operation and then a write of the new value back to the original memory address. A caller without a preinitialized &struct station_info.filled can then no longer decide which parts of sinfo were filled in by cfg80211_get_station.
The caller of cfg80211_get_station must therefore take care that sinfo (or at least sinfo.filled) is initialized to zero. Otherwise, the caller may tries to read information which was not filled in and is therefore also uninitialized. In batadv_v_elp_get_throughput's case, an invalid "random" expected throughput may be saved for this neighbor and thus the B.A.T.M.A.N V algorithm may switch to non-optimal neighbors for certain destinations.
Fixes: 5c3245172c01 ("batman-adv: ELP - compute the metric based on the estimated throughput") Reported-by: Thomas Lauer holminateur@gmail.com Reported-by: Marcel Schmidt ff.z-casparistrasse@mailbox.org Signed-off-by: Sven Eckelmann sven@narfation.org
This looks fairly reasonable and at a first glance I can confirm that even ieee80211_get_station() does not clear it up before filling it.
However, what do you think about zero'ing the sinfo object directly in cfg80211_get_station()? I think it is safe to assume that no user should store anything in this object before passing it to get_station().
At the same time future users of this API won't be able to hit the same issue we just did.
(At the moment we are the only user of this function in the kernel, therefore changing its behaviour now might still be an option)
Cheers,