Skip to content

Commit 0e716ce

Browse files
dwsusekeithbusch
authored andcommitted
nvmet-trace: avoid dereferencing pointer too early
The first command issued from the host to the target is the fabrics connect command. At this point, neither the target queue nor the controller have been allocated. But we already try to trace this command in nvmet_req_init. Reported by KASAN. Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Daniel Wagner <dwagner@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent 72e8c93 commit 0e716ce

2 files changed

Lines changed: 20 additions & 14 deletions

File tree

drivers/nvme/target/trace.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ const char *nvmet_trace_disk_name(struct trace_seq *p, char *name)
211211
return ret;
212212
}
213213

214-
const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl)
214+
const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id)
215215
{
216216
const char *ret = trace_seq_buffer_ptr(p);
217217

@@ -224,8 +224,8 @@ const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl)
224224
* If we can know the extra data of the connect command in this stage,
225225
* we can update this print statement later.
226226
*/
227-
if (ctrl)
228-
trace_seq_printf(p, "%d", ctrl->cntlid);
227+
if (ctrl_id)
228+
trace_seq_printf(p, "%d", ctrl_id);
229229
else
230230
trace_seq_printf(p, "_");
231231
trace_seq_putc(p, 0);

drivers/nvme/target/trace.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,24 @@ const char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype,
3232
nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \
3333
nvmet_trace_parse_admin_cmd(p, opcode, cdw10)))
3434

35-
const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl);
36-
#define __print_ctrl_name(ctrl) \
37-
nvmet_trace_ctrl_name(p, ctrl)
35+
const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id);
36+
#define __print_ctrl_id(ctrl_id) \
37+
nvmet_trace_ctrl_id(p, ctrl_id)
3838

3939
const char *nvmet_trace_disk_name(struct trace_seq *p, char *name);
4040
#define __print_disk_name(name) \
4141
nvmet_trace_disk_name(p, name)
4242

4343
#ifndef TRACE_HEADER_MULTI_READ
44-
static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req)
44+
static inline u16 nvmet_req_to_ctrl_id(struct nvmet_req *req)
4545
{
46-
return req->sq->ctrl;
46+
/*
47+
* The queue and controller pointers are not valid until an association
48+
* has been established.
49+
*/
50+
if (!req->sq || !req->sq->ctrl)
51+
return 0;
52+
return req->sq->ctrl->cntlid;
4753
}
4854

4955
static inline void __assign_req_name(char *name, struct nvmet_req *req)
@@ -63,7 +69,7 @@ TRACE_EVENT(nvmet_req_init,
6369
TP_ARGS(req, cmd),
6470
TP_STRUCT__entry(
6571
__field(struct nvme_command *, cmd)
66-
__field(struct nvmet_ctrl *, ctrl)
72+
__field(u16, ctrl_id)
6773
__array(char, disk, DISK_NAME_LEN)
6874
__field(int, qid)
6975
__field(u16, cid)
@@ -76,7 +82,7 @@ TRACE_EVENT(nvmet_req_init,
7682
),
7783
TP_fast_assign(
7884
__entry->cmd = cmd;
79-
__entry->ctrl = nvmet_req_to_ctrl(req);
85+
__entry->ctrl_id = nvmet_req_to_ctrl_id(req);
8086
__assign_req_name(__entry->disk, req);
8187
__entry->qid = req->sq->qid;
8288
__entry->cid = cmd->common.command_id;
@@ -90,7 +96,7 @@ TRACE_EVENT(nvmet_req_init,
9096
),
9197
TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, "
9298
"meta=%#llx, cmd=(%s, %s)",
93-
__print_ctrl_name(__entry->ctrl),
99+
__print_ctrl_id(__entry->ctrl_id),
94100
__print_disk_name(__entry->disk),
95101
__entry->qid, __entry->cid, __entry->nsid,
96102
__entry->flags, __entry->metadata,
@@ -104,23 +110,23 @@ TRACE_EVENT(nvmet_req_complete,
104110
TP_PROTO(struct nvmet_req *req),
105111
TP_ARGS(req),
106112
TP_STRUCT__entry(
107-
__field(struct nvmet_ctrl *, ctrl)
113+
__field(u16, ctrl_id)
108114
__array(char, disk, DISK_NAME_LEN)
109115
__field(int, qid)
110116
__field(int, cid)
111117
__field(u64, result)
112118
__field(u16, status)
113119
),
114120
TP_fast_assign(
115-
__entry->ctrl = nvmet_req_to_ctrl(req);
121+
__entry->ctrl_id = nvmet_req_to_ctrl_id(req);
116122
__entry->qid = req->cq->qid;
117123
__entry->cid = req->cqe->command_id;
118124
__entry->result = le64_to_cpu(req->cqe->result.u64);
119125
__entry->status = le16_to_cpu(req->cqe->status) >> 1;
120126
__assign_req_name(__entry->disk, req);
121127
),
122128
TP_printk("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x",
123-
__print_ctrl_name(__entry->ctrl),
129+
__print_ctrl_id(__entry->ctrl_id),
124130
__print_disk_name(__entry->disk),
125131
__entry->qid, __entry->cid, __entry->result, __entry->status)
126132

0 commit comments

Comments
 (0)