On Thu, Apr 15, 2021 at 05:41:07PM +0700, Dmitry Kadashev wrote: > On Thu, Apr 15, 2021 at 5:09 PM Christian Brauner > <christian.brauner@xxxxxxxxxx> wrote: > > > > On Thu, Apr 15, 2021 at 12:08:20PM +0200, Christian Brauner wrote: > > > Would something like this help? > > Thanks for the reply, Christian! > > But it's not the AT_EMPTY_PATH / LOOKUP_EMPTY part that is tricky, it's > the fact that do_linkat() allows AT_EMPTY_PATH only if the process has > CAP_DAC_READ_SEARCH capability. But AT_EMPTY_PATH is processed during > getname(), so if do_linkat() accepts struct filename* then there is no > bullet-proof way to force the capability. > > We could do something like this: > > do_linkat(oldfd, getname_uflags(oldname, flags), newfd, > getname(newname), flags); > > I.e. call getname_uflags() without checking the capability and rely on > the fact that do_linkat() will do the checking. But this is fragile if > somehow someone passes different flags to getname_uflags and do_linkat. > And there is no way (that I know of) for do_linkat to actually check > that AT_EMPTY_PATH was not used if it gets struct filename. > > Or am I creating extra problems and the thing above is OK? Hm, I get your point but if you e.g. look at fs/exec.c we already do have that problem today: SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, const char __user *const __user *, envp, int, flags) { int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0; return do_execveat(fd, getname_flags(filename, lookup_flags, NULL), argv, envp, flags); } The new simple flag helper would simplify things because right now it pretends that it cares about multiple flags where it actually just cares about whether or not empty pathnames are allowed and it forces callers to translate between flags too. (Note, just my opinion this might get shot to hell.) Christian