All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dominique Martinet <asmadeus@codewreck.org>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Christian Schoenebeck <linux_oss@crudebyte.com>,
	JP Kobryn <inwardvessel@gmail.com>,
	ericvh@kernel.org, lucho@ionkov.net, mhiramat@kernel.org,
	mathieu.desnoyers@efficios.com, v9fs@lists.linux.dev,
	linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org,
	kernel-team@meta.com
Subject: Re: [PATCH] 9p: prevent read overrun in protocol dump tracepoint
Date: Sun, 3 Dec 2023 10:33:32 +0900	[thread overview]
Message-ID: <ZWva7DYTPUG95xv8@codewreck.org> (raw)
In-Reply-To: <20231202201409.10223677@rorschach.local.home>

Steven Rostedt wrote on Sat, Dec 02, 2023 at 08:14:09PM -0500:
> > AFAICS __entry is a local variable on stack, and array __entry->line not
> > intialized with zeros, i.e. the dump would contain trash at the end. Maybe
> > prepending memset() before memcpy()?

Well spotted!
Now I'm thinking about it we weren't initializing the source buffer
either back when we had (>32) msize allocations, so these already had
been printing garbage, but might as well get this sorted out while we're
here.

> __entry is a macro that points into the ring buffer that gets allocated
> before this is called. TRACE_EVENT() has a __dynamic_array() field that
> can handle variable length arrays. What you can do is turn this into
> something like:
> 
> TRACE_EVENT(9p_protocol_dump,
>             TP_PROTO(struct p9_client *clnt, struct p9_fcall *pdu),
> 
>             TP_ARGS(clnt, pdu),
> 
>             TP_STRUCT__entry(
>                     __field(    void *,         clnt                            )
>                     __field(    __u8,           type                            )
>                     __field(    __u16,          tag                             )
>                     __dynamic_array(unsigned char,  line, min(pdu->capacity, P9_PROTO_DUMP_SZ) )
>                     ),
> 
>             TP_fast_assign(
>                     __entry->clnt   =  clnt;
>                     __entry->type   =  pdu->id;
>                     __entry->tag    =  pdu->tag;
>                     memcpy(__get_dynamic_array(line), pdu->sdata,
> 			   min(pdu->capacity, P9_PROTO_DUMP_SZ));
>                     ),
>             TP_printk("clnt %lu %s(tag = %d)\n%.3x: %16ph\n%.3x: %16ph\n",
>                       (unsigned long)__entry->clnt, show_9p_op(__entry->type),
>                       __entry->tag, 0, __get_dynamic_array(line), 16,
> 		      __get_dynamic_array(line) + 16)

This was just printing garbage in the previous version but %16ph with a
dynamic alloc would be out of range (even the start of the next buffer,
_get_dynamic_array(line) + 16, can be out of range)

Also, for custom tracepoints e.g. bpftrace the program needs to know how
many bytes can be read safely even if it's just for dumping -- unless
dynamic_array is a "fat pointer" that conveys its own size?
(Sorry didn't take the time to check)

So I see two ways forward:
 - We can give up on the 16 bytes split here, add the size in one of the
fields, and print with %*ph using that size.
 - Or just give up and zero the tail; I'm surprised there's no "memcpy
up to x bytes and zero up to y bytes if required" helper but Christian's
suggestion of always doing memset first is probably not that bad
performance-wise if someone's dumping these out already.

I don't have a hard preference here, what do you think?
-- 
Dominique Martinet | Asmadeus

  reply	other threads:[~2023-12-03  1:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-02  3:04 [PATCH] 9p: prevent read overrun in protocol dump tracepoint JP Kobryn
2023-12-02  4:35 ` asmadeus
2023-12-02  7:19   ` asmadeus
2023-12-02 13:05   ` Christian Schoenebeck
2023-12-03  1:14     ` Steven Rostedt
2023-12-03  1:33       ` Dominique Martinet [this message]
2023-12-03  4:15         ` Steven Rostedt
2023-12-03  5:32           ` Dominique Martinet
2023-12-04 16:20             ` JP Kobryn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZWva7DYTPUG95xv8@codewreck.org \
    --to=asmadeus@codewreck.org \
    --cc=bpf@vger.kernel.org \
    --cc=ericvh@kernel.org \
    --cc=inwardvessel@gmail.com \
    --cc=kernel-team@meta.com \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=linux_oss@crudebyte.com \
    --cc=lucho@ionkov.net \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=v9fs@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.