mac80211: fix a regression in generating radiotap headers
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		| @@ -0,0 +1,49 @@ | ||||
| From: Johannes Berg <johannes.berg@intel.com> | ||||
| Date: Tue, 9 Nov 2021 10:02:04 +0100 | ||||
| Subject: [PATCH] mac80211: fix radiotap header generation | ||||
|  | ||||
| In commit 8c89f7b3d3f2 ("mac80211: Use flex-array for radiotap header | ||||
| bitmap") we accidentally pointed the position to the wrong place, so | ||||
| we overwrite a present bitmap, and thus cause all kinds of trouble. | ||||
|  | ||||
| To see the issue, note that the previous code read: | ||||
|  | ||||
|   pos = (void *)(it_present + 1); | ||||
|  | ||||
| The requirement now is that we need to calculate pos via it_optional, | ||||
| to not trigger the compiler hardening checks, as: | ||||
|  | ||||
|   pos = (void *)&rthdr->it_optional[...]; | ||||
|  | ||||
| Rewriting the original expression, we get (obviously, since that just | ||||
| adds "+ x - x" terms): | ||||
|  | ||||
|   pos = (void *)(it_present + 1 + rthdr->it_optional - rthdr->it_optional) | ||||
|  | ||||
| and moving the "+ rthdr->it_optional" outside to be used as an array: | ||||
|  | ||||
|   pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional]; | ||||
|  | ||||
| The original is off by one, fix it. | ||||
|  | ||||
| Cc: stable@vger.kernel.org | ||||
| Fixes: 8c89f7b3d3f2 ("mac80211: Use flex-array for radiotap header bitmap") | ||||
| Reported-by: Sid Hayn <sidhayn@gmail.com> | ||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
| Tested-by: Sid Hayn <sidhayn@gmail.com> | ||||
| Reviewed-by: Kees Cook <keescook@chromium.org> | ||||
| Link: https://lore.kernel.org/r/20211109100203.c61007433ed6.I1dade57aba7de9c4f48d68249adbae62636fd98c@changeid | ||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
| --- | ||||
|  | ||||
| --- a/net/mac80211/rx.c | ||||
| +++ b/net/mac80211/rx.c | ||||
| @@ -364,7 +364,7 @@ ieee80211_add_rx_radiotap_header(struct | ||||
|  	 * the compiler to think we have walked past the end of the | ||||
|  	 * struct member. | ||||
|  	 */ | ||||
| -	pos = (void *)&rthdr->it_optional[it_present - rthdr->it_optional]; | ||||
| +	pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional]; | ||||
|   | ||||
|  	/* the order of the following fields is important */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau