From 75d0ec47021c893eeecf1c19d06e6a5620565433 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Date: Wed, 12 Feb 2020 15:14:59 +0530 Subject: [PATCH] P2P: Fix a possible buffer overflow in struct p2p_reg_class Avoid adding more than P2P_MAX_REG_CLASSES operating classes or P2P_MAX_REG_CLASS_CHANNELS channels while populating P2P channels. The current limits on the operating classes or channels per operating class could be hit in some case (mainly, with 6 GHz, but in theory, with a 2.4/5/60 GHz capable device as well). If the local driver advertised a larger number of supported operarting classes or channels per operating class, the construction of the struct p2p_reg_class instances could have resulted in writing beyond the end of the buffer and ending up corrupting memory around the struct p2p_config. This could result in unexpected behavior in some other operations that used corrupted memory, e.g., generation of a P2P Channel List failing (with validation code stopping the process to avoid writing beyond the end of the message buffer) due to not having sufficient buffer space for the corrupted data. This issue is triggered only based on information from the local driver (mainly based on addition of support for 6 GHz band operating classes), so the issue cannot be triggered based on received frames or any other remote information. The issue was introduced by commit d7c2c5c98c4f ("AP: Add initial support for 6 GHz band") which added the operating class 131 which has sufficiently large number of channels to go beyond the P2P_MAX_REG_CLASS_CHANNELS limit. Signed-off-by: Jouni Malinen --- wpa_supplicant/p2p_supplicant.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 974e3e0ed..41d50f397 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3736,23 +3736,32 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw); if (res == ALLOWED) { if (reg == NULL) { + if (cla == P2P_MAX_REG_CLASSES) + continue; wpa_printf(MSG_DEBUG, "P2P: Add operating class %u", o->op_class); reg = &chan->reg_class[cla]; cla++; reg->reg_class = o->op_class; } + if (reg->channels == P2P_MAX_REG_CLASS_CHANNELS) + continue; reg->channel[reg->channels] = ch; reg->channels++; } else if (res == NO_IR && wpa_s->conf->p2p_add_cli_chan) { if (cli_reg == NULL) { + if (cli_cla == P2P_MAX_REG_CLASSES) + continue; wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)", o->op_class); cli_reg = &cli_chan->reg_class[cli_cla]; cli_cla++; cli_reg->reg_class = o->op_class; } + if (cli_reg->channels == + P2P_MAX_REG_CLASS_CHANNELS) + continue; cli_reg->channel[cli_reg->channels] = ch; cli_reg->channels++; }