Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

open14 and openat03 failed with wrong file mode #118

Closed
ghost opened this issue Dec 8, 2016 · 17 comments
Closed

open14 and openat03 failed with wrong file mode #118

ghost opened this issue Dec 8, 2016 · 17 comments

Comments

@ghost
Copy link

ghost commented Dec 8, 2016

Hi,

I had both testcases open14 and openat03 failed with same errors

open14 0 TINFO : and check file permissions
open14 3 TFAIL : open14.c:212: file mode read 7777, but expected 7755

openat03 0 TINFO : and check file permissions
openat03 3 TFAIL : openat03.c:223: file mode read 7777, but expected 7755

Looking a little deeper into the code, the issue may come from these lines

const mode_t test_perms[] = { 0, 07777, 001, 0755, 0644, 0440 };
...
mode_t mask = umask(0), perm;
umask(mask);
...
perm = test_perms[i % ARRAY_SIZE(test_perms)];
fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, perm);
...
mode_t exp_mode = perm & ~mask;

In the beginning, the writer may intend to create files and test with each value in test_perms[].
But the "exp_mode" is calculated based on "perm" and "mask", so to keep it with initial value, umask should be set to 0 before calculate "mask" variable ?
(mode_t mask = umask(0) just returns the previous value of the file creation mask, in my machine, it's default 0022)

Tried with this way and it can run normally

root@mx6q:# umask 0
root@mx6q:# /opt/ltp/testcases/bin/open14
open14 0 TINFO : creating a file with O_TMPFILE flag
open14 0 TINFO : writing data to the file
open14 0 TINFO : file size is '4096'
open14 0 TINFO : looking for the file in '.'
open14 0 TINFO : file not found, OK
open14 0 TINFO : renaming '/var/volatile/tmp/opeENexEp/#38411 (deleted)' -> 'tmpfile'
open14 0 TINFO : found a file: tmpfile
open14 1 TPASS : single file tests passed
open14 0 TINFO : create files in multiple directories
open14 0 TINFO : removing test directories
open14 0 TINFO : writing/reading temporary files
open14 0 TINFO : closing temporary files
open14 2 TPASS : multiple files tests passed
open14 0 TINFO : create multiple directories, link files into them
open14 0 TINFO : and check file permissions
open14 0 TINFO : remove files, directories
open14 3 TPASS : file permission tests passed

or put this line here in the code also can help (with any default umask value)

umask(0);
mode_t mask = umask(0), perm;

Should it be fine with this approach ?

@ghost
Copy link
Author

ghost commented Dec 8, 2016

Or another way can be calculate the permission before creating the file
change from
perm = test_perms[i % ARRAY_SIZE(test_perms)];
to
perm = test_perms[i % ARRAY_SIZE(test_perms)] & ~mask;

but this case, I don't think numbers in test_perms[] still make sense as before (it masked).

@jstancek
Copy link
Contributor

jstancek commented Dec 8, 2016

What LTP version/arch/kernel/distro/glibc/filesystem are you using?

On first look, my guess is your kernel doesn't respect umask for O_TMPFILE. From man page:

              The mode argument specifies the file mode bits be applied when
              a new file is created.  This argument must be supplied when
              O_CREAT or O_TMPFILE is specified in flags; if neither O_CREAT
              nor O_TMPFILE is specified, then mode is ignored.  The
              effective mode is modified by the process's umask in the usual
              way: in the absence of a default ACL, the mode of the created
              file is (mode & ~umask)

Can you compile/run following and provide output? (With your default umask)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#ifndef O_TMPFILE
# define O_TMPFILE (020000000 | O_DIRECTORY)
#endif

void test(char *name, int flags)
{
        int fd = open(name, flags, 0777);
        char s[80];

        if (fd < 0) {
                perror("fd");
                exit(1);
        }

        printf("fd opened: %d\n", fd);
        sprintf(s, "stat -L /proc/self/fd/%d\n", fd);
        system(s);
}

int main(void)
{

        test("tst", O_CREAT | O_RDWR);
        test(".", O_TMPFILE | O_RDWR);

        unlink("tst");

        return 0;
}

There was a glibc bug related to O_TMPFILE, that made these 2 tests fail as well, but I think the symptoms were a little different:
Bug 17523 - open() and openat() ignore 'mode' with O_TMPFILE
https://sourceware.org/bugzilla/show_bug.cgi?id=17523

@ghost
Copy link
Author

ghost commented Dec 9, 2016

Hi @jstancek

I'm testing with armv7l (32bits), just fetching LTP several days ago, so I believe it almost latest.

root@mx6q:~# uname -a
Linux mx6q 3.14.79-vm0-05103-g54d2ed4 #1 SMP PREEMPT Tue Dec 6 16:37:17 CET 2016 armv7l GNU/Linux

root@mx6q:~# ldd --version
ldd (Sourcery CodeBench 2015.12-138) 2.22
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

The output from your code

root@mx6q:~# ./test
fd opened: 3
  File: "/proc/self/fd/3"
  Size: 0               Blocks: 0          IO Block: 4096   Regular File
Device: b319h/45849d    Inode: 20246       Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: Fri Dec  9 03:01:05 2016
Modify: Fri Dec  9 03:01:05 2016
Change: Fri Dec  9 03:01:05 2016

fd opened: 4
  File: "/proc/self/fd/4"
  Size: 0               Blocks: 0          IO Block: 4096   Regular File
Device: b319h/45849d    Inode: 20247       Links: 0
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: Fri Dec  9 03:01:05 2016
Modify: Fri Dec  9 03:01:05 2016
Change: Fri Dec  9 03:01:05 2016

root@mx6q:~# umask
0022

(-L option is not support on my machine, so I changed it)
Still a little bit confusing, because I still didn't see different things between your code and open14.c code from LTP, but with LTP code, I put some debug code and it's created with 777. (not 755 as yours) (I even change using open() instead of SAFE_OPEN() as previously to make it almost like your code)

exp_mode = 0
st.st_mode = 100000
S_IFMT = 170000
st.st_mode & ~S_IFMT = 0
path = tst03_1
perm = 7777
  File: "/proc/self/fd/4"
  Size: 0               Blocks: 0          IO Block: 4096   Regular File
Device: 18h/24d Inode: 19707       Links: 0
Access: (7777/-rwsrwsrwt)  Uid: (    0/    root)   Gid: (    0/    root)
Access: Fri Dec  9 03:17:00 2016
Modify: Fri Dec  9 03:17:00 2016
Change: Fri Dec  9 03:17:00 2016

exp_mode = 7755
st.st_mode = 107777
S_IFMT = 170000
st.st_mode & ~S_IFMT = 7777
open14      3  TFAIL  :  open14.c:226: file mode read 7777, but expected 7755

@jstancek
Copy link
Contributor

jstancek commented Dec 9, 2016

It was only for purposes of having simpler reproducer.

Where is your TMPDIR set to? Does it define any ACLs (check getfacl)? Other than that I suspect your kernel doesn't honor umask for O_TMPFILE.

... in the absence of a default ACL, the mode of the created
file is (mode & ~umask)

@ghost
Copy link
Author

ghost commented Dec 9, 2016

Hi @jstancek

Yes, I also put logs everywhere and found the the issue appear after tst_tmpdir is provoked.
My TMPDIR is point to /tmp/, and realize that file created in /tmp is different with other location.

root@mx6q:/tmp# touch a
root@mx6q:/tmp# getfacl a
# file: a
# owner: root
# group: root
user::rw-
group::r--
other::r--

root@mx6q:/tmp# cd -
/home/root
root@mx6q:~# touch a
root@mx6q:~#  getfacl a
# file: a
# owner: root
# group: root
user::rw-
group::rw-
other::rw-

Export TMPDIR to another location before running this test can help to pass, but actually it's not a suitable solution for me, because my testing system is read-only system, I'd better not running rwrfs on it. Still wonder is there any way can be improved from LTP testcases side ?

@jstancek
Copy link
Contributor

jstancek commented Dec 9, 2016

Your output does not list any default ACLs. Can you provide also output of "df -T"? I'm curious about file system types of /home and /tmp.

@ghost
Copy link
Author

ghost commented Dec 9, 2016

Hi,

For your information, df -T output

root@mx6q:~# df -T
Filesystem           Type       1K-blocks      Used Available Use% Mounted on
/dev/root            ext4         1479088    877612    508292  63% /
devtmpfs             devtmpfs      411060         8    411052   0% /dev
tmpfs                tmpfs         607668      1048    606620   0% /dev/shm
tmpfs                tmpfs         607668       224    607444   0% /run
tmpfs                tmpfs         607668         0    607668   0% /sys/fs/cgroup
tmpfs                tmpfs         607668        16    607652   0% /var/volatile
tmpfs                tmpfs         607668         0    607668   0% /media
/dev/mmcblk1p5       ext4          289293      2149    267688   1% /var/opt/bosch/static
/dev/mmcblk1p3       ext4           45478       950     40944   2% /var/opt/bosch/persistent
/dev/mmcblk1p6       ext4        11423612     28676  10791600   0% /var/opt/bosch/dynamic

One more observation, /tmp is actually linked to /var/volatile/tmp, and "sticky bit" is set on this folder. I just know this bit help files in this directory can only be renamed or deleted by the user that owns them (and root), I'm not sure if it has any affects to file permission ?

root@mx6q:~# ls -ld /tmp
lrwxrwxrwx    1 root     root            17 Jan  1 00:06 /tmp -> /var/volatile/tmp
root@mx6q:~# ls -ld /var/volatile/tmp
drwxrwxrwt    4 root     root           180 Jan  1 00:00 /var/volatile/tmp

@ghost
Copy link
Author

ghost commented Dec 12, 2016

Hi @jstancek ,

I tried with several values of test_perms[] and seems that umask actually did not work for any values. From the original values
const mode_t test_perms[] = { 0, 07777, 001, 0755, 0644, 0440 };
most of the cases can pass because the "exp_mode" is equals to "perm", so cases that need mask such as 07777 or 002 will be failed.

Did this testcase passed on your system ( I looked around and this not find any LTP reports that have this case) ? I tried with another machine and 07777 is still failed (get 1755 but expect 7755). I guess the permission of O_TMPFILE created in /tmp is much affected by attribute of /tmp file, and the calculation of exp_mode must included also setuid/setgid/Sticky Bit ?

@jstancek
Copy link
Contributor

It does pass with several kernels (on my x86 KVM guest).

# ./open14 
open14      0  TINFO  :  creating a file with O_TMPFILE flag
open14      0  TINFO  :  writing data to the file
open14      0  TINFO  :  file size is '4096'
open14      0  TINFO  :  looking for the file in '.'
open14      0  TINFO  :  file not found, OK
open14      0  TINFO  :  renaming '/tmp/opecF0vWo/#69723424 (deleted)' -> 'tmpfile'
open14      0  TINFO  :  found a file: tmpfile
open14      1  TPASS  :  single file tests passed
open14      0  TINFO  :  create files in multiple directories
open14      0  TINFO  :  removing test directories
open14      0  TINFO  :  writing/reading temporary files
open14      0  TINFO  :  closing temporary files
open14      2  TPASS  :  multiple files tests passed
open14      0  TINFO  :  create multiple directories, link files into them
open14      0  TINFO  :  and check file permissions
open14      0  TINFO  :  remove files, directories
open14      3  TPASS  :  file permission tests passed

# uname -r
4.8.0-1.el7.test.x86_64

# umask
0022

At the moment, I'm suspecting this to be related to tmpfs, rather than /tmp permissions/sticky bit. You can try to set TMPDIR to /root/test and set exact same permission/sticky bit on it (as /tmp currently has) - that is mirror the setup of /tmp for all details except for file system type.

@ghost
Copy link
Author

ghost commented Dec 12, 2016

Hi @jstancek,

Yes, it's more related on tmpfs than the other ones. Although the last result on another machine (which "get 1755 but expect 7755") the /tmp is on the hard disk, not the tmpfs, but we can temporary abort it.

I can pass when pointing TMPDIR to another folder (but need "rwrfs" in advance)
I've just confused that which should be the side (testing environment and LTP code) to improve in my case (/tmp on tmpfs), changing the system with "rwrfs" and export TMPDIR to another place just for this special testcase is really not my expectation (from the testing point of view, I would prefer keep the system as it is).

root@mx6q:/root# pwd
/root
root@mx6q:/root# mkdir test
mkdir: can't create directory 'test': Read-only file system
root@mx6q:/root# rwrfs
root@mx6q:/root# mkdir test
root@mx6q:/root# ls -l /tmp
lrwxrwxrwx    1 root     root            17 Jan  1 00:06 /tmp -> /var/volatile/tmp
root@mx6q:/root# ls -ld /var/volatile/tmp
drwxrwxrwt    4 root     root           180 Jan  1 00:00 /var/volatile/tmp
root@mx6q:/root# ls -ld test
drwxr-xr-x    2 root     root          4096 Jan  1 00:01 test/
root@mx6q:/root# chmod 1777 test
root@mx6q:/root# ls -ld test/
drwxrwxrwt    2 root     root          4096 Jan  1 00:01 test/
root@mx6q:/root# export TMPDIR=/root/test
root@mx6q:/root# cd /home/root/
root@mx6q:~# ./open14
open14      0  TINFO  :  creating a file with O_TMPFILE flag
open14      0  TINFO  :  writing data to the file
open14      0  TINFO  :  file size is '4096'
open14      0  TINFO  :  looking for the file in '.'
open14      0  TINFO  :  file not found, OK
open14      0  TINFO  :  renaming '/home/root/test/opeHuPUBI/#20255 (deleted)' -> 'tmpfile'
open14      0  TINFO  :  found a file: tmpfile
open14      1  TPASS  :  single file tests passed
open14      0  TINFO  :  create files in multiple directories
open14      0  TINFO  :  removing test directories
open14      0  TINFO  :  writing/reading temporary files
open14      0  TINFO  :  closing temporary files
open14      2  TPASS  :  multiple files tests passed
open14      0  TINFO  :  create multiple directories, link files into them
open14      0  TINFO  :  and check file permissions
open14      0  TINFO  :  remove files, directories
open14      3  TPASS  :  file permission tests passed
root@mx6q:~# umask
0022
root@mx6q:~# echo $TMPDIR
/root/test
root@mx6q:~# uname -r
3.14.79-vm0-05103-g54d2ed4

@jstancek
Copy link
Contributor

changing the system with "rwrfs" and export TMPDIR to another place just for this special testcase is really not my expectation

I'm not suggesting you do that permanently. Based on your data so far, behaviour is not the same for ext4 vs. tmpfs, so I'd start looking into potential kernel bug.

I'd run the failing test via strace, and double-check syscall parameters.
Also, do you have chance to try latest upstream kernel?

@ghost
Copy link
Author

ghost commented Dec 13, 2016

Hi @jstancek ,

I did not chance to try with latest upstream kernel.
strace log is a little bit long, (some reasons I cannot upload the file from my side) so I tried to give here part of it, hope it can give us some clues

(
I'll have some training in next several days, so sorry that my response may be a little bit late
Thanks a lot for your help for during our discussion until now :-)
)

root@mx6q:~# strace /opt/ltp/testcases/bin/open14
execve("/opt/ltp/testcases/bin/open14", ["/opt/ltp/testcases/bin/open14"], [/* 16 vars */]) = 0
brk(0)                                  = 0x1d59000
uname({sysname="Linux", nodename="mx6q", ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f23000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=92814, ...}) = 0
mmap2(NULL, 92814, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76edf000
close(3)                                = 0
open("/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\200\315\0\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=288672, ...}) = 0
mmap2(NULL, 180796, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76eb2000
mprotect(0x76ece000, 65536, PROT_NONE)  = 0
mmap2(0x76ede000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x76ede000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0,m\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1679852, ...}) = 0
mmap2(NULL, 1303904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76d73000
mprotect(0x76e9d000, 61440, PROT_NONE)  = 0
mmap2(0x76eac000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x129000) = 0x76eac000
mmap2(0x76eaf000, 9568, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76eaf000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f22000
set_tls(0x76f226d0, 0x76f22da8, 0x76f26050, 0x76f226d0, 0x76f26050) = 0
mprotect(0x76eac000, 8192, PROT_READ)   = 0
mprotect(0x76f25000, 4096, PROT_READ)   = 0
munmap(0x76edf000, 92814)               = 0
brk(0)                                  = 0x1d59000
brk(0x1d7a000)                          = 0x1d7a000
gettimeofday({144, 150739}, NULL)       = 0
getpid()                                = 453
mkdir("/tmp/opedvJIWk", 0700)           = 0
getgid32()                              = 0
chown32("/tmp/opedvJIWk", -1, 0)        = 0
chmod("/tmp/opedvJIWk", 0777)           = 0
getcwd("/home/root", 4096)              = 11
chdir("/tmp/opedvJIWk")                 = 0
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 3
close(3)                                = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f21000
write(1, "open14      0  TINFO  :  creatin"..., 61open14      0  TINFO  :  creating a file with O_TMPFILE flag
) = 61
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 3
write(1, "open14      0  TINFO  :  writing"..., 50open14      0  TINFO  :  writing data to the file
) = 50
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
fstat64(3, {st_mode=S_IFREG|0600, st_size=4096, ...}) = 0
write(1, "open14      0  TINFO  :  file si"..., 45open14      0  TINFO  :  file size is '4096'
) = 45
write(1, "open14      0  TINFO  :  looking"..., 53open14      0  TINFO  :  looking for the file in '.'
) = 53
stat64(".", {st_mode=S_IFDIR|0777, st_size=40, ...}) = 0
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 4
fstat64(4, {st_mode=S_IFDIR|0777, st_size=40, ...}) = 0
getdents(4, /* 2 entries */, 32768)     = 32
getdents(4, /* 0 entries */, 32768)     = 0
close(4)                                = 0
write(1, "open14      0  TINFO  :  file no"..., 44open14      0  TINFO  :  file not found, OK
) = 44
readlink("/proc/self/fd/3", "/var/volatile/tmp/opedvJIWk/#538"..., 4096) = 43
write(1, "open14      0  TINFO  :  renamin"..., 93open14      0  TINFO  :  renaming '/var/volatile/tmp/opedvJIWk/#5383 (deleted)' -> 'tmpfile'
) = 93
linkat(AT_FDCWD, "/proc/self/fd/3", AT_FDCWD, "tmpfile", AT_SYMLINK_FOLLOW) = 0
stat64(".", {st_mode=S_IFDIR|0777, st_size=60, ...}) = 0
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 4
fstat64(4, {st_mode=S_IFDIR|0777, st_size=60, ...}) = 0
getdents(4, /* 3 entries */, 32768)     = 52
write(1, "open14      0  TINFO  :  found a"..., 47open14      0  TINFO  :  found a file: tmpfile
) = 47
close(4)                                = 0
unlink("tmpfile")                       = 0
close(3)                                = 0
write(1, "open14      1  TPASS  :  single "..., 50open14      1  TPASS  :  single file tests passed
) = 50
write(1, "open14      0  TINFO  :  create "..., 62open14      0  TINFO  :  create files in multiple directories
) = 62
mkdir("tst02_0", 0700)                  = 0
chdir("tst02_0")                        = 0
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 3
mkdir("tst02_1", 0700)                  = 0
...
...
chdir("..")                             = 0
rmdir("tst02_0")                        = 0
write(1, "open14      0  TINFO  :  writing"..., 57open14      0  TINFO  :  writing/reading temporary files
) = 57
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(3, 0, SEEK_SET)                   = 0
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
...
...
read(102, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(1, "open14      0  TINFO  :  closing"..., 49open14      0  TINFO  :  closing temporary files
) = 49
close(3)                                = 0
close(4)                                = 0
...
...
close(102)                              = 0
write(1, "open14      2  TPASS  :  multipl"..., 53open14      2  TPASS  :  multiple files tests passed
) = 53
umask(0)                                = 022
umask(022)                              = 0
write(1, "open14      0  TINFO  :  create "..., 75open14      0  TINFO  :  create multiple directories, link files into them
) = 75
write(1, "open14      0  TINFO  :  and che"..., 52open14      0  TINFO  :  and check file permissions
) = 52
mkdir("tst03_0", 0700)                  = 0
chdir("tst03_0")                        = 0
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 3
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(3, 0, SEEK_SET)                   = 0
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
linkat(AT_FDCWD, "/proc/self/fd/3", AT_FDCWD, "tmpfile_3", AT_SYMLINK_FOLLOW) = 0
lstat64("tmpfile_3", {st_mode=S_IFREG, st_size=4096, ...}) = 0
mkdir("tst03_1", 0700)                  = 0
chdir("tst03_1")                        = 0
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 4
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(4, 0, SEEK_SET)                   = 0
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
linkat(AT_FDCWD, "/proc/self/fd/4", AT_FDCWD, "tmpfile_4", AT_SYMLINK_FOLLOW) = 0
lstat64("tmpfile_4", {st_mode=S_IFREG|S_ISUID|S_ISGID|S_ISVTX|0777, st_size=4096, ...}) = 0
write(1, "open14      3  TFAIL  :  open14."..., 78open14      3  TFAIL  :  open14.c:212: file mode read 7777, but expected 7755
) = 78
open("/tmp/opedvJIWk", O_RDONLY|O_DIRECTORY|O_NOFOLLOW) = 5
close(5) 

@ghost
Copy link
Author

ghost commented Dec 30, 2016

Hi @jstancek ,

https://sourceware.org/bugzilla/show_bug.cgi?id=17523

I read this again, I think the phenomenon somehow like in "Comment 5". open() may have the issue with tmpfs when creating the fd with wrong permission. Workaround with fchmod (fchmod(fd[i], perm & ~mask);) right after the open() helped to move the testcase to correct direction

lstat64("tmpfile_3", {st_mode=S_IFREG, st_size=4096, ...}) = 0
mkdir("tst03_1", 0700)                  = 0
chdir("tst03_1")                        = 0
open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 4
**fchmod(4, 07755)                        = 0**
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(4, 0, SEEK_SET)                   = 0
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
linkat(AT_FDCWD, "/proc/self/fd/4", AT_FDCWD, "tmpfile_4", AT_SYMLINK_FOLLOW) = 0
lstat64("tmpfile_4", {st_mode=S_IFREG|S_ISUID|S_ISGID|S_ISVTX|0755, st_size=4096, ...}) = 0 

Not much meaning when I added fchmod like this, but at least we can narrow it to open() method, other parts seems ok, so issue with "glibc" ?

@jstancek
Copy link
Contributor

jstancek commented Jan 5, 2017

I still suspect your kernel and tmpfs as it worked fine on other filesystems. If you want to rule out glibc involvement, you can replace open() with syscall(NR_open, ...).

@ghost
Copy link
Author

ghost commented Jan 6, 2017

:(

Yes, I tried with syscall and the testcase still fail as before

fd[i] = syscall(__NR_open, ".", O_TMPFILE | O_RDWR, perm);

open(".", O_RDWR|O_DIRECTORY|O_TMPFILE) = 4
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(4, 0, SEEK_SET)                   = 0
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
linkat(AT_FDCWD, "/proc/self/fd/4", AT_FDCWD, "tmpfile_4", AT_SYMLINK_FOLLOW) = 0
lstat64("tmpfile_4", {st_mode=S_IFREG|S_ISUID|S_ISGID|S_ISVTX|0777, st_size=4096, ...}) = 0
write(1, "open14      3  TFAIL  :  open14."..., 78open14      3  TFAIL  :  open14.c:215: file mode read 7777, but expected 7755
) = 78

Maybe as you said, issue seems from our kernel, I may contact our kernel dev team to check more with them.
If you have any more ideas, please continue to share with me

Thanks a lot for taking time to help me.

@hkandiga
Copy link

hkandiga commented Mar 2, 2017

CONFIG_TMPFS_POSIX_ACL option needs to be enabled in defconfig. Otherwise the umask is not applied when a new inode is created using shmem_tmpfile call.

@ghost
Copy link
Author

ghost commented Mar 3, 2017

@hkandiga thanks for helping me answer the issue.
@jstancek we can pass these 2 testcases with CONFIG_TMPFS_POSIX_ACL set. Thanks a lot for your help again. I think we can close this issue here.

@ghost ghost closed this as completed Mar 3, 2017
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants