Bug 1590228

Summary: kernel: openat with O_TMPFILE and mode 0 fails with EACCES (if not root)
Product: Red Hat Enterprise Linux 7 Reporter: Florian Weimer <fweimer>
Component: kernelAssignee: Prarit Bhargava <prarit>
kernel sub component: VFS QA Contact: Kun Wang <kunwan>
Status: CLOSED ERRATA Docs Contact:
Severity: unspecified    
Priority: unspecified CC: bhu, dj, pfrankli, xzhou
Version: 7.5   
Target Milestone: rc   
Target Release: 7.7   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: kernel-3.10.0-966.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-08-06 12:12:19 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1614004, 1647483    
Attachments:
Description Flags
RHEL PATCH 1/2
none
RHEL PATCH 2/2 none

Description Florian Weimer 2018-06-12 09:13:46 UTC
This test program, when running on non-root, fails:

#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/syscall.h>

int
main (void)
{
  int ret = syscall (__NR_openat, AT_FDCWD, ".",
                     O_RDWR | 020000000 | O_DIRECTORY, 0);
  if (ret < 0)
    err (1, "openat");
  printf ("descriptor: %d\n", ret);
  return 0;
}

(I'm using syscall to avoid any interference from the convoluted glibc openat implementation.)

Output is:

a.out: openat: Permission denied

Expected is:

descriptor: 3

Observed with kernel-3.10.0-862.6.1.el7.ppc64le.  The file system is XFS (from a default installation of current RHEL 7.5.z).  As root, the test works, so it's probably not lack of O_TMPFILE support in the file system.

Upstream kernels do not appear to have this problem.

Comment 1 Florian Weimer 2018-06-12 09:16:55 UTC
This upstream commit appears related:

commit e305f48bc453da773a3601135a2cce40b8e62856
Author: Andy Lutomirski <luto>
Date:   Thu Aug 1 21:07:52 2013 -0700

    fs: Fix file mode for O_TMPFILE
    
    O_TMPFILE, like O_CREAT, should respect the requested mode and should
    create regular files.
    
    This fixes two bugs: O_TMPFILE required privilege (because the mode
    ended up as 000) and it produced bogus inodes with no type.
    
    Signed-off-by: Andy Lutomirski <luto>
    Signed-off-by: Al Viro <viro.org.uk>

But the indicated kernel has this backported, so it doesn't seem to have the intended effect.

Comment 2 Florian Weimer 2018-06-12 09:33:21 UTC
kernel-4.14.0-49.2.2.el7a.ppc64le returns the expected output.

Comment 3 Florian Weimer 2018-11-07 17:00:16 UTC
Also fails with kernel-3.10.0-961.el7.s390x.

Comment 4 Florian Weimer 2018-11-07 17:13:49 UTC
The backport of this upstream patch appears to be missing:

commit 69a91c237ab0ebe4e9fdeaf6d0090c85275594ec
Author: Eric Rannaud <e>
Date:   Thu Oct 30 01:51:01 2014 -0700

    fs: allow open(dir, O_TMPFILE|..., 0) with mode 0

Comment 5 Prarit Bhargava 2018-11-07 18:37:02 UTC
(In reply to Florian Weimer from comment #4)
> The backport of this upstream patch appears to be missing:
> 
> commit 69a91c237ab0ebe4e9fdeaf6d0090c85275594ec
> Author: Eric Rannaud <e>
> Date:   Thu Oct 30 01:51:01 2014 -0700
> 
>     fs: allow open(dir, O_TMPFILE|..., 0) with mode 0

Florian, I'll take a look at this and attempt a backport.

P.

Comment 6 Prarit Bhargava 2018-11-07 20:06:31 UTC
Needs 

69a91c237ab0 ("fs: allow open(dir, O_TMPFILE|..., 0) with mode 0")
62fb4a155f74 ("don't carry MAY_OPEN in op->acc_mode")

and testing as non-root user shows before the change

[02:57 PM root@intel-wildcatpass-07 ~]# su - prarit
Last login: Wed Nov  7 14:57:51 EST 2018 on pts/0
[prarit@intel-wildcatpass-07 ~]$ gcc -o test test.c
[prarit@intel-wildcatpass-07 ~]$ ./test 
test: openat: Permission denied

and after the change

[03:02 PM root@intel-wildcatpass-07 ~]# su - prarit
Last login: Wed Nov  7 14:57:55 EST 2018 on pts/0
[prarit@intel-wildcatpass-07 ~]$ ./test 
descriptor: 3

P.

Comment 7 Murphy Zhou 2018-11-08 07:39:03 UTC
Reproducer fails on 3.10.0-957.el7.x86_64, pass on 4.18.0-35.el8.x86_64

Comment 8 Florian Weimer 2018-11-08 08:18:20 UTC
Running the glibc test case against Prarit's scratch build results in:

[test@ibm-z-07 build]$ io/tst-open-tmpfile ; echo $?
info: testing open at: .
info: testing openat at: .
info: testing open64 at: .
info: testing openat64 at: .
info: testing open at: /dev/shm
info: testing openat at: /dev/shm
info: testing open64 at: /dev/shm
info: testing openat64 at: /dev/shm
info: testing open at: /tmp
info: testing openat at: /tmp
info: testing open64 at: /tmp
info: testing openat64 at: /tmp
0
[test@ibm-z-07 build]$ 

Previously, it would result in:

[test@ibm-z-07 build]$ io/tst-open-tmpfile  ; echo $?
error: openat (".", O_TMPFILE | O_RDWR): Permission denied
1
[test@ibm-z-07 build]$ 

So the bug appears to be fixed.

Comment 9 Prarit Bhargava 2018-11-08 14:35:34 UTC
Created attachment 1503361 [details]
RHEL PATCH 1/2

Comment 10 Prarit Bhargava 2018-11-08 14:35:38 UTC
Created attachment 1503362 [details]
RHEL PATCH 2/2

Comment 13 Bruno Meneguele 2018-11-19 19:45:18 UTC
Patch(es) committed on kernel-3.10.0-966.el7

Comment 18 errata-xmlrpc 2019-08-06 12:12:19 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2019:2029