SUNRPC: Fix a NULL pointer deref in trace_svc_stats_latency()
authorChuck Lever <chuck.lever@oracle.com>
Thu, 5 Aug 2021 19:11:24 +0000 (15:11 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Tue, 17 Aug 2021 15:47:53 +0000 (11:47 -0400)
Some paths through svc_process() leave rqst->rq_procinfo set to
NULL, which triggers a crash if tracing happens to be enabled.

Fixes: 89ff87494c6e ("SUNRPC: Display RPC procedure names instead of proc numbers")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/sunrpc/svc.h
include/trace/events/sunrpc.h
net/sunrpc/svc.c

index ab9afbf..f0f846f 100644 (file)
@@ -527,6 +527,7 @@ void                   svc_wake_up(struct svc_serv *);
 void              svc_reserve(struct svc_rqst *rqstp, int space);
 struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 char *            svc_print_addr(struct svc_rqst *, char *, size_t);
+const char *      svc_proc_name(const struct svc_rqst *rqstp);
 int               svc_encode_result_payload(struct svc_rqst *rqstp,
                                             unsigned int offset,
                                             unsigned int length);
index 861f199..d323f5a 100644 (file)
@@ -1642,7 +1642,7 @@ TRACE_EVENT(svc_process,
                __field(u32, vers)
                __field(u32, proc)
                __string(service, name)
-               __string(procedure, rqst->rq_procinfo->pc_name)
+               __string(procedure, svc_proc_name(rqst))
                __string(addr, rqst->rq_xprt ?
                         rqst->rq_xprt->xpt_remotebuf : "(null)")
        ),
@@ -1652,7 +1652,7 @@ TRACE_EVENT(svc_process,
                __entry->vers = rqst->rq_vers;
                __entry->proc = rqst->rq_proc;
                __assign_str(service, name);
-               __assign_str(procedure, rqst->rq_procinfo->pc_name);
+               __assign_str(procedure, svc_proc_name(rqst));
                __assign_str(addr, rqst->rq_xprt ?
                             rqst->rq_xprt->xpt_remotebuf : "(null)");
        ),
@@ -1918,7 +1918,7 @@ TRACE_EVENT(svc_stats_latency,
        TP_STRUCT__entry(
                __field(u32, xid)
                __field(unsigned long, execute)
-               __string(procedure, rqst->rq_procinfo->pc_name)
+               __string(procedure, svc_proc_name(rqst))
                __string(addr, rqst->rq_xprt->xpt_remotebuf)
        ),
 
@@ -1926,7 +1926,7 @@ TRACE_EVENT(svc_stats_latency,
                __entry->xid = be32_to_cpu(rqst->rq_xid);
                __entry->execute = ktime_to_us(ktime_sub(ktime_get(),
                                                         rqst->rq_stime));
-               __assign_str(procedure, rqst->rq_procinfo->pc_name);
+               __assign_str(procedure, svc_proc_name(rqst));
                __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
        ),
 
index d2d412d..5aa2633 100644 (file)
@@ -1650,6 +1650,21 @@ u32 svc_max_payload(const struct svc_rqst *rqstp)
 }
 EXPORT_SYMBOL_GPL(svc_max_payload);
 
+/**
+ * svc_proc_name - Return RPC procedure name in string form
+ * @rqstp: svc_rqst to operate on
+ *
+ * Return value:
+ *   Pointer to a NUL-terminated string
+ */
+const char *svc_proc_name(const struct svc_rqst *rqstp)
+{
+       if (rqstp && rqstp->rq_procinfo)
+               return rqstp->rq_procinfo->pc_name;
+       return "unknown";
+}
+
+
 /**
  * svc_encode_result_payload - mark a range of bytes as a result payload
  * @rqstp: svc_rqst to operate on