Commit 36d8230b authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

ath10k: add extra check for frame tracing

Frames are logged via tracing in two slices:
header and payload, separately. This is done for
performance reasons when one wants to, e.g.
analyse metadata only of frames only.

If for some reason device delivered a frame buffer
which was sized below what 802.11 header implied
tracing logic would blow doing an invalid memory
accesses.

I've hit this problem when running IBSS on QCA988X
with 999.999.0.636 and tracing at the same time.

Fixes: 5ce8e7fd ("ath10k: handle ieee80211 header and payload tracing separately")
Signed-off-by: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent d9585a92
...@@ -21,11 +21,16 @@ ...@@ -21,11 +21,16 @@
#include "core.h" #include "core.h"
#if !defined(_TRACE_H_) #if !defined(_TRACE_H_)
static inline u32 ath10k_frm_hdr_len(const void *buf) static inline u32 ath10k_frm_hdr_len(const void *buf, size_t len)
{ {
const struct ieee80211_hdr *hdr = buf; const struct ieee80211_hdr *hdr = buf;
return ieee80211_hdrlen(hdr->frame_control); /* In some rare cases (e.g. fcs error) device reports frame buffer
* shorter than what frame header implies (e.g. len = 0). The buffer
* can still be accessed so do a simple min() to guarantee caller
* doesn't get value greater than len.
*/
return min_t(u32, len, ieee80211_hdrlen(hdr->frame_control));
} }
#endif #endif
...@@ -360,13 +365,13 @@ DECLARE_EVENT_CLASS(ath10k_hdr_event, ...@@ -360,13 +365,13 @@ DECLARE_EVENT_CLASS(ath10k_hdr_event,
__string(device, dev_name(ar->dev)) __string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev)) __string(driver, dev_driver_string(ar->dev))
__field(size_t, len) __field(size_t, len)
__dynamic_array(u8, data, ath10k_frm_hdr_len(data)) __dynamic_array(u8, data, ath10k_frm_hdr_len(data, len))
), ),
TP_fast_assign( TP_fast_assign(
__assign_str(device, dev_name(ar->dev)); __assign_str(device, dev_name(ar->dev));
__assign_str(driver, dev_driver_string(ar->dev)); __assign_str(driver, dev_driver_string(ar->dev));
__entry->len = ath10k_frm_hdr_len(data); __entry->len = ath10k_frm_hdr_len(data, len);
memcpy(__get_dynamic_array(data), data, __entry->len); memcpy(__get_dynamic_array(data), data, __entry->len);
), ),
...@@ -387,15 +392,16 @@ DECLARE_EVENT_CLASS(ath10k_payload_event, ...@@ -387,15 +392,16 @@ DECLARE_EVENT_CLASS(ath10k_payload_event,
__string(device, dev_name(ar->dev)) __string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev)) __string(driver, dev_driver_string(ar->dev))
__field(size_t, len) __field(size_t, len)
__dynamic_array(u8, payload, (len - ath10k_frm_hdr_len(data))) __dynamic_array(u8, payload, (len -
ath10k_frm_hdr_len(data, len)))
), ),
TP_fast_assign( TP_fast_assign(
__assign_str(device, dev_name(ar->dev)); __assign_str(device, dev_name(ar->dev));
__assign_str(driver, dev_driver_string(ar->dev)); __assign_str(driver, dev_driver_string(ar->dev));
__entry->len = len - ath10k_frm_hdr_len(data); __entry->len = len - ath10k_frm_hdr_len(data, len);
memcpy(__get_dynamic_array(payload), memcpy(__get_dynamic_array(payload),
data + ath10k_frm_hdr_len(data), __entry->len); data + ath10k_frm_hdr_len(data, len), __entry->len);
), ),
TP_printk( TP_printk(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment