On Mon, Nov 19, 2018 at 10:11:01AM +0200, Leon Romanovsky wrote: > From: Jason Gunthorpe <jgg@xxxxxxxxxxxx> > > The size meta-data in the prior patch describes the smallest acceptable > buffer for the write() interface. Globally check this in the core code. > > This is necessary in the case of write() methods that have a driver udata > to prevent computing a negative udata buffer length. > > The return code of -ENOSPC is chosen here as some of the handlers already > use this code, however many other handler use EINVAL. > > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx> > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> > drivers/infiniband/core/uverbs_main.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > > diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c > index ac830735f45b..e00c5cc745e5 100644 > +++ b/drivers/infiniband/core/uverbs_main.c > @@ -589,15 +589,18 @@ struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file > } > > static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr, > - struct ib_uverbs_ex_cmd_hdr *ex_hdr, > - size_t count, bool extended) > + struct ib_uverbs_ex_cmd_hdr *ex_hdr, size_t count, > + const struct uverbs_api_write_method *method_elm) > { > - if (extended) { > + if (method_elm->is_ex) { > count -= sizeof(*hdr) + sizeof(*ex_hdr); > > if ((hdr->in_words + ex_hdr->provider_in_words) * 8 != count) > return -EINVAL; > > + if (hdr->in_words * 8 < method_elm->req_size) > + return -ENOSPC; > + > if (ex_hdr->cmd_hdr_reserved) > return -EINVAL; > > @@ -605,6 +608,9 @@ static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr, > if (!hdr->out_words && !ex_hdr->provider_out_words) > return -EINVAL; > > + if (hdr->out_words * 8 < method_elm->resp_size) > + return -ENOSPC; > + > if (!access_ok(VERIFY_WRITE, > u64_to_user_ptr(ex_hdr->response), > (hdr->out_words + ex_hdr->provider_out_words) * 8)) > @@ -621,6 +627,11 @@ static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr, > if (hdr->in_words * 4 != count) > return -EINVAL; > > + if (hdr->in_words * 4 < method_elm->req_size) > + return -ENOSPC; At this point req_size does not include the header, while in_words * 4 does - so this test permits buffers that are too small. My woops Jason