Description of problem:
Trying to build Ruby with --new-chroot option, the test suite hangs on TestFileUtils#test_chown_R_force test. As it turns out, the test expects to have some supplementary groups of the calling process available, but while they are available using --old-chroot, they are not available using --new-chroot. I submitted ticket to upstream to improve the test [1], but I'd expect --{new,old}-chroot to provide the same experience.
Version-Release number of selected component (if applicable):
$ rpm -q mock
mock-1.3.2-1.fc26.noarch
How reproducible:
Steps to Reproduce:
1.
2.
3.
Actual results:
Supplementary groups of the calling process are not available.
Expected results:
There are some supplementary groups of the calling process available.
Additional info:
This [2] is the implementation of Process.groups method, which is internally used by the test case [3].
I tried to prepare simple reproducer in C:
```
$ cat getgroups.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
main()
{
gid_t groupIDs[NGROUPS_MAX];
int i, count;
if ((count = getgroups(NGROUPS_MAX, groupIDs)) == -1)
perror("getgroups error");
else
if (count)
for (i = 0; i < count; i++)
printf("Group ID %d = %d\n", i + 1, (int) groupIDs[i]);
else
printf("No supplementary group\n");
}
$ gcc getgroups.c
getgroups.c:7:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main()
^~~~
```
and execute it:
```
$ mock -r ruby --unpriv --old-chroot --chroot '/builddir/getgroups/a.out'
INFO: mock.py version 1.3.2 starting (python version = 3.5.2)...
Start: init plugins
INFO: selinux enabled
INFO: {'cache_topdir': '/var/cache/mock', 'cachedir': '/var/cache/mock/ruby', 'basedir': '/var/lib/mock/ruby', 'root': 'ruby', 'opts': '-o %(resultdir)s %(resultdir)s', 'cmd': 'createrepo_c', 'resultdir': '/var/lib/mock/ruby/result'}
INFO: enabled package signing
Finish: init plugins
Start: run
Start: chroot init
INFO: LVM plugin enabled. Allocated pool data: 36.71%. Allocated metadata: 20.2%.
INFO: calling preinit hooks
INFO: enabled root cache
INFO: enabled dnf cache
Start: cleaning dnf metadata
Finish: cleaning dnf metadata
Mock Version: 1.3.2
INFO: Mock Version: 1.3.2
Finish: chroot init
INFO: Running in chroot: ['/builddir/getgroups/a.out']
Start: chroot ['/builddir/getgroups/a.out']
Group ID 1 = 135
Finish: chroot ['/builddir/getgroups/a.out']
Finish: run
$ mock -r ruby --unpriv --new-chroot --chroot '/builddir/getgroups/a.out'
INFO: mock.py version 1.3.2 starting (python version = 3.5.2)...
Start: init plugins
INFO: selinux disabled
INFO: {'cmd': 'createrepo_c', 'root': 'ruby', 'cachedir': '/var/cache/mock/ruby', 'opts': '-o %(resultdir)s %(resultdir)s', 'basedir': '/var/lib/mock/ruby', 'resultdir': '/var/lib/mock/ruby/result', 'cache_topdir': '/var/cache/mock'}
INFO: enabled package signing
Finish: init plugins
Start: run
Start: chroot init
INFO: LVM plugin enabled. Allocated pool data: 36.71%. Allocated metadata: 20.2%.
INFO: calling preinit hooks
INFO: enabled root cache
INFO: enabled dnf cache
Start: cleaning dnf metadata
Finish: cleaning dnf metadata
Mock Version: 1.3.2
INFO: Mock Version: 1.3.2
Finish: chroot init
INFO: Running in chroot: ['/builddir/getgroups/a.out']
Start: chroot ['/builddir/getgroups/a.out']
No supplementary group
Finish: chroot ['/builddir/getgroups/a.out']
Finish: run
```
As you can see, the --old-chroot variant returns one group, while the --new-chroot does not return any group.
[1] https://bugs.ruby-lang.org/issues/12910
[2] https://github.com/ruby/ruby/blob/911f3d95033f54c0e02107873cbb4219e0ba377c/process.c#L5823
[3] https://github.com/ruby/ruby/blob/911f3d95033f54c0e02107873cbb4219e0ba377c/test/fileutils/test_fileutils.rb#L145
I am able to reproduce it with plain systemd-nspawn:
[mirek@triple//tmp]1$ sudo /usr/bin/systemd-nspawn -q -M 36cda89a9cf74a088c47a782bda54299 -D /var/lib/mock/fedora-25-x86_64/root --setenv=HOSTNAME=mock --setenv=HOME=/builddir -u 1000 /bin/sh -i -l
[sudo] password for mirek:
sh-4.3$ /a.out
No supplementary group
sh-4.3$ id
uid=1000(mockbuild) gid=135(mockbuild) groups=135(mockbuild)
Note, that I'm not sure if "supplementary groups" should include the primary group. But it seems that this is default behaviour outside of container.
Comment 2Zbigniew Jędrzejewski-Szmek
2016-11-22 23:17:49 UTC
The getgroups(2) man page is pretty clear:
It is unspecified whether the effective group ID of the
calling process is included in the returned list.
(Thus, an application should also call getegid(2)
and add or remove the resulting value.)
I don't think there's any bug here.
Description of problem: Trying to build Ruby with --new-chroot option, the test suite hangs on TestFileUtils#test_chown_R_force test. As it turns out, the test expects to have some supplementary groups of the calling process available, but while they are available using --old-chroot, they are not available using --new-chroot. I submitted ticket to upstream to improve the test [1], but I'd expect --{new,old}-chroot to provide the same experience. Version-Release number of selected component (if applicable): $ rpm -q mock mock-1.3.2-1.fc26.noarch How reproducible: Steps to Reproduce: 1. 2. 3. Actual results: Supplementary groups of the calling process are not available. Expected results: There are some supplementary groups of the calling process available. Additional info: This [2] is the implementation of Process.groups method, which is internally used by the test case [3]. I tried to prepare simple reproducer in C: ``` $ cat getgroups.c #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <limits.h> main() { gid_t groupIDs[NGROUPS_MAX]; int i, count; if ((count = getgroups(NGROUPS_MAX, groupIDs)) == -1) perror("getgroups error"); else if (count) for (i = 0; i < count; i++) printf("Group ID %d = %d\n", i + 1, (int) groupIDs[i]); else printf("No supplementary group\n"); } $ gcc getgroups.c getgroups.c:7:1: warning: return type defaults to ‘int’ [-Wimplicit-int] main() ^~~~ ``` and execute it: ``` $ mock -r ruby --unpriv --old-chroot --chroot '/builddir/getgroups/a.out' INFO: mock.py version 1.3.2 starting (python version = 3.5.2)... Start: init plugins INFO: selinux enabled INFO: {'cache_topdir': '/var/cache/mock', 'cachedir': '/var/cache/mock/ruby', 'basedir': '/var/lib/mock/ruby', 'root': 'ruby', 'opts': '-o %(resultdir)s %(resultdir)s', 'cmd': 'createrepo_c', 'resultdir': '/var/lib/mock/ruby/result'} INFO: enabled package signing Finish: init plugins Start: run Start: chroot init INFO: LVM plugin enabled. Allocated pool data: 36.71%. Allocated metadata: 20.2%. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled dnf cache Start: cleaning dnf metadata Finish: cleaning dnf metadata Mock Version: 1.3.2 INFO: Mock Version: 1.3.2 Finish: chroot init INFO: Running in chroot: ['/builddir/getgroups/a.out'] Start: chroot ['/builddir/getgroups/a.out'] Group ID 1 = 135 Finish: chroot ['/builddir/getgroups/a.out'] Finish: run $ mock -r ruby --unpriv --new-chroot --chroot '/builddir/getgroups/a.out' INFO: mock.py version 1.3.2 starting (python version = 3.5.2)... Start: init plugins INFO: selinux disabled INFO: {'cmd': 'createrepo_c', 'root': 'ruby', 'cachedir': '/var/cache/mock/ruby', 'opts': '-o %(resultdir)s %(resultdir)s', 'basedir': '/var/lib/mock/ruby', 'resultdir': '/var/lib/mock/ruby/result', 'cache_topdir': '/var/cache/mock'} INFO: enabled package signing Finish: init plugins Start: run Start: chroot init INFO: LVM plugin enabled. Allocated pool data: 36.71%. Allocated metadata: 20.2%. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled dnf cache Start: cleaning dnf metadata Finish: cleaning dnf metadata Mock Version: 1.3.2 INFO: Mock Version: 1.3.2 Finish: chroot init INFO: Running in chroot: ['/builddir/getgroups/a.out'] Start: chroot ['/builddir/getgroups/a.out'] No supplementary group Finish: chroot ['/builddir/getgroups/a.out'] Finish: run ``` As you can see, the --old-chroot variant returns one group, while the --new-chroot does not return any group. [1] https://bugs.ruby-lang.org/issues/12910 [2] https://github.com/ruby/ruby/blob/911f3d95033f54c0e02107873cbb4219e0ba377c/process.c#L5823 [3] https://github.com/ruby/ruby/blob/911f3d95033f54c0e02107873cbb4219e0ba377c/test/fileutils/test_fileutils.rb#L145