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

Tune owner for umockdev dir/files #221

Open
ikerexxe opened this issue Dec 1, 2023 · 22 comments
Open

Tune owner for umockdev dir/files #221

ikerexxe opened this issue Dec 1, 2023 · 22 comments
Labels

Comments

@ikerexxe
Copy link

ikerexxe commented Dec 1, 2023

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.

@martinpitt
Copy link
Owner

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.

@martinpitt
Copy link
Owner

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.

@ikerexxe
Copy link
Author

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?

@martinpitt
Copy link
Owner

@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
Copy link
Author

@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.

We are using su, so I don't think runuser would help us.

@martinpitt
Copy link
Owner

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.

@madhuriupadhye
Copy link

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?

Yes, we did and doing recording as a root user.

@martinpitt
Copy link
Owner

@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.

@ikerexxe
Copy link
Author

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-passkeypackage. The file is present at /usr/libexec/sssd/passkey_child.

Do you miss any details?

@alexey-tikhonov
Copy link

alexey-tikhonov commented Dec 20, 2023

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').

@martinpitt
Copy link
Owner

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..

@alexey-tikhonov
Copy link

So the most obvious thing to do would be to run umockdev-run as user sssd

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)

@martinpitt
Copy link
Owner

Sure, a root process has no trouble accessing files owned by any user. (Unless it drops CAP_DAC_OVERRIDE)

@martinpitt
Copy link
Owner

@ikerexxe @alexey-tikhonov Just to avoid misunderstandings: This isn't actionable for me right now, I'm still waiting for your input/details.

@alexey-tikhonov
Copy link

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...

@alexey-tikhonov
Copy link

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...

@alexey-tikhonov
Copy link

'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...

@alexey-tikhonov
Copy link

So the most obvious thing to do would be to run umockdev-run as user sssd

@martinpitt, how will umockdev-run create a file under /dev/ then?

@alexey-tikhonov
Copy link

@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"

?

@alexey-tikhonov
Copy link

I tried both 'runuser' and 'setpriv' without luck so far.

@martinpitt
Copy link
Owner

@alexey-tikhonov sorry for the late answer, this slipped through the cracks 😢

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.

@alexey-tikhonov
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants