lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aYysaoP0y4_j9erG@fedora-2.fritz.box>
Date: Wed, 11 Feb 2026 17:35:44 +0100
From: Horst Birthelmer <horst@...thelmer.de>
To: Miklos Szeredi <miklos@...redi.hu>
Cc: Horst Birthelmer <horst@...thelmer.com>, 
	Bernd Schubert <bschubert@....com>, Joanne Koong <joannelkoong@...il.com>, 
	Luis Henriques <luis@...lia.com>, linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org, 
	Horst Birthelmer <hbirthelmer@....com>
Subject: Re: Re: [PATCH v5 1/3] fuse: add compound command to combine
 multiple requests

Hi Miklos,

thanks for taking the time to look at this!

On Wed, Feb 11, 2026 at 05:13:21PM +0100, Miklos Szeredi wrote:
> On Tue, 10 Feb 2026 at 09:46, Horst Birthelmer <horst@...thelmer.com> wrote:
> 
> > +static char *fuse_compound_build_one_op(struct fuse_conn *fc,
> > +                                        struct fuse_args *op_args,
> > +                                        char *buffer_pos)
> > +{
> > +       struct fuse_in_header *hdr;
> > +       size_t needed_size = sizeof(struct fuse_in_header);
> > +       int j;
> > +
> > +       for (j = 0; j < op_args->in_numargs; j++)
> > +               needed_size += op_args->in_args[j].size;
> > +
> > +       hdr = (struct fuse_in_header *)buffer_pos;
> > +       memset(hdr, 0, sizeof(*hdr));
> > +       hdr->len = needed_size;
> > +       hdr->opcode = op_args->opcode;
> > +       hdr->nodeid = op_args->nodeid;
> 
> hdr->unique is notably missing.
> 
> I don't know.  Maybe just fill it with the index?

OK, will do. Since it was never used in libfuse, I didn't notice.

> 
> > +       hdr->uid = from_kuid(fc->user_ns, current_fsuid());
> > +       hdr->gid = from_kgid(fc->user_ns, current_fsgid());
> 
> uid/gid are not needed except for creation ops, and those need idmap
> to calculate the correct values.  I don't think we want to keep legacy
> behavior of always setting these.
> 
> > +       hdr->pid = pid_nr_ns(task_pid(current), fc->pid_ns);
> 
> This will be the same as the value in the compound header, so it's
> redundant.  That might not be bad, but I feel that we're better off
> setting this to zero and letting the userspace server fetch the pid
> value from the compound header if that's needed.
> 
> > +#define FUSE_MAX_COMPOUND_OPS   16        /* Maximum operations per compound */
> 
> Don't see a good reason to declare this in the API.   More sensible
> would be to negotiate a max_request_size during INIT.
> 

Wouldn't that make for a very complicated implementation of larger compounds.
If a fuse server negotiates something like 2?

> > +
> > +#define FUSE_COMPOUND_SEPARABLE (1<<0)
> > +#define FUSE_COMPOUND_ATOMIC (1<<1)
> 
> What is the meaning of these flags?

FUSE_COMPOUND_SEPARABLE is a hint for the fuse server that the requests are all
complete and there is no need to use the result of one request to complete the input
of another request further down the line.

Think of LOOKUP+MKNOD+OPEN ... that would never be 'separable'.

At the moment I use this flag to signal libfuse that it can decode the compund 
and execute sequencially completely in the lib and just call the separate requests
of the fuse server.

FUSE_COMPOUND_ATOMIC was an idea to hint to the fuse server that the kernel treats
the compound as one atomic request. This can maybe save us some checks for some
compounds.

> 
> > +
> > +/*
> > + * Compound request header
> > + *
> > + * This header is followed by the fuse requests
> > + */
> > +struct fuse_compound_in {
> > +       uint32_t        count;                  /* Number of operations */
> 
> This is redundant, as the sum of the sub-request lengths is equal to
> the compound request length, hence calculating the number of ops is
> trivial.
> 
> > +       uint32_t        flags;                  /* Compound flags */
> > +
> > +       /* Total size of all results.
> > +        * This is needed for preallocating the whole result for all
> > +        * commands in this compound.
> > +        */
> > +       uint32_t        result_size;
> 
> I don't understand why this is needed.  Preallocation by the userspace
> server?  Why is this different from a simple request?
> 

The reason is the implementation in libfuse.
It makes it a lot easier to know what the sum of the result buffers in the kernel is
and preallocate that in libfuse for compounds that will be decoded and handled in the
library.

> > +       uint64_t        reserved;
> > +};
> > +
> > +/*
> > + * Compound response header
> > + *
> > + * This header is followed by complete fuse responses
> > + */
> > +struct fuse_compound_out {
> > +       uint32_t        count;     /* Number of results */
> 
> Again, redundant.
> 
> Thanks,
> Miklos
> 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