Skip to content

getpwuid_r may return ENOENT for "No such user" #8069

Closed
@lugia-kun

Description

@lugia-kun

In my Linux x86-64, glibc environment, spec/std/system/user_sepc.cr fails with following log:

[momonga@elma ~/crystal x86_64]$ make all
Using /usr/bin/llvm-config [version=8.0.1]
g++ -c  -o src/llvm/ext/llvm_ext.o src/llvm/ext/llvm_ext.cc -I/usr/include -std=c++11  -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
cc -fPIC    -c -o src/ext/sigfault.o src/ext/sigfault.c
ar -rcs src/ext/libcrystal.a src/ext/sigfault.o
CRYSTAL_CONFIG_PATH="/opt/momonga/crystal/src" CRYSTAL_CONFIG_LIBRARY_PATH="/usr/lib64/crystal" CRYSTAL_CONFIG_BUILD_COMMIT="55b664ced" ./bin/crystal build -D preview_overflow -D compiler_rt  -o .build/crystal src/compiler/crystal.cr -D without_openssl -D without_zlib
[momonga@elma ~/crystal x86_64]$ bin/crystal -v
Using compiled compiler at `.build/crystal'
Crystal 0.30.0 [55b664ced] (2019-08-11)

LLVM: 8.0.1
Default target: x86_64-unknown-linux-gnu
[momonga@elma ~/crystal x86_64]$ bin/crystal run spec/std/system/user_spec.cr
Using compiled compiler at `.build/crystal'
...F...E.......

Failures:

  1) System::User .find_by(*, id) raises on nonexistent user id
     Failure/Error: expect_raises System::User::NotFoundError, "No such user" do

       Expected System::User::NotFoundError, got #<Errno: getpwuid_r: No such file or directory> with backtrace:
         # src/crystal/system/unix/user.cr:47:5 in 'from_id?'
         # src/system/user.cr:66:5 in 'find_by?:id'
         # src/system/user.cr:59:5 in 'find_by:id'
         # spec/std/system/user_spec.cr:35:9 in '->'
         # src/spec/methods.cr:255:3 in 'it'
         # spec/std/system/user_spec.cr:33:5 in '->'
         # src/spec/context.cr:255:3 in 'describe'
         # src/spec/methods.cr:16:5 in 'describe'
         # spec/std/system/user_spec.cr:24:3 in '->'
         # src/spec/context.cr:255:3 in 'describe'
         # src/spec/methods.cr:16:5 in 'describe'
         # spec/std/system/user_spec.cr:7:1 in '__crystal_main'
         # src/crystal/main.cr:97:5 in 'main_user_code'
         # src/crystal/main.cr:86:7 in 'main'
         # src/crystal/main.cr:106:3 in 'main'
         # __libc_start_main
         # _start
         # ???

     # spec/std/system/user_spec.cr:34

  2) System::User .find_by?(*, id) returns nil on nonexistent user id

       getpwuid_r: No such file or directory (Errno)
         from src/crystal/system/unix/user.cr:47:5 in 'from_id?'
         from src/system/user.cr:66:5 in 'find_by?:id'
         from spec/std/system/user_spec.cr:65:7 in '->'
         from src/spec/methods.cr:255:3 in 'it'
         from spec/std/system/user_spec.cr:64:5 in '->'
         from src/spec/context.cr:255:3 in 'describe'
         from src/spec/methods.cr:16:5 in 'describe'
         from spec/std/system/user_spec.cr:55:3 in '->'
         from src/spec/context.cr:255:3 in 'describe'
         from src/spec/methods.cr:16:5 in 'describe'
         from spec/std/system/user_spec.cr:7:1 in '__crystal_main'
         from src/crystal/main.cr:97:5 in 'main_user_code'
         from src/crystal/main.cr:86:7 in 'main'
         from src/crystal/main.cr:106:3 in 'main'
         from __libc_start_main
         from _start
         from ???


Finished in 66.85 milliseconds
15 examples, 1 failures, 1 errors, 0 pending

Failed examples:

