Re: xattr names for unprivileged stacking?

Matthew Wilcox
2020-08-29T19:18:01Z

On Sat, Aug 29, 2020 at 05:13:58PM +0100, Al Viro wrote:
> On Sat, Aug 29, 2020 at 05:07:17PM +0100, Matthew Wilcox wrote:
>
> > I agree with you that supporting named streams within a file requires
> > an independent inode for each stream. I disagree with you that this is
> > dentry cache infrastructure. I do not believe in giving each stream
> > its own dentry. Either they share the default stream's dentry, or they
> > have no dentry (mild preference for no dentry).
>
> *blink*
>
> Just how would they have different inodes while sharing a dentry?
>
> > > The fact that ADS inodes would not be in the dentry cache and hence
> > > not visible to pathwalks at all then means that all of the issues
> > > such as mounting over them, chroot, etc don't exist in the first
> > > place...
> >
> > Wait, you've now switched from "this is dentry cache infrastructure"
> > to "it should not be in the dentry cache". So I don't understand what
> > you're arguing for.
>
> Bloody wonderful, that. So now we have struct file instances with no dentry
> associated with them? Which would have to be taken into account all over
> the place...

I probably have the wrong nomenclature for what I'm proposing.

So here's a concrete API. What questions need to be answered?

fd = open("real", O_RDWR);

// fetch stream names
sfd = open_stream(fd, NULL);
read(sfd, names, length);
close(sfd);

// open the first one
sfd = open_stream(fd, names);
read(sfd, buffer, buflen);
close(sfd);

// create a new anonymous stream
sfd = open_stream(fd, "");
write(sfd, buffer, buflen);
// name it
linkat(sfd, NULL, fd, "newstream", AT_EMPTY_PATH);
close(sfd);

- Stream names are NUL terminated and may contain any other character.
If you want to put a '/' in a stream name, that's fine, but there's
no hierarchy. Ditto "//../././../../..//./." It's just a really
oddly named stream.
- linkat() will fail if 'fd' does not match where 'sfd' was created.
- open_stream() always creates a new stream when a zero-length string is
specified.
- open_stream() returns ENOENT if there is no stream by that name (ie the
only way to create a stream is to specify no name, and then name
it later).
- sfd inherits the appropriate O_ flags from fd (O_RDWR, O_CLOEXEC, ...)
- open_stream(sfd) is ENOTTY.