Re: [PATCH v2 00/19] `zerocopy` support

Greg Kroah-Hartman <[email protected]>
Newsgroups org.kernel.vger.linux-kbuild,org.kernel.vger.rust-for-linux
Message-ID <2026061224-outhouse-widget-8a3a@gregkh>
On Tue, Jun 09, 2026 at 12:43:03PM +0000, Alice Ryhl wrote:
> On Tue, Jun 09, 2026 at 12:21:21PM +0000, Alice Ryhl wrote:
> > On Mon, Jun 08, 2026 at 04:14:19PM +0200, Miguel Ojeda wrote:
> > > This patch series introduces support for `zerocopy`:
> > >
> > >     Fast, safe, compile error. Pick two.
> > >
> > >     Zerocopy makes zero-cost memory manipulation effortless. We write
> > >     `unsafe` so you don't have to.
> > 
> > I tried applying this and using it with Binder. I ran into one
> > challenge, which is this uapi struct:
> > 
> > struct binder_transaction_data {
> > 	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
> > 	 * identifying the target and contents of the transaction.
> > 	 */
> > 	union {
> > 		/* target descriptor of command transaction */
> > 		__u32	handle;
> > 		/* target descriptor of return transaction */
> > 		binder_uintptr_t ptr;
> > 	} target;
> > 	binder_uintptr_t	cookie;	/* target object cookie */
> > 	...
> > }
> > 
> > The problem is that when the union contains a handle, there are 4 bytes
> > of padding in the union. Currently Rust Binder handles this by wrapping
> > the uapi struct in MaybeUninit and using MaybeUninit::zeroed() to
> > construct it, ensuring that even if padding is present, it is zeroed.
> > 
> > However, this trick relies on unsafely implementing AsBytes for
> > BinderTransactionData with the safety comment being that the MaybeUninit
> > actually always contains initialized data.
> > 
> > To translate this to zerocopy, I'd have to do this:
> > 
> > unsafe impl zerocopy::IntoBytes for $newname {
> >     fn only_derive_is_allowed_to_implement_this_trait() {}
> > }
> > 
> > One fix could be to update the uapi header by explicitly adding the
> > padding, but that's kind of awkward for a union like this, since I'd
> > have to do it like this with an extra struct:
> > 
> > 	union {
> > 		/* target descriptor of command transaction */
> > 		struct {
> > 			__u32	handle;
> > 			__u32	_pad;
> > 		};
> > 		/* target descriptor of return transaction */
> > 		binder_uintptr_t ptr;
> > 	} target;
> > 
> > It's not clear to me if changing the uapi headers like this is even
> > allowed to begin with. It's a somewhat non-trivial change.
> 
> Hey Greg,
> Do you have any input on this from the C side?
> 
> For context, zerocopy is a tool that helps convert raw bytes into
> structs and vice-versa. When I tried using zerocopy with Rust Binder to
> see if it helps there, I found that zerocopy is flagging that Rust
> Binder copied a uapi struct containing padding into userspace, which is
> of course dangerous since padding on the kernel stack may contain data
> we don't want to leak to userspace.

A UAPI structure should not have padding, and if it does, it must be
zeroed out, as you say.  So in C we normally manually fix this up.

> Now, there's not actually a problem today because I'm using another
> strategy to ensure that the padding is zeroed when copying the output of
> the ioctl to userspace, but ideally I'd like to switch over to using
> zerocopy.
> 
> How is this kind of thing usually handled on the C side? As far as I can
> tell, C Binder handles it by just being extra careful like this:
> 
> 	fp->binder = 0;
> 	fp->handle = rdata.desc;

Yes, we have to almost always manually do this.  Sometimes we use memset
on the structure first before copying, or rely on a foo = {}; to do it
for us (but I never remember if the compiler will zero out the holes...)

> where fp->binder and fp->handle are fields of the same union, with
> fp->binder being 8 bytes and fp->handle being 4 bytes. The first
> assignment ensures that the extra 4 bytes in the union are zeroed.

Yes, that's why we manually do this :(

thanks,

greg k-h
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.