В ядре Linux устранена следующая уязвимость:
wifi: mac80211: привязан S1G TIM PVB к элементу TIM
ieee80211_s1g_check_tim() анализирует частичное виртуальное растровое изображение (PVB) S1G
получил элемент TIM. TIM передается как полезная нагрузка элемента:
ieee802_11_parse_elems_full() хранит elems->tim = elem->data и
elems->tim_len = elem->datalen (net/mac80211/parse.c), поэтому допустимые байты
являются [тим, тим + тим_лен). При обходе закодированных блоков функция передает ходоку конец
страж (const u8 *)tim + tim_len + 2, т. е. на два байта после конца
элемент. ieee80211_s1g_find_target_block() выполняет цикл while (ptr + 1 <= end)
и разыменовывает ptr (и помощники ieee80211_s1g_len_*() для каждого режима читают
*ptr), поэтому он может читать до двух байтов за пределами элемента TIM —
чтение за пределами границ соседних данных skb/кучи, когда TIM является последним
элемент в кадре. +2, похоже, учитывает идентификатор/длину элемента.
заголовок, но Тим уже указывает за этот заголовок на полезную нагрузку элемента, поэтому
дополнение неверно.
Передайте правильный конец элемента (const u8 *)tim + tim_len.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: wifi: mac80211: bound S1G TIM PVB walk to the TIM element ieee80211_s1g_check_tim() parses the S1G Partial Virtual Bitmap (PVB) of a received TIM element. The TIM is handed in as the element payload: ieee802_11_parse_elems_full() stores elems->tim = elem->data and elems->tim_len = elem->datalen (net/mac80211/parse.c), so the valid bytes are [tim, tim + tim_len). When walking the encoded blocks the function passes the walker an end sentinel of (const u8 *)tim + tim_len + 2, i.e. two bytes past the end of the element. ieee80211_s1g_find_target_block() loops while (ptr + 1 <= end) and dereferences ptr (and the per-mode ieee80211_s1g_len_*() helpers read *ptr), so it can read up to two bytes beyond the TIM element -- an out-of-bounds read of adjacent skb/heap data when the TIM is the last element in the frame. The +2 appears to account for the element id/len header, but tim already points past that header at the element payload, so the addend is wrong. Pass the correct element end, (const u8 *)tim + tim_len.