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 d7c2c5c98c ("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 <jouni@codeaurora.org>
This commit is contained in:
Vamsi Krishna 2020-02-12 15:14:59 +05:30 committed by Jouni Malinen
parent 5551317834
commit 75d0ec4702

View file

@ -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++;
}