Open ikerexxe opened 9 months ago
Can you please tell me the privilege/component structure of how you use umockdev? Are you using the CLI (umockdev-run
) or the API to build the mock env? I suppose you build that from a root process and expect to use it from a non-root process?
For the CLI you could just run it via runuser
, from the API you could just temporarily switch to the target user with seteuid()
. But I suppose that's not possible somehow. Hence, I don't yet understand what kind of new API/CLI/feature you need to support your use case? I. e. where exactly would you like to specify the target user? An umockdev-run
CLI option? An API call? Something else?
This information does not really belong into the recorded .umockdev
file, as it's highly specific to the caller, not to the recorded device.
Also, what do you mean by "accessed"? Many devices are read-only for unpriv users by default, some are world writable. Does your non-root consumer need to write to them?
One option would be to record the permissions and owner into the .umockdev
file, and restore the permissions (and the owner if running as root) in umockdev-run. But I don't really want to create world-writable files, they are kind of dangerous. So I'm interested in your specific use case.
We use the CLI (umockdev-record
and umockdev-run
) to build the mock environment. Where can I find some documentation that explains how to user runuser
? Perhaps we could use it.
I have one question regarding the operation of this tool. When we run umockdev-run
does it write to the device? Or does it only read? I mean, as I understand it when you communicate with a physical device you need to read and write, but I don't know if this is the case here.
@madhuriupadhye can you confirm that you are doing the umockdev recording as root user?
@ikerexxe runuser
is a standard util-linux thing, similar to su -c 'command' user
, just nicer to use as it avoids a level of quoting.
BTW, for this problem the user that umockdev-record
runs as isn't super important, only that it needs to be able to access the real devices for ioctl etc. recording. Your troubles (between root and sssd) happen on the replay side.
@ikerexxe
runuser
is a standard util-linux thing, similar tosu -c 'command' user
, just nicer to use as it avoids a level of quoting.
We are using su, so I don't think runuser
would help us.
No no, this isn't about su vs. runuser. I'm interested in a structural overview which components are in your test setup, i.e. how umockdev{-record,run} or the umockdev API hangs together with the things you want to test, and which privileges each process has, etc.
We use the CLI (
umockdev-record
andumockdev-run
) to build the mock environment. Where can I find some documentation that explains how to userrunuser
? Perhaps we could use it.I have one question regarding the operation of this tool. When we run
umockdev-run
does it write to the device? Or does it only read? I mean, as I understand it when you communicate with a physical device you need to read and write, but I don't know if this is the case here.@madhuriupadhye can you confirm that you are doing the umockdev recording as root user?
Yes, we did and doing recording as a root user.
@madhuriupadhye As I said, the recording side is much less interesting. I still need to understand how your root/non-root test processes and umockdev-run (or whatever else) hang together, and where the privilege boundaries are. There are several ways how permissions could be addressed/changed, but I need to understand your setup.
I can only speak from the development side, and how the functionality works. I'll let Madhuri provide you the exact details about the testing environment.
All the communication from SSSD happens in a binary called passkey_child
. Depending on the distribution it's owned by root or sssd and it has the following permissions 755. As said before, this is the binary that communicated with the FIDO2 device and it relies on libfido2 for that.
Note: if you are using Fedora 39+ you can install this binary by installing the sssd-passkey
package. The file is present at /usr/libexec/sssd/passkey_child
.
Do you miss any details?
passkey_child
doesn't (shouldn't) have SUID bit (or any other file caps) set .
It's executed by other SSSD processes that are run under configured user (either 'root' or 'sssd').
I'm still missing pretty much all of the details in this and this comment. I can guess that you run umockdev-run
as root with some recording in the test setup, and then do something(?) that calls a process owned by a non-root user (which is now clarified to be passkey_child
, running as sysuser sssd
, right?), which is supposed to access the testbed. There's no suid involved anywhere, so I suppose it's simply called by the sssd.service daemon?
So the most obvious thing to do would be to run umockdev-run
as user sssd
, so that both that and root processes can access the testbed. But I guess you already tried that? What went wrong there? Perhaps that's much easier to fix than reimplementing Linux' ACL system in umockdev..
So the most obvious thing to do would be to run
umockdev-run
as usersssd
Would it work other way round: run umockdev-run
as user sssd
but passkey_child
as user root
?
We strive to test both modes (privileged & unprivileged SSSD)
Sure, a root process has no trouble accessing files owned by any user. (Unless it drops CAP_DAC_OVERRIDE)
@ikerexxe @alexey-tikhonov Just to avoid misunderstandings: This isn't actionable for me right now, I'm still waiting for your input/details.
Meanwhile we realized that real tokens are (also) not accessible by non privileged users.
For this reason following udev rule was added to sssd-passkey package: https://github.com/SSSD/sssd/blob/master/contrib/90-sssd-token-access.rules.in
But looks like it doesn't work for mocked devices...
Sure, a root process has no trouble accessing files owned by any user. (Unless it drops CAP_DAC_OVERRIDE)
It does drop all capabilities.
This is how 'umockdev-run' is executed: https://github.com/SSSD/sssd-test-framework/blob/ff10c0fd5ed949ad426a2c9b5c3d47ac611643f8/sssd_test_framework/utils/authentication.py#L352
'run_su' script has 'chmod -R a+rwx $UMOCKDEV_DIR': https://github.com/SSSD/sssd-test-framework/blob/ff10c0fd5ed949ad426a2c9b5c3d47ac611643f8/sssd_test_framework/utils/authentication.py#L341C17-L341C45
But this doesn't help for some reason...
'run_su' script has 'chmod -R a+rwx $UMOCKDEV_DIR': https://github.com/SSSD/sssd-test-framework/blob/ff10c0fd5ed949ad426a2c9b5c3d47ac611643f8/sssd_test_framework/utils/authentication.py#L341C17-L341C45
But this doesn't help for some reason...
Ah, of course, it doesn't help because this is a source dir, that is being replayed, not a device file.
I wonder if it would work to just chown o+rw /dev/hidraw* in the test env...
So the most obvious thing to do would be to run
umockdev-run
as usersssd
@martinpitt, how will umockdev-run
create a file under /dev/ then?
@martinpitt, is it possible to make following udev rule work with 'umockdev-run':
# cat ./usr/lib/udev/rules.d/90-sssd-token-access.rules
# this udev file should be used with udev 188 and newer
ACTION!="add|change", GOTO="sssd_end"
# Allow SSSD to access security tokens
SUBSYSTEM=="hidraw", ENV{ID_SECURITY_TOKEN}=="1", RUN{program}+="/usr/bin/setfacl -m u:sssd:rw $env{DEVNAME}"
LABEL="sssd_end"
?
I tried both 'runuser' and 'setpriv' without luck so far.
@alexey-tikhonov sorry for the late answer, this slipped through the cracks :cry:
umockdev doesn't run udev rules at all, so I'm afraid no. You'll have to call setfacl
manually in your test after creating the mock env.
@martinpitt,
Usage:
umockdev-run [OPTION?] -- program [args..]
-- by the moment 'umockdev-run' starts execution of 'program', is mocked device file already available?
In our case 'program' is a script. I added setfacl -m u:sssd:rw /dev/hidraw*
to this script and it fails with
setfacl: /dev/hidraw1: No such file or directory
We'd like to be able to use umockdev as unprivileged users, but currently the directory and files that need to be accessed by umockdev are hardcoded as root.
Provide a way to tune the owner of the umockdev directory and files to another (unprivileged) user.