In preparation for FORTIFY_SOURCE performing compile-time and run-time field bounds checking for memcpy(), memmove(), and memset(), avoid intentionally writing across neighboring fields. Use struct_group() around members addr1, addr2, and addr3 in struct ieee80211_hdr so they can be referenced together. This will allow memcpy() and sizeof() to more easily reason about sizes, improve readability, and avoid future warnings about writing beyond the end of addr1. "pahole" shows no size nor member offset changes to struct ieee80211_hdr. "objdump -d" shows no meaningful object code changes (i.e. only source line number induced differences and optimizations). Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> --- drivers/staging/rtl8723bs/core/rtw_security.c | 5 +++-- drivers/staging/rtl8723bs/core/rtw_xmit.c | 5 +++-- include/linux/ieee80211.h | 8 +++++--- net/wireless/lib80211_crypt_ccmp.c | 3 ++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index a99f439328f1..be7cf42855a1 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -1421,8 +1421,9 @@ u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe) ClearRetry(BIP_AAD); ClearPwrMgt(BIP_AAD); ClearMData(BIP_AAD); - /* conscruct AAD, copy address 1 to address 3 */ - memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + /* conscruct AAD, copy address 1 through address 3 */ + BUILD_BUG_ON(sizeof(pwlanhdr->addrs) != 3 * ETH_ALEN); + memcpy(BIP_AAD + 2, &pwlanhdr->addrs, 3 * ETH_ALEN); if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey , BIP_AAD, ori_len, mic)) diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 79e4d7df1ef5..cb47db784130 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -1198,8 +1198,9 @@ s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, s ClearRetry(BIP_AAD); ClearPwrMgt(BIP_AAD); ClearMData(BIP_AAD); - /* conscruct AAD, copy address 1 to address 3 */ - memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + /* conscruct AAD, copy address 1 through address 3 */ + BUILD_BUG_ON(sizeof(pwlanhdr->addrs) != 3 * ETH_ALEN); + memcpy(BIP_AAD + 2, &pwlanhdr->addrs, 3 * ETH_ALEN); /* copy management fram body */ memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len); /* calculate mic */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index a6730072d13a..d7932b520aaf 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -297,9 +297,11 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2) struct ieee80211_hdr { __le16 frame_control; __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; + struct_group(addrs, + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + ); __le16 seq_ctrl; u8 addr4[ETH_ALEN]; } __packed __aligned(2); diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index 6a5f08f7491e..21d7c39bb394 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c @@ -136,7 +136,8 @@ static int ccmp_init_iv_and_aad(const struct ieee80211_hdr *hdr, pos = (u8 *) hdr; aad[0] = pos[0] & 0x8f; aad[1] = pos[1] & 0xc7; - memcpy(aad + 2, hdr->addr1, 3 * ETH_ALEN); + BUILD_BUG_ON(sizeof(hdr->addrs) != 3 * ETH_ALEN); + memcpy(aad + 2, &hdr->addrs, ETH_ALEN); pos = (u8 *) & hdr->seq_ctrl; aad[20] = pos[0] & 0x0f; aad[21] = 0; /* all bits masked */ -- 2.30.2