All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stanislav Fomichev <stfomichev@gmail.com>
To: Mina Almasry <almasrymina@google.com>
Cc: Stanislav Fomichev <sdf@fomichev.me>,
	netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, linux-kernel@vger.kernel.org,
	ncardwell@google.com, kuniyu@amazon.com, dsahern@kernel.org,
	horms@kernel.org, willemb@google.com, kaiyuanz@google.com
Subject: Re: [PATCH net] tcp: devmem: properly export MSG_CTRUNC to userspace
Date: Tue, 18 Feb 2025 14:14:53 -0800	[thread overview]
Message-ID: <Z7UGXdx-Wx4-mkXK@mini-arch> (raw)
In-Reply-To: <CAHS8izOu33xLNQUJZgKq971f+rfzqaj0f5CG8sQ7U3pKth_QBA@mail.gmail.com>

On 02/18, Mina Almasry wrote:
> On Tue, Feb 18, 2025 at 1:17 PM Stanislav Fomichev <stfomichev@gmail.com> wrote:
> >
> > On 02/18, Mina Almasry wrote:
> > > On Tue, Feb 18, 2025 at 11:40 AM Stanislav Fomichev <sdf@fomichev.me> wrote:
> > > >
> > > > Currently, we report -ETOOSMALL (err) only on the first iteration
> > > > (!sent). When we get put_cmsg error after a bunch of successful
> > > > put_cmsg calls, we don't signal the error at all. This might be
> > > > confusing on the userspace side which will see truncated CMSGs
> > > > but no MSG_CTRUNC signal.
> > > >
> > > > Consider the following case:
> > > > - sizeof(struct cmsghdr) = 16
> > > > - sizeof(struct dmabuf_cmsg) = 24
> > > > - total cmsg size (CMSG_LEN) = 40 (16+24)
> > > >
> > > > When calling recvmsg with msg_controllen=60, the userspace
> > > > will receive two(!) dmabuf_cmsg(s), the first one will
> > >
> > > The intended API in this scenario is that the user will receive *one*
> > > dmabuf_cmgs. The kernel will consider that data in that frag to be
> > > delivered to userspace, and subsequent recvmsg() calls will not
> > > re-deliver that data. The next recvmsg() call will deliver the data
> > > that we failed to put_cmsg() in the current call.
> > >
> > > If you receive two dmabuf_cmsgs in this scenario, that is indeed a
> > > bug. Exposing CMSG_CTRUNC could be a good fix. It may indicate to the
> > > user "ignore the last cmsg we put, because it got truncated, and
> > > you'll receive the full cmsg on the next recvmsg call". We do need to
> > > update the docs for this I think.
> > >
> > > However, I think a much much better fix is to modify put_cmsg() so
> > > that we only get one dmabuf_cmsgs in this scenario, if possible. We
> > > could add a strict flag to put_cmsg(). If (strict == true &&
> > > msg->controlllen < cmlen), we return an error instead of putting a
> > > truncated cmsg, so that the user only sees one dmabuf_cmsg in this
> > > scenario.
> > >
> > > Is this doable?
> >
> > Instead of modifying put_cmsg(), I can have an extra check before
> > calling it to make sure the full entry fits. Something like:
> >
> 
> Yes, that sounds perfect. I would add a new helper, maybe
> put_dmabuf_cmsg, that checks that we have enough space before calling
> the generic put_cmsg().
> 
> > --- a/net/ipv4/tcp.c
> > +++ b/net/ipv4/tcp.c
> > @@ -2498,6 +2498,11 @@ static int tcp_recvmsg_dmabuf(struct sock *sk, const struct sk_buff *skb,
> >                                 offset += copy;
> >                                 remaining_len -= copy;
> >
> > +                               if (msg.msg_controllen < CMSG_LEN(sizeof(dmabuf_cmsg))) {
> > +                                       err = -ETOOSMALL;
> > +                                       goto out;
> > +                               }
> > +
> >                                 err = put_cmsg(msg, SOL_SOCKET,
> >                                                SO_DEVMEM_DMABUF,
> >                                                sizeof(dmabuf_cmsg),
> >
> > WDYT? I'll still probably remove '~MSG_CTRUNC' parts as well to avoid
> > confusion.
> 
> Yes, since we check there is enough space before calling put_cmsg(),
> it should now become impossible for put_cmsg() to set MSG_CTRUNC
> anyway, so the check in tcp_recvmsg_dmabuf() becomes an unnecessary
> defensive check that should be removed.
> 
> Thanks for catching this!

Perfect, thanks for a quick review!

---
pw-bot: cr

      reply	other threads:[~2025-02-18 22:14 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-18 19:40 [PATCH net] tcp: devmem: properly export MSG_CTRUNC to userspace Stanislav Fomichev
2025-02-18 20:10 ` Mina Almasry
2025-02-18 21:17   ` Stanislav Fomichev
2025-02-18 21:51     ` Mina Almasry
2025-02-18 22:14       ` Stanislav Fomichev [this message]

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=Z7UGXdx-Wx4-mkXK@mini-arch \
    --to=stfomichev@gmail.com \
    --cc=almasrymina@google.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kaiyuanz@google.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@amazon.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ncardwell@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    --cc=willemb@google.com \
    /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.