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

setgid bit in chmod dropped inconsistently #6800

Closed
Blub opened this issue Oct 30, 2017 · 8 comments · Fixed by #7270
Closed

setgid bit in chmod dropped inconsistently #6800

Blub opened this issue Oct 30, 2017 · 8 comments · Fixed by #7270
Labels
Type: Regression Indicates a functional regression

Comments

@Blub
Copy link
Contributor

Blub commented Oct 30, 2017

System information

Type Version/Name
Distribution Name Debian
Distribution Version Stretch
Linux Kernel 4.13.4-1-pve
Architecture x86_64
ZFS Version tested git-master & 0.7.2
SPL Version tested git-master & 0.7.2

Describe the problem you're observing

The setgid bit of a chmod() call as root (with all usual capabilities
(CAP_FSETID, CAP_FOWNER, ...) from within a user namespace drops the setgid bit
if the user (root) is the owner of the file while the file belongs to a group
one is currently not part of.

# id
uid=0(root) gid=0(root) groups=0(root)
# touch asdf
# chmod 2755 asdf
# ls -l asdf
-rwxr-sr-x 1 root root 0 Oct 30 15:33 asdf     <- ok - worked
# chgrp 88 asdf
# ls -l asdf
-rwxr-xr-x 1 root 88 0 Oct 30 15:33 asdf       <- ok - lost setgid as as expected
# chmod 2755 asdf
# ls -l asdf
-rwxr-xr-x 1 root 88 0 Oct 30 15:33 asdf       <- wrong - setgid ignored
# chown 88 asdf
# chmod 2755 asdf
# ls -l asdf
-rwxr-sr-x 1 88 88 0 Oct 30 15:33 asdf         <- ok - setgid honored (inconsistent!)

Note that as root one can simply use setgroups() to work around this issue
usually.

This seems to have happened together with the zfs allow change set. At least
when adapting secpolicy_vnode_setids_setgids() in module/zfs/policy.c to use
an ns_capable(current_user_ns(), cap) check rather than the regular
capable() check from priv_policy() the setgid bit is not dropped anymore.
I used the following change to test (it also adds a check for whether the gid
has a mapping in the current namespace):
Blub@dd97fcf

I'm not sure whether the other functions using priv_policy() also require more
user namespace specific adjustments, and the comment above the function doesn't
help me figure that out ;-)
I was, however, unable to find additional easily triggerable code-paths which
misbehave in user namespaces, but I'm quite new to the code, so there is that...

@behlendorf
Copy link
Contributor

I'm not sure whether the other functions using priv_policy() also require more
user namespace specific adjustments.

Nice find. In fact, I believe priv_policy() can be updated to always check the user namespace. But we'll have to do some manual testing to verify this is true. We should add some user namespace tests to the ZFS Test Suite to verify the behavior is correct.

@MarkGavalda
Copy link

MarkGavalda commented Nov 2, 2017

I can confirm this affects all releases since (at least) 0.7.1, we're running ZFS on lots of Ubuntu servers and all of them are affected that have been upgraded to 0.7.x. Thanks for the detailed tests @Blub we were able to work around this bug with your help.

@behlendorf behlendorf added the Type: Regression Indicates a functional regression label Nov 3, 2017
Blub added a commit to Blub/zfs that referenced this issue Nov 6, 2017
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
@Blub
Copy link
Contributor Author

Blub commented Nov 6, 2017

After reading through more the zfs & user namespace related kernel codes I was wondering if something like this was going in the right direction: master...Blub:rfc-wip-userns-policy
This still lacks id mapping in the allow ioctl, so user namespaces still see the "real" uids/gids, which makes the allow permission somewhat messy with user namespaces.
The first patch there is the important one to fix the regression, so I'd like to get some version of that merged soon if possible, as for the rest, I'd like some feedback before investing more time :-)

@behlendorf
Copy link
Contributor

@Blub yes, I think your on exactly the right track with this and should continue. I'm particularly happy to see you've added some initial coverage for user namespaces!

Blub added a commit to Blub/zfs that referenced this issue Nov 8, 2017
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
@Blub
Copy link
Contributor Author

Blub commented Nov 8, 2017

While adding uid/gid mapping for ZFS_IOC_{GET,SET}_FSACL I was wondering if there's a reason why some of the loops over nvlists take the nvpair's name and then do an nvlist_lookup_* instead of using nvpair_value_*, for instance module/zcommon/zfs_deleg.c's zfs_deleg_verify_nvlist(). In my mapping code using nvpair_value_nvlist() seems to work as well? Since the mentioned function explicitly handles ENOENT separately I thought it might be a concurrency thing, but the function is only used coming from these ioctls, so the data should only be accessed by one thread in this case.

@behlendorf
Copy link
Contributor

Depending on the flags passed when the nvlist_t was created there may or may not be a difference. If the nvlist_t was created with the NV_UNIQUE_NAME* flag then they're going to be equivalent. Otherwise the list may contain duplicate names which the lookup variant may return instead. As for concurrency the caller is responsible for any locking required.

Blub added a commit to Blub/zfs that referenced this issue Nov 14, 2017
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
Blub added a commit to Blub/zfs that referenced this issue Nov 14, 2017
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
@stgraber
Copy link

stgraber commented Mar 5, 2018

@Blub as there been some progress on a fix for this?

We (LXD) have just noticed a number of our users start hitting this as they switched to distributions shipping 0.7.x, most notably the upcoming Ubuntu 18.04 LTS.

Having package installations silently drop setgid makes for extremely annoying bugs to figure out...

@Blub
Copy link
Contributor Author

Blub commented Mar 5, 2018

For that particular patch to be merged the only missing parts are the detection of older kernels without ns_capable/cred->user_ns. I really need to give this a higher priority now and should get separate this part out into its own PR.

Blub added a commit to Blub/zfs that referenced this issue Mar 5, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
Blub added a commit to Blub/zfs that referenced this issue Mar 7, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

This also adds an initial user namespace regression test
for the setgid bit loss, with a user_ns_exec helper usable
in further tests.

Additionally, configure checks for the required user
namespace related features are added for:
  * ns_capable
  * kuid/kgid_has_mapping()
  * user_ns in cred_t

Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800
behlendorf pushed a commit that referenced this issue Mar 7, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

This also adds an initial user namespace regression test
for the setgid bit loss, with a user_ns_exec helper usable
in further tests.

Additionally, configure checks for the required user
namespace related features are added for:
  * ns_capable
  * kuid/kgid_has_mapping()
  * user_ns in cred_t

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes #6800 
Closes #7270
tonyhutter pushed a commit to tonyhutter/zfs that referenced this issue Mar 12, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

This also adds an initial user namespace regression test
for the setgid bit loss, with a user_ns_exec helper usable
in further tests.

Additionally, configure checks for the required user
namespace related features are added for:
  * ns_capable
  * kuid/kgid_has_mapping()
  * user_ns in cred_t

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800 
Closes openzfs#7270
tonyhutter pushed a commit to tonyhutter/zfs that referenced this issue Mar 13, 2018
This is a squashed patchset for zfs-0.7.7.  The individual commits are
in the tonyhutter:zfs-0.7.7-hutter branch.  I squashed the commits so
that buildbot wouldn't have to run against each one, and because
github/builbot seem to have a maximum limit of 30 commits they can
test from a PR.

- Fix MMP write frequency for large pools openzfs#7205 openzfs#7289
- Handle zio_resume and mmp => off openzfs#7286
- Fix zfs-kmod builds when using rpm >= 4.14 openzfs#7284
- zdb and inuse tests don't pass with real disks openzfs#6939 openzfs#7261
- Take user namespaces into account in policy checks openzfs#6800 openzfs#7270
- Detect long config lock acquisition in mmp openzfs#7212
- Linux 4.16 compat: get_disk_and_module() openzfs#7264
- Change checksum & IO delay ratelimit values openzfs#7252
- Increment zil_itx_needcopy_bytes properly openzfs#6988 openzfs#7176
- Fix some typos openzfs#7237
- Fix zpool(8) list example to match actual format openzfs#7244
- Add SMART self-test results to zpool status -c openzfs#7178
- Add scrub after resilver zed script openzfs#4662 openzfs#7086
- Fix free memory calculation on v3.14+ openzfs#7170
- Report duration and error in mmp_history entries openzfs#7190
- Do not initiate MMP writes while pool is suspended openzfs#7182
- Linux 4.16 compat: use correct *_dec_and_test()
- Allow modprobe to fail when called within systemd openzfs#7174
- Add SMART attributes for SSD and NVMe openzfs#7183 openzfs#7193
- Correct count_uberblocks in mmp.kshlib openzfs#7191
- Fix config issues: frame size and headers openzfs#7169
- Clarify zinject(8) explanation of -e openzfs#7172
- OpenZFS 8857 - zio_remove_child() panic due to already destroyed parent zio openzfs#7168
- 'zfs receive' fails with "dataset is busy" openzfs#7129 openzfs#7154
- contrib/initramfs: add missing conf.d/zfs openzfs#7158
- mmp should use a fixed tag for spa_config locks openzfs#6530 openzfs#7155
- Handle zap_add() failures in mixed case mode openzfs#7011 openzfs#7054
- Fix zdb -ed on objset for exported pool openzfs#7099 openzfs#6464
- Fix zdb -E segfault openzfs#7099
- Fix zdb -R decompression openzfs#7099 openzfs#4984
- Fix racy assignment of zcb.zcb_haderrors openzfs#7099
- Fix zle_decompress out of bound access openzfs#7099
- Fix zdb -c traverse stop on damaged objset root openzfs#7099
- Linux 4.11 compat: avoid refcount_t name conflict openzfs#7148
- Linux 4.16 compat: inode_set_iversion() openzfs#7148
- OpenZFS 8966 - Source file zfs_acl.c, function zfs_aclset_common contains a use after end of the lifetime of a local variable openzfs#7141
- Remove deprecated zfs_arc_p_aggressive_disable openzfs#7135
- Fix default libdir for Debian/Ubuntu openzfs#7083 openzfs#7101
- Bug fix in qat_compress.c for vmalloc addr check openzfs#7125
- Fix systemd_ RPM macros usage on Debian-based distributions openzfs#7074 openzfs#7100
- Emit an error message before MMP suspends pool openzfs#7048
- ZTS: Fix create-o_ashift test case openzfs#6924 openzfs#6977
- Fix --with-systemd on Debian-based distributions (openzfs#6963) openzfs#6591 openzfs#6963
- Remove vn_rename and vn_remove dependency openzfs/spl#648 openzfs#6753
- Add support for "--enable-code-coverage" option openzfs#6670
- Make "-fno-inline" compile option more accessible openzfs#6605
- Add configure option to enable gcov analysis openzfs#6642
- Implement --enable-debuginfo to force debuginfo openzfs#2734
- Make --enable-debug fail when given bogus args openzfs#2734

Signed-off-by: Tony Hutter <[email protected]>
Requires-spl: refs/pull/690/head
tonyhutter pushed a commit to tonyhutter/zfs that referenced this issue Mar 13, 2018
This is a squashed patchset for zfs-0.7.7.  The individual commits are
in the tonyhutter:zfs-0.7.7-hutter branch.  I squashed the commits so
that buildbot wouldn't have to run against each one, and because
github/builbot seem to have a maximum limit of 30 commits they can
test from a PR.

- Fix MMP write frequency for large pools openzfs#7205 openzfs#7289
- Handle zio_resume and mmp => off openzfs#7286
- Fix zfs-kmod builds when using rpm >= 4.14 openzfs#7284
- zdb and inuse tests don't pass with real disks openzfs#6939 openzfs#7261
- Take user namespaces into account in policy checks openzfs#6800 openzfs#7270
- Detect long config lock acquisition in mmp openzfs#7212
- Linux 4.16 compat: get_disk_and_module() openzfs#7264
- Change checksum & IO delay ratelimit values openzfs#7252
- Increment zil_itx_needcopy_bytes properly openzfs#6988 openzfs#7176
- Fix some typos openzfs#7237
- Fix zpool(8) list example to match actual format openzfs#7244
- Add SMART self-test results to zpool status -c openzfs#7178
- Add scrub after resilver zed script openzfs#4662 openzfs#7086
- Fix free memory calculation on v3.14+ openzfs#7170
- Report duration and error in mmp_history entries openzfs#7190
- Do not initiate MMP writes while pool is suspended openzfs#7182
- Linux 4.16 compat: use correct *_dec_and_test()
- Allow modprobe to fail when called within systemd openzfs#7174
- Add SMART attributes for SSD and NVMe openzfs#7183 openzfs#7193
- Correct count_uberblocks in mmp.kshlib openzfs#7191
- Fix config issues: frame size and headers openzfs#7169
- Clarify zinject(8) explanation of -e openzfs#7172
- OpenZFS 8857 - zio_remove_child() panic due to already destroyed
  parent zio openzfs#7168
- 'zfs receive' fails with "dataset is busy" openzfs#7129 openzfs#7154
- contrib/initramfs: add missing conf.d/zfs openzfs#7158
- mmp should use a fixed tag for spa_config locks openzfs#6530 openzfs#7155
- Handle zap_add() failures in mixed case mode openzfs#7011 openzfs#7054
- Fix zdb -ed on objset for exported pool openzfs#7099 openzfs#6464
- Fix zdb -E segfault openzfs#7099
- Fix zdb -R decompression openzfs#7099 openzfs#4984
- Fix racy assignment of zcb.zcb_haderrors openzfs#7099
- Fix zle_decompress out of bound access openzfs#7099
- Fix zdb -c traverse stop on damaged objset root openzfs#7099
- Linux 4.11 compat: avoid refcount_t name conflict openzfs#7148
- Linux 4.16 compat: inode_set_iversion() openzfs#7148
- OpenZFS 8966 - Source file zfs_acl.c, function zfs_aclset_common
  contains a use after end of the lifetime of a local variable openzfs#7141
- Remove deprecated zfs_arc_p_aggressive_disable openzfs#7135
- Fix default libdir for Debian/Ubuntu openzfs#7083 openzfs#7101
- Bug fix in qat_compress.c for vmalloc addr check openzfs#7125
- Fix systemd_ RPM macros usage on Debian-based distributions openzfs#7074
  openzfs#7100
- Emit an error message before MMP suspends pool openzfs#7048
- ZTS: Fix create-o_ashift test case openzfs#6924 openzfs#6977
- Fix --with-systemd on Debian-based distributions (openzfs#6963) openzfs#6591 openzfs#6963
- Remove vn_rename and vn_remove dependency openzfs/spl#648 openzfs#6753
- Add support for "--enable-code-coverage" option openzfs#6670
- Make "-fno-inline" compile option more accessible openzfs#6605
- Add configure option to enable gcov analysis openzfs#6642
- Implement --enable-debuginfo to force debuginfo openzfs#2734
- Make --enable-debug fail when given bogus args openzfs#2734

Signed-off-by: Tony Hutter <[email protected]>
Requires-spl: refs/pull/690/head
tonyhutter pushed a commit to tonyhutter/zfs that referenced this issue Mar 13, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

This also adds an initial user namespace regression test
for the setgid bit loss, with a user_ns_exec helper usable
in further tests.

Additionally, configure checks for the required user
namespace related features are added for:
  * ns_capable
  * kuid/kgid_has_mapping()
  * user_ns in cred_t

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes openzfs#6800 
Closes openzfs#7270
tonyhutter pushed a commit to tonyhutter/zfs that referenced this issue Mar 13, 2018
This is a squashed patchset for zfs-0.7.7.  The individual commits are
in the tonyhutter:zfs-0.7.7-hutter branch.  I squashed the commits so
that buildbot wouldn't have to run against each one, and because
github/builbot seem to have a maximum limit of 30 commits they can
test from a PR.

- Fix MMP write frequency for large pools openzfs#7205 openzfs#7289
- Handle zio_resume and mmp => off openzfs#7286
- Fix zfs-kmod builds when using rpm >= 4.14 openzfs#7284
- zdb and inuse tests don't pass with real disks openzfs#6939 openzfs#7261
- Take user namespaces into account in policy checks openzfs#6800 openzfs#7270
- Detect long config lock acquisition in mmp openzfs#7212
- Linux 4.16 compat: get_disk_and_module() openzfs#7264
- Change checksum & IO delay ratelimit values openzfs#7252
- Increment zil_itx_needcopy_bytes properly openzfs#6988 openzfs#7176
- Fix some typos openzfs#7237
- Fix zpool(8) list example to match actual format openzfs#7244
- Add SMART self-test results to zpool status -c openzfs#7178
- Add scrub after resilver zed script openzfs#4662 openzfs#7086
- Fix free memory calculation on v3.14+ openzfs#7170
- Report duration and error in mmp_history entries openzfs#7190
- Do not initiate MMP writes while pool is suspended openzfs#7182
- Linux 4.16 compat: use correct *_dec_and_test()
- Allow modprobe to fail when called within systemd openzfs#7174
- Add SMART attributes for SSD and NVMe openzfs#7183 openzfs#7193
- Correct count_uberblocks in mmp.kshlib openzfs#7191
- Fix config issues: frame size and headers openzfs#7169
- Clarify zinject(8) explanation of -e openzfs#7172
- OpenZFS 8857 - zio_remove_child() panic due to already destroyed
  parent zio openzfs#7168
- 'zfs receive' fails with "dataset is busy" openzfs#7129 openzfs#7154
- contrib/initramfs: add missing conf.d/zfs openzfs#7158
- mmp should use a fixed tag for spa_config locks openzfs#6530 openzfs#7155
- Handle zap_add() failures in mixed case mode openzfs#7011 openzfs#7054
- Fix zdb -ed on objset for exported pool openzfs#7099 openzfs#6464
- Fix zdb -E segfault openzfs#7099
- Fix zdb -R decompression openzfs#7099 openzfs#4984
- Fix racy assignment of zcb.zcb_haderrors openzfs#7099
- Fix zle_decompress out of bound access openzfs#7099
- Fix zdb -c traverse stop on damaged objset root openzfs#7099
- Linux 4.11 compat: avoid refcount_t name conflict openzfs#7148
- Linux 4.16 compat: inode_set_iversion() openzfs#7148
- OpenZFS 8966 - Source file zfs_acl.c, function zfs_aclset_common
  contains a use after end of the lifetime of a local variable openzfs#7141
- Remove deprecated zfs_arc_p_aggressive_disable openzfs#7135
- Fix default libdir for Debian/Ubuntu openzfs#7083 openzfs#7101
- Bug fix in qat_compress.c for vmalloc addr check openzfs#7125
- Fix systemd_ RPM macros usage on Debian-based distributions openzfs#7074
  openzfs#7100
- Emit an error message before MMP suspends pool openzfs#7048
- ZTS: Fix create-o_ashift test case openzfs#6924 openzfs#6977
- Fix --with-systemd on Debian-based distributions (openzfs#6963) openzfs#6591 openzfs#6963
- Remove vn_rename and vn_remove dependency openzfs/spl#648 openzfs#6753
- Fix "--enable-code-coverage" debug build openzfs#6674
- Update codecov.yml openzfs#6669
- Add support for "--enable-code-coverage" option openzfs#6670
- Make "-fno-inline" compile option more accessible openzfs#6605
- Add configure option to enable gcov analysis openzfs#6642
- Implement --enable-debuginfo to force debuginfo openzfs#2734
- Make --enable-debug fail when given bogus args openzfs#2734

Signed-off-by: Tony Hutter <[email protected]>
Requires-spl: refs/pull/690/head
tonyhutter pushed a commit that referenced this issue Mar 19, 2018
Change file related checks to use user namespaces and make
sure involved uids/gids are mappable in the current
namespace.

Note that checks without file ownership information will
still not take user namespaces into account, as some of
these should be handled via 'zfs allow' (otherwise root in a
user namespace could issue commands such as `zpool export`).

This also adds an initial user namespace regression test
for the setgid bit loss, with a user_ns_exec helper usable
in further tests.

Additionally, configure checks for the required user
namespace related features are added for:
  * ns_capable
  * kuid/kgid_has_mapping()
  * user_ns in cred_t

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Wolfgang Bumiller <[email protected]>
Closes #6800
Closes #7270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Regression Indicates a functional regression
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants