This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: shm_open failed:Invalid argument in glibc 2.20


Hi

On 18-02-2016 00:29, Cui Bixuan wrote:
> Hi,
>     I have a testcase:
> 
> test.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> #include <signal.h>
> #include <sys/types.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <stdint.h>
> #include <sys/stat.h>
> #include <sys/mman.h>
> #include <sys/wait.h>
> 
> //number of child progress
> #define N 20
> #define FILE_SIZE 4096
> 
> 
> int main(int ac, char **av)
> {
>         pid_t pid;
>         int state;
>         int i, j;
>         int ret = -1;
>         int fd = -1;
>         int FLAG = 0;
>         unsigned char* add_fw = NULL;
>         unsigned char* add_fr = NULL;
> 
>         fd = shm_open("./a", O_RDWR|O_CREAT, 00700);
>         if(-1 == (ret = fd))
>         {
>                 perror("shm_open fail\n");
>                 printf("errno=%d, EINVAL:%d\n", errno, EINVAL);
>                 FLAG++;
>                 exit(FLAG);
>         }
> 
>         return(FLAG);
> }
> 
> It just test shm_open() syscall. And It failed in Arm64eb:
> 
> linux /tmp # ./test_be
> shm_open fail
> : Invalid argument
> errno=22, EINVAL:22
> 
> (And shm_open("a", O_RDWR|O_CREAT, 00700) will pass I find;)
> 
> 
> But it can pass in Arm64el:
> ./test
> echo $?
> 0
> 
> Then I compile it by:
> aarch64-linux-gnu-gcc test.c -o test -static -lrt  (run it in arm64el)
> aarch64_be-linux-gnu-gcc test.c -o test_be -static -lrt  (run it in arm64eb)
> 
> I think it's related to the sdk which I use:
> aarch64-linux-gnu-gcc is compiled by libc-2.20.so and aarch64_be-linux-gnu-gcc is compiled by libc-2.17.so;
> 
> Is it a bug in glibc 2.20 ?
> Thanks for your help.
> 
> 
> Trace it:
> strace ./test_be
> execve("./test_be", ["./test_be"], [/* 17 vars */]) = 0
> uname({sys="Linux", node="linux", ...}) = 0
> brk(0)                                  = 0x27586000
> brk(0x27586f60)                         = 0x27586f60
> readlinkat(AT_FDCWD, "/proc/self/exe", "/tmp/test_be", 4096) = 12
> brk(0x275a7f60)                         = 0x275a7f60
> brk(0x275a8000)                         = 0x275a8000
> statfs64("/dev/shm/", {f_type=0x1021994, f_bsize=4096, f_blocks=374412, f_bfree=374412, f_bavail=374412, f_files=374412, f_ffree=374411, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
> dup(2)                                  = 3
> fcntl(3, F_GETFL)                       = 0x20002 (flags O_RDWR|0x20000)
> fstat(3, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 64), ...}) = 0
> ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost isig icanon echo ...}) = 0
> mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f957f2000
> write(3, "shm_open fail\n", 14shm_open fail
> )         = 14
> write(3, ": Invalid argument\n", 19: Invalid argument
> )    = 19
> close(3)                                = 0
> munmap(0x7f957f2000, 65536)             = 0
> fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 64), ...}) = 0
> ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost isig icanon echo ...}) = 0
> mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f957f2000
> write(1, "errno=22, EINVAL:22\n", 20errno=22, EINVAL:22
> )   = 20
> exit_group(1)                           = ?
> +++ exited with 1 +++
> 
> 
> 
> strace ./test
> execve("./test", ["./test"], [/* 18 vars */]) = 0
> uname({sys="Linux", node="localhost", ...}) = 0
> brk(0)                                  = 0x3a31000
> brk(0x3a31f58)                          = 0x3a31f58
> brk(0x3a52f58)                          = 0x3a52f58
> brk(0x3a53000)                          = 0x3a53000
> rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
> statfs64("/dev/shm/", {f_type=0x1021994, f_bsize=4096, f_blocks=1021184, f_bfree=1021184, f_bavail=1021184, f_files=1021184, f_ffree=1021182, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
> openat(AT_FDCWD, "/dev/shm/./a", O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0700) = 3
> exit_group(0)                           = ?
> +++ exited with 0 +++
> 

Since the be version is failing before the openat syscall, the SHM_GET_NAME at
sysdeps/posix/shm_open.c:35 is issuing an EINVAL. The macro is defined at
sysdeps/posix/shm-directory.h and I think the relevant snippet is:

 52   while (name[0] == '/')                                                      \
 53     ++name;                                                                   \
 54   size_t namelen = strlen (name) + 1;                                         \
 55   /* Validate the filename.  */                                               \
 56   if (namelen == 1 || namelen >= NAME_MAX || strchr (name, '/') != NULL)      \
 57     {                                                                         \
 58       __set_errno (errno_for_invalid);                                        \
 59       return retval_for_invalid;                                              \
 60     }   

So I presume something might be wrong with these evaluations.  I do not have access
to a aarch64-be environment, but since you build statically it would be easier to
try debug it. You could try break in shm_open and check the results of the strlen
and strchr for the name variable to see if something is wrong with these routines
for BE (aarch64 provides optimized assembly implementation for both).


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]