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
Preparation for the nspawn-OCI work #10996
Conversation
… in range As it turns out glibc and the Linux kernel have different ideas about the size of dev_t and how many bits exist for the major and the minor. When validating major/minor numbers we should check against the kernel's actual sizes, hence add macros for this.
…VALID()/DEVICE_MINOR_VALID() Let's be a bit more careful when parsing major/minor pairs, and filter out more corner cases. This also means using safe_atou() rather than sscanf() to avoid weird negative unsigned handling and such.
We should probably drop path_join() entirely in the long run (and then rename path_join_many() to it?), but for now let's make one a wrapper for the other.
…ock/* and /dev/char/* device nodes This adds some code to hanlde /dev/block/* and /dev/char/* device node paths specially: instead of actually stat()ing them we'll just parse the major/minor name from the name. This is useful 'hack' to allow clients to install whitelists for devices that don't actually have to exist. Also, let's similarly handle /run/systemd/inaccessible/{blk|chr}. This allows us to simplify our built-in default whitelist to not require a "ignore_enoent" mode for these nodes. In general we should be careful with hardcoding major/minor numbers, but in this case this should safe.
Previously we'd allow pattern expressions such as "char-input" to match all input devices. Internally, this would look up the right major to test in /proc/devices. With this commit the syntax is slightly extended: - "char-*" can be used to match any kind of character device, and similar "block-*. This expression would work previously already, but instead of actually installing a wildcard match it would install many individual matches for everything listed in /proc/devices. - "char-<MAJOR>" with "<MAJOR>" being a numerical parameter works now too. This allows clients to install whitelist items by specifying the major directly. The main reason to add these is to provide limited compat support for clients that for some reason contain whitelists with major/minor numbers (such as OCI containers).
…d device_path_parse_major_minor() device_path_make_{major_minor|canonical) generate device node paths given a mode_t and a dev_t. We have similar code all over the place, let's unify this in one place. The former will generate a "/dev/char/" or "/dev/block" path, and never go to disk. The latter then goes to disk and resolves that path to the actual path of the device node. device_path_parse_major_minor() reverses device_path_make_major_minor(), also withozut going to disk. We have similar code doing something like this at various places, let's unify this in a single set of functions. This also allows us to teach them special tricks, for example handling of the /run/systemd/inaccessible/{blk|chr} device nodes, which we use for masking device nodes, and which do not exist in /dev/char/* and /dev/block/*
…r_minor_path() calls
Not only when we populate the "devices" cgroup controller we need major/minor numbers, but for the io/blkio one it's the same, hence let's use the same logic for both.
Let's generalize this, so that we can use this in nspawn later on, which is pretty useful as we need to be able to mask files from the inner child of nspawn too, where the host's /run/systemd/inaccessible directory is not visible anymore. Moreover, if nspawn can create these nodes on its own before the payload this means the payload can run with fewer privileges.
This has been split out of #9762 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
return -EINVAL; | ||
} | ||
|
||
if (chmod(fd_path, mode & 07777) < 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of & 07777
I think it'd be more reasonable to do assert((mode & 07777) == 0);
or even assert((mode & 0777) == 0);
since we don't ever set those high bits this way.
This stuff is generally useful even outside of OCI. Some more, some less. But let's get this merged, so that I don't have to constantly rebase this