crystal spec spec/std/system/user_spec.cr:33 # System::User .find_by(*, id) raises on nonexistent user id
crystal spec spec/std/system/user_spec.cr:64 # System::User .find_by?(*, id) returns nil on nonexistent user id
/usr/bin/ld: warning: skipping incompatible /usr/lib/libm.so while searching for m
/usr/bin/ld: warning: skipping incompatible /usr/lib/libpthread.so while searching for pthread
/usr/bin/ld: warning: skipping incompatible /usr/lib/librt.so while searching for rt
/usr/bin/ld: warning: skipping incompatible /usr/lib/libdl.so while searching for dl
/usr/bin/ld: warning: skipping incompatible /usr/lib/libc.so while searching for c
[momonga@elma ~/crystal x86_64]$ uname -a
Linux elma 4.18.16-1m.mo8.x86_64 #1 SMP Fri Oct 26 14:16:38 JST 2018 x86_64 x86_64 x86_64 GNU/Linux
  • The version of glibc is 2.29.

Our man page of getpwuid_r says that it informs that the given user name or id was not found when it returned ENOENT, ESRCH, EBADF, EPERM or other errno values. It is likely to indicate that there are some system problems which is not responsible to the application.

RETURN VALUE
       The  getpwnam()  and  getpwuid() functions return a pointer to a passwd
       structure, or NULL if the matching entry  is  not  found  or  an  error
       occurs.   If an error occurs, errno is set appropriately.  If one wants
       to check errno after the call, it should be  set  to  zero  before  the
       call.

       The  return value may point to a static area, and may be overwritten by
       subsequent calls to getpwent(3), getpwnam(), or  getpwuid().   (Do  not
       pass the returned pointer to free(3).)

       On  success, getpwnam_r() and getpwuid_r() return zero, and set *result
       to pwd.  If no matching password  record  was  found,  these  functions
       return  0 and store NULL in *result.  In case of error, an error number
       is returned, and NULL is stored in *result.

ERRORS
       0 or ENOENT or ESRCH or EBADF or EPERM or ...
              The given name or uid was not found.

       EINTR  A signal was caught; see signal(7).

       EIO    I/O error.

       EMFILE The per-process limit on the number of open file descriptors has
              been reached.

       ENFILE The system-wide limit on the total number of open files has been
              reached.

       ENOMEM Insufficient memory to allocate passwd structure.

       ERANGE Insufficient buffer space supplied.

When I strace-ed it, then I found ENOENT event. /run/dbus/system_bus_socket is not found because I'm in chroot-ed environment, but I did not bind /run of the host. After fixing it, the spec ran fine.

Is spec needed to detect these problems? Or even is System::User.find_by needed to response to these problems?

[pid  2254] write(1, "\33[32m.\33[0m", 10.) = 10
[pid  2254] epoll_wait(3, [], 32, 0)    = 0
[pid  2254] openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 8
[pid  2254] lseek(8, 0, SEEK_CUR)       = 0
[pid  2254] fstat(8, {st_mode=S_IFREG|0644, st_size=1755, ...}) = 0
[pid  2254] read(8, "[SECRET]"..., 4096) = 1755
[pid  2254] lseek(8, 0, SEEK_CUR)       = 1755
[pid  2254] read(8, "", 4096)           = 0
[pid  2254] close(8)                    = 0
[pid  2254] rt_sigprocmask(SIG_BLOCK, [HUP USR1 USR2 PIPE ALRM CHLD TSTP URG VTALRM PROF WINCH IO], [], 8) = 0
[pid  2254] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 8
[pid  2254] getsockopt(8, SOL_SOCKET, SO_RCVBUF, [212992], [4]) = 0
[pid  2254] setsockopt(8, SOL_SOCKET, SO_RCVBUFFORCE, [8388608], 4) = -1 EPERM (Operation not permitted)
[pid  2254] setsockopt(8, SOL_SOCKET, SO_RCVBUF, [8388608], 4) = 0
[pid  2254] getsockopt(8, SOL_SOCKET, SO_SNDBUF, [212992], [4]) = 0
[pid  2254] setsockopt(8, SOL_SOCKET, SO_SNDBUFFORCE, [8388608], 4) = -1 EPERM (Operation not permitted)
[pid  2254] setsockopt(8, SOL_SOCKET, SO_SNDBUF, [8388608], 4) = 0
[pid  2254] connect(8, {sa_family=AF_UNIX, sun_path="/run/dbus/system_bus_socket"}, 29) = -1 ENOENT (No such file or directory)
[pid  2254] close(8)                    = 0
[pid  2254] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid  2254] write(1, "\33[31mE\33[0m", 10E) = 10

This occurs same for about groups: spec/std/system/group_spec.cr.

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueThis is an issue suited for newcomers to become aquianted with working on the codebase.help wantedThis issue is generally accepted and needs someone to pick it upkind:bugA bug in the code. Does not apply to documentation, specs, etc.topic:stdlib

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions