<p dir="ltr"><br>
On Mar 29, 2015 5:18 PM, "Alban Crequy" <<a href="mailto:alban.crequy@gmail.com">alban.crequy@gmail.com</a>> wrote:<br>
><br>
> From: Alban Crequy <<a href="mailto:alban@endocode.com">alban@endocode.com</a>><br>
><br>
> Some systems abusively restrict mknod, even when the device node already<br>
> exists in /dev. This is unfortunate because it prevents systemd-nspawn<br>
> from creating the basic devices in /dev in the container.<br>
><br>
> This patch implements a workaround: when mknod fails, fallback on bind<br>
> mounts.</p>
<p dir="ltr">Could we just always use bind mounts and avoid the two code paths? </p>
<p dir="ltr">Tom</p>
<p dir="ltr">> Additionally, /dev/console was created with a mknod with the same<br>
> major/minor as /dev/null before bind mounting a pts on it. This patch<br>
> removes the mknod and creates an empty regular file instead.<br>
><br>
> In order to test this patch, I used the following configuration, which I<br>
> think should replicate the system with the abusive restriction on mknod:<br>
><br>
> # grep devices /proc/self/cgroup<br>
> 4:devices:/user.slice/restrict<br>
> # cat /sys/fs/cgroup/devices/user.slice/restrict/devices.list<br>
> c 1:9 r<br>
> c 5:2 rw<br>
> c 136:* rw<br>
> # systemd-nspawn --register=false -D .<br>
> ---<br>
> src/nspawn/nspawn.c | 27 ++++++++++++++-------------<br>
> 1 file changed, 14 insertions(+), 13 deletions(-)<br>
><br>
> diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c<br>
> index 300b6df..09fff38 100644<br>
> --- a/src/nspawn/nspawn.c<br>
> +++ b/src/nspawn/nspawn.c<br>
> @@ -1449,8 +1449,17 @@ static int copy_devnodes(const char *dest) {<br>
> return -r;<br>
> }<br>
><br>
> - if (mknod(to, st.st_mode, st.st_rdev) < 0)<br>
> - return log_error_errno(errno, "mknod(%s) failed: %m", to);<br>
> + if (mknod(to, st.st_mode, st.st_rdev) < 0) {<br>
> + if (errno != EPERM)<br>
> + return log_error_errno(errno, "mknod(%s) failed: %m", to);<br>
> +<br>
> + /* Some systems abusively restrict mknod but<br>
> + * allow bind mounts. */<br>
> + if (touch(to) < 0)<br>
> + return log_error_errno(errno, "touch (%s) failed: %m", to);<br>
> + if (mount(from, to, "bind", MS_BIND, NULL) < 0)<br>
> + return log_error_errno(errno, "both mknod and bind mount (%s) failed: %m", to);<br>
> + }<br>
><br>
> if (arg_userns && arg_uid_shift != UID_INVALID)<br>
> if (lchown(to, arg_uid_shift, arg_uid_shift) < 0)<br>
> @@ -1481,7 +1490,6 @@ static int setup_ptmx(const char *dest) {<br>
> static int setup_dev_console(const char *dest, const char *console) {<br>
> _cleanup_umask_ mode_t u;<br>
> const char *to;<br>
> - struct stat st;<br>
> int r;<br>
><br>
> assert(dest);<br>
> @@ -1489,24 +1497,17 @@ static int setup_dev_console(const char *dest, const char *console) {<br>
><br>
> u = umask(0000);<br>
><br>
> - if (stat("/dev/null", &st) < 0)<br>
> - return log_error_errno(errno, "Failed to stat /dev/null: %m");<br>
> -<br>
> r = chmod_and_chown(console, 0600, 0, 0);<br>
> if (r < 0)<br>
> return log_error_errno(r, "Failed to correct access mode for TTY: %m");<br>
><br>
> /* We need to bind mount the right tty to /dev/console since<br>
> * ptys can only exist on pts file systems. To have something<br>
> - * to bind mount things on we create a device node first, and<br>
> - * use /dev/null for that since we the cgroups device policy<br>
> - * allows us to create that freely, while we cannot create<br>
> - * /dev/console. (Note that the major minor doesn't actually<br>
> - * matter here, since we mount it over anyway). */<br>
> + * to bind mount things on we create a empty regular file. */<br>
><br>
> to = strjoina(dest, "/dev/console");<br>
> - if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0)<br>
> - return log_error_errno(errno, "mknod() for /dev/console failed: %m");<br>
> + if (touch(to) < 0)<br>
> + return log_error_errno(errno, "touch() for /dev/console failed: %m");<br>
><br>
> if (mount(console, to, "bind", MS_BIND, NULL) < 0)<br>
> return log_error_errno(errno, "Bind mount for /dev/console failed: %m");<br>
> --<br>
> 2.1.4<br>
><br>
> _______________________________________________<br>
> systemd-devel mailing list<br>
> <a href="mailto:systemd-devel@lists.freedesktop.org">systemd-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/systemd-devel">http://lists.freedesktop.org/mailman/listinfo/systemd-devel</a><br>
</p>