----- On Nov 2, 2017, at 2:46 PM, Alexander Viro viro@xxxxxxxxxxxxxxxxxx wrote: > On Tue, Oct 31, 2017 at 07:00:38PM -0400, Mathieu Desnoyers wrote: >> Comparing a signed return value against an unsigned num_pages >> field performs the comparison as "unsigned", and therefore mistakenly >> considers get_user_pages_fast() errors as success. > > It's worse than that - if you look into the code in question you'll > see > pr_debug("get_user_pages_fast(produce) failed (retval=%d)", > retval); > qp_release_pages(produce_q->kernel_if->u.h.header_page, > retval, false); > err = VMCI_ERROR_NO_MEM; > goto out; > with > static void qp_release_pages(struct page **pages, > u64 num_pages, bool dirty) > { > int i; > > for (i = 0; i < num_pages; i++) { > if (dirty) > set_page_dirty(pages[i]); > > put_page(pages[i]); > pages[i] = NULL; > } > } > > Now, guess what'll happen if you get there with retval being negative? Well this ought to be a pretty long loop... > AFAICS, the right fix is something along the lines of > if (retval != produce_q->kernel_if->num_pages) { > pr_debug("get_user_pages_fast(produce) failed (retval=%d)", > retval); > if (retval > 0) > qp_release_pages(produce_q->kernel_if->u.h.header_page, > retval, false); > err = VMCI_ERROR_NO_MEM; > goto out; > } > and similar for the second caller. Objections? No objection from me, Thanks! Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com