On Thu, 2019-01-10 at 07:28 +0100, Greg Kroah-Hartman wrote: > l2cap_get_conf_opt can handle a "default" message type, but it needs to > be verified that it really is the correct type (CONF_EFS or CONF_RFC) > before passing it back to the caller. To do this we need to check the > return value of this call now and handle the error correctly up the > stack. [] > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c [] > @@ -3324,7 +3328,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data > void *endptr = data + data_size; > void *req = chan->conf_req; > int len = chan->conf_len; > - int type, hint, olen; > + int type, hint, olen, err; err doesn't seem the right name for any of these as the return is now negative only when there is an error. Maybe opt_len instead. > unsigned long val; > struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; > struct l2cap_conf_efs efs; > @@ -3336,7 +3340,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data > BT_DBG("chan %p", chan); > > while (len >= L2CAP_CONF_OPT_SIZE) { > - len -= l2cap_get_conf_opt(&req, &type, &olen, &val); > + err = l2cap_get_conf_opt(&req, &type, &olen, &val); > + if (err < 0) > + return err; > + len -= err; especially as you subtract the positive return not an error value. > > hint = type & L2CAP_CONF_HINT; > type &= L2CAP_CONF_MASK; > @@ -3539,7 +3546,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, > struct l2cap_conf_req *req = data; > void *ptr = req->data; > void *endptr = data + size; > - int type, olen; > + int type, olen, err; > unsigned long val; > struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; > struct l2cap_conf_efs efs; > @@ -3547,7 +3554,10 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, > BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); > > while (len >= L2CAP_CONF_OPT_SIZE) { > - len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); > + err = l2cap_get_conf_opt(&rsp, &type, &olen, &val); > + if (err < 0) > + return err; > + len -= err; > > switch (type) { > case L2CAP_CONF_MTU: > @@ -3707,7 +3717,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) > > static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) > { > - int type, olen; > + int type, olen, err; > unsigned long val; > /* Use sane default values in case a misbehaving remote device > * did not send an RFC or extended window size option. > @@ -3727,7 +3737,10 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) > return; > > while (len >= L2CAP_CONF_OPT_SIZE) { > - len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); > + err = l2cap_get_conf_opt(&rsp, &type, &olen, &val); > + if (err < 0) > + return; > + len -= err; > > switch (type) { > case L2CAP_CONF_RFC: