summaryrefslogtreecommitdiff
path: root/include/trace/events/sunrpc.h
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2023-03-18 00:09:20 +0300
committerChuck Lever <chuck.lever@oracle.com>2023-04-26 16:05:01 +0300
commit0f5162480bd25bd97b91c9153db7afbd89698804 (patch)
treea273f9e1648e80256d5e4b9321f624d0a9424cd4 /include/trace/events/sunrpc.h
parent376bcd9b37632cf191711a68aa25ab42f0048c2e (diff)
downloadlinux-0f5162480bd25bd97b91c9153db7afbd89698804.tar.xz
NFSD: Watch for rq_pages bounds checking errors in nfsd_splice_actor()
There have been several bugs over the years where the NFSD splice actor has attempted to write outside the rq_pages array. This is a "should never happen" condition, but if for some reason the pipe splice actor should attempt to walk past the end of rq_pages, it needs to terminate the READ operation to prevent corruption of the pointer addresses in the fields just beyond the array. A server crash is thus prevented. Since the code is not behaving, the READ operation returns -EIO to the client. None of the READ payload data can be trusted if the splice actor isn't operating as expected. Suggested-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org>
Diffstat (limited to 'include/trace/events/sunrpc.h')
-rw-r--r--include/trace/events/sunrpc.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 3ca54536f8f7..5a3bb42e1f50 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1790,6 +1790,31 @@ DEFINE_EVENT(svc_rqst_status, svc_send,
TP_PROTO(const struct svc_rqst *rqst, int status),
TP_ARGS(rqst, status));
+TRACE_EVENT(svc_replace_page_err,
+ TP_PROTO(const struct svc_rqst *rqst),
+
+ TP_ARGS(rqst),
+ TP_STRUCT__entry(
+ SVC_RQST_ENDPOINT_FIELDS(rqst)
+
+ __field(const void *, begin)
+ __field(const void *, respages)
+ __field(const void *, nextpage)
+ ),
+
+ TP_fast_assign(
+ SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
+
+ __entry->begin = rqst->rq_pages;
+ __entry->respages = rqst->rq_respages;
+ __entry->nextpage = rqst->rq_next_page;
+ ),
+
+ TP_printk(SVC_RQST_ENDPOINT_FORMAT " begin=%p respages=%p nextpage=%p",
+ SVC_RQST_ENDPOINT_VARARGS,
+ __entry->begin, __entry->respages, __entry->nextpage)
+);
+
TRACE_EVENT(svc_stats_latency,
TP_PROTO(
const struct svc_rqst *rqst