Commit 46ca8dd2 authored by Chuck Lever's avatar Chuck Lever
Browse files

SUNRPC: Tighten bounds checking in svc_rqst_replace_page



svc_rqst_replace_page() builds the Reply buffer by advancing
rq_next_page through the response page range. The bounds
check validates rq_next_page against the full rq_pages array,
but the valid range for rq_next_page is

  [rq_respages, rq_page_end].

Use those bounds instead.

This is correct today because rq_respages and rq_page_end
both point into rq_pages, and it prepares for a subsequent
change that separates the Reply page array from rq_pages.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 2a83ffc5
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -934,11 +934,11 @@ svc_set_num_threads(struct svc_serv *serv, unsigned int min_threads,
EXPORT_SYMBOL_GPL(svc_set_num_threads);

/**
 * svc_rqst_replace_page - Replace one page in rq_pages[]
 * svc_rqst_replace_page - Replace one page in rq_respages[]
 * @rqstp: svc_rqst with pages to replace
 * @page: replacement page
 *
 * When replacing a page in rq_pages, batch the release of the
 * When replacing a page in rq_respages, batch the release of the
 * replaced pages to avoid hammering the page allocator.
 *
 * Return values:
@@ -947,8 +947,8 @@ EXPORT_SYMBOL_GPL(svc_set_num_threads);
 */
bool svc_rqst_replace_page(struct svc_rqst *rqstp, struct page *page)
{
	struct page **begin = rqstp->rq_pages;
	struct page **end = &rqstp->rq_pages[rqstp->rq_maxpages];
	struct page **begin = rqstp->rq_respages;
	struct page **end = rqstp->rq_page_end;

	if (unlikely(rqstp->rq_next_page < begin || rqstp->rq_next_page > end)) {
		trace_svc_replace_page_err(rqstp);