<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div data-marker="__QUOTED_TEXT__"><div style="font-family:'arial' , 'helvetica' , sans-serif;font-size:12pt;color:#000000"><div>Hi Alexander.</div><br><div>I understand all of the concerns. Yes, it's possible to create a regular user inside of containers (at least in case of the rootless LXC and Docker containers), but this is a question of usability. </div><div>All existed Docker containers for a Yocto compilation (including tge CROPS described at the yoctoproject wiki) tried to use same UID/GID for files inside and outside of the container in order to allow to work with files both inside and outside of container. <br></div><div><br data-mce-bogus="1"></div><div>In the case of the main container subsystems (Docker, OCI) same level of a usability for rootless containers can be supported only if we allow compilation from UID == 0 because users own UID mapped to 0 in this containers. In order to support such configuration we, in any case, should modify somehow contamination check, check for a root user in the sanity.bbclass and disable root check from "mknod" module in gnulib (used by coreutils).</div><div><br data-mce-bogus="1"></div><div>Will it be appropriate if we allow such regime of the compilation with the following limitation:<br data-mce-bogus="1"></div><div>1. Allow compilation only from root user inside of the linux user namespace (not a real root)<br data-mce-bogus="1"></div><div>2. Allow such compilation only if there is "native_root_user" feature in DISTRO_FEATURES<br data-mce-bogus="1"></div><div>3. Each modified place will check this two conditions<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Will be such design appropriate compromise between safety and usability?<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Regards,<br>Nikolai<br data-mce-bogus="1"></div><br><hr id="zwchr"><div><blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:'helvetica' , 'arial' , sans-serif;font-size:12pt"><b>From: </b>"Alexander Kanavin" &lt;alex.kanavin@gmail.com&gt;<br><b>To: </b>"n merinov" &lt;n.merinov@inango-systems.com&gt;<br><b>Cc: </b>"openembedded-core" &lt;openembedded-core@lists.openembedded.org&gt;<br><b>Sent: </b>Tuesday, December 31, 2019 9:29:34 AM<br><b>Subject: </b>Re: [OE-core] [PATCH] sanity: allow to compile from root in user namespaces<br></blockquote></div><div><blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:'helvetica' , 'arial' , sans-serif;font-size:12pt"><div dir="ltr"><div>I believe it should be possible to create a regular user inside the container and then run bitbake as that user?&nbsp;</div><br><div>The patch effectively disables the host contamination check, fixes one recipe that breaks, and likely introduces other issues; the assumption (and automated testing) throughout the build is that it's run under a regular user.</div><br><div>Alex</div></div><br><div><div dir="ltr">On Tue, 31 Dec 2019 at 11:40, Nikolai Merinov via Openembedded-core &lt;<a href="mailto:openembedded-core@lists.openembedded.org" rel="nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">openembedded-core@lists.openembedded.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb( 204 , 204 , 204 );border-left-width:1px;border-left-style:solid">New rootless container subsystems rely on the "user namespaces"<br>
Linux feature. In order to create a container from a regular user the<br>
user uid and subuids mapped to the uid space inside of container.<br>
<br>
There are different default configurations used for different<br>
container subsystems:<br>
<br>
&nbsp;1. Rootless Docker[1] maps the user ID to 0, the subuids to range<br>
&nbsp; &nbsp; starting from 1.<br>
&nbsp;2. Rootless RunC[2] from OCI by default maps the user ID to 0 and<br>
&nbsp; &nbsp; ignores the subuids.<br>
&nbsp;3. LXC[3] maps the subuids to range from 0. UID not participates<br>
&nbsp; &nbsp; in the mapping.<br>
<br>
The LXC variant does not allow to work on same files simultaneusly<br>
inside and outside of a container. Variant suggested by other<br>
container susbsystems assumes that files owned by user should be<br>
owned by root in a container environment.<br>
<br>
In order to simplify Yocto compilation in such rootless containers I<br>
want to allow to start the bitbake from root user in user namespace<br>
and allow software compilation from root user in the described<br>
configuration. Additionally I want to provide minimal dockerfile<br>
suitable for the core-image-sato image compilation.<br>
<br>
--<br>
[1] <a href="https://docs.docker.com/engine/security/rootless/" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">https://docs.docker.com/engine/security/rootless/</a><br>
[2] <a href="https://github.com/opencontainers/runc#rootless-containers" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">https://github.com/opencontainers/runc#rootless-containers</a><br>
[3] <a href="https://linuxcontainers.org/lxc/getting-started/#creating-unprivileged-containers-as-a-user" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">https://linuxcontainers.org/lxc/getting-started/#creating-unprivileged-containers-as-a-user</a><br>
---<br>
&nbsp;meta/classes/insane.bbclass&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; 4 ++--<br>
&nbsp;meta/classes/sanity.bbclass&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 10 +++++++-<br>
&nbsp;meta/recipes-core/coreutils/<a href="http://coreutils_8.31.bb" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">coreutils_8.31.bb</a> |&nbsp; 1 +<br>
&nbsp;scripts/docker/Dockerfile&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 19 +++++++++++++++<br>
&nbsp;scripts/docker/oe-rootless-docker&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 24 +++++++++++++++++++<br>
&nbsp;5 files changed, 55 insertions(+), 3 deletions(-)<br>
&nbsp;create mode 100644 scripts/docker/Dockerfile<br>
&nbsp;create mode 100755 scripts/docker/oe-rootless-docker<br>
<br>
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass<br>
index 0564f9c2a4..3599ce3e6a 100644<br>
--- a/meta/classes/insane.bbclass<br>
+++ b/meta/classes/insane.bbclass<br>
@@ -876,12 +876,12 @@ def package_qa_check_host_user(path, name, d, elf, messages):<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;raise<br>
&nbsp; &nbsp; &nbsp;else:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;check_uid = int(d.getVar('HOST_USER_UID'))<br>
-&nbsp; &nbsp; &nbsp; &nbsp; if stat.st_uid == check_uid:<br>
+&nbsp; &nbsp; &nbsp; &nbsp; if check_uid != 0 and stat.st_uid == check_uid:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;package_qa_add_message(messages, "host-user-contaminated", "%s: %s is owned by uid %d, which is the same as the user running bitbake. This may be due to host contamination" % (pn, package_qa_clean_path(path, d, name), check_uid))<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return False<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;check_gid = int(d.getVar('HOST_USER_GID'))<br>
-&nbsp; &nbsp; &nbsp; &nbsp; if stat.st_gid == check_gid:<br>
+&nbsp; &nbsp; &nbsp; &nbsp; if check_gid != 0 and stat.st_gid == check_gid:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;package_qa_add_message(messages, "host-user-contaminated", "%s: %s is owned by gid %d, which is the same as the user running bitbake. This may be due to host contamination" % (pn, package_qa_clean_path(path, d, name), check_gid))<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return False<br>
&nbsp; &nbsp; &nbsp;return True<br>
diff --git a/meta/classes/sanity.bbclass b/meta/classes/sanity.bbclass<br>
index 63ab6cf3df..a1eba62589 100644<br>
--- a/meta/classes/sanity.bbclass<br>
+++ b/meta/classes/sanity.bbclass<br>
@@ -742,7 +742,15 @@ def check_sanity_everybuild(status, d):<br>
&nbsp; &nbsp; &nbsp;# it makes sense to always run them.<br>
<br>
&nbsp; &nbsp; &nbsp;if 0 == os.getuid():<br>
-&nbsp; &nbsp; &nbsp; &nbsp; raise_sanity_error("Do not use Bitbake as root.", d)<br>
+&nbsp; &nbsp; &nbsp; &nbsp; userns = False<br>
+&nbsp; &nbsp; &nbsp; &nbsp; with open("/proc/self/uid_map") as f:<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for line in f:<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fields = line.split()<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if fields[0] == "0" and fields[1] != "0":<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userns = True<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break<br>
+&nbsp; &nbsp; &nbsp; &nbsp; if not userns:<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise_sanity_error("Do not use Bitbake as root.", d)<br>
<br>
&nbsp; &nbsp; &nbsp;# Check the Python version, we now have a minimum of Python 3.4<br>
&nbsp; &nbsp; &nbsp;import sys<br>
diff --git a/meta/recipes-core/coreutils/<a href="http://coreutils_8.31.bb" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">coreutils_8.31.bb</a> b/meta/recipes-core/coreutils/<a href="http://coreutils_8.31.bb" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">coreutils_8.31.bb</a><br>
index 57b2c1bdba..2f8009331a 100644<br>
--- a/meta/recipes-core/coreutils/<a href="http://coreutils_8.31.bb" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">coreutils_8.31.bb</a><br>
+++ b/meta/recipes-core/coreutils/<a href="http://coreutils_8.31.bb" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">coreutils_8.31.bb</a><br>
@@ -28,6 +28,7 @@ SRC_URI[sha256sum] = "ff7a9c918edce6b4f4b2725e3f9b37b0c4d193531cac49a48b56c4d0d3<br>
&nbsp;EXTRA_OECONF_class-native = "--without-gmp"<br>
&nbsp;EXTRA_OECONF_class-target = "--enable-install-program=arch,hostname --libexecdir=${libdir}"<br>
&nbsp;EXTRA_OECONF_class-nativesdk = "--enable-install-program=arch,hostname"<br>
+EXTRA_OECONF_append = " FORCE_UNSAFE_CONFIGURE=1"<br>
<br>
&nbsp;# acl and xattr are not default features<br>
&nbsp;#<br>
diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile<br>
new file mode 100644<br>
index 0000000000..4a143d6aa1<br>
--- /dev/null<br>
+++ b/scripts/docker/Dockerfile<br>
@@ -0,0 +1,19 @@<br>
+FROM ubuntu:18.04<br>
+<br>
+RUN DEBIAN_FRONTEND=noninteractive apt-get -y update --fix-missing<br>
+<br>
+# Configure locale for Python3<br>
+RUN DEBIAN_FRONTEND=noninteractive apt-get -y install locales ; \<br>
+&nbsp; &nbsp; DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales &amp;&amp; \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; locale-gen en_US.UTF-8 &amp;&amp; \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8<br>
+<br>
+ENV LANG=en_US.UTF-8<br>
+ENV LC_ALL=en_US.UTF-8<br>
+<br>
+# Install Yocto native dependencies<br>
+RUN DEBIAN_FRONTEND=noninteractive apt-get -y install \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; wget git-core diffstat unzip texinfo gcc-multilib \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \<br>
+&nbsp; &nbsp; &nbsp; &nbsp; pylint3 xterm gawk<br>
diff --git a/scripts/docker/oe-rootless-docker b/scripts/docker/oe-rootless-docker<br>
new file mode 100755<br>
index 0000000000..1efcc82280<br>
--- /dev/null<br>
+++ b/scripts/docker/oe-rootless-docker<br>
@@ -0,0 +1,24 @@<br>
+#!/bin/sh<br>
+<br>
+usage () {<!-- --><br>
+CMD=$(basename $0)<br>
+cat &lt;&lt;EOF<br>
+Usage: $CMD [docker-build|docker-run]<br>
+&nbsp; docker-build&nbsp; Build Dockerfile locally<br>
+&nbsp; docker-run&nbsp; &nbsp; Run rootless docker image suitable for image compilation<br>
+EOF<br>
+}<br>
+<br>
+if ! [ -n "${DOCKER_HOST}" -a "$(stat -c '%U' "${DOCKER_HOST#*://}" 2&gt;/dev/null)" = "$(whoami)" ] ; then<br>
+&nbsp; &nbsp; &nbsp; &nbsp;echo "Install rootless docker according to the <a href="https://docs.docker.com/engine/security/rootless/" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">https://docs.docker.com/engine/security/rootless/</a>"<br>
+&nbsp; &nbsp; &nbsp; &nbsp;exit 1<br>
+fi<br>
+<br>
+if [ "$1" = "docker-build" ]; then<br>
+&nbsp; &nbsp; &nbsp; &nbsp;docker build -t poky-docker $(dirname $(readlink -f $0))<br>
+elif [ "$1" = "docker-run" ]; then<br>
+&nbsp; &nbsp; &nbsp; &nbsp;docker run -ti -v ${HOME}:${HOME} -v ${PWD}:${PWD} --workdir ${PWD} -e HOME poky-docker<br>
+else<br>
+&nbsp; &nbsp; &nbsp; &nbsp;usage<br>
+&nbsp; &nbsp; &nbsp; &nbsp;exit 0<br>
+fi<br>
-- <br>
2.17.1<br>
<br>
-- <br>
_______________________________________________<br>
Openembedded-core mailing list<br>
<a href="mailto:Openembedded-core@lists.openembedded.org" rel="nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">Openembedded-core@lists.openembedded.org</a><br>
<a href="http://lists.openembedded.org/mailman/listinfo/openembedded-core" rel="noreferrer nofollow noopener noreferrer nofollow noopener noreferrer" target="_blank">http://lists.openembedded.org/mailman/listinfo/openembedded-core</a><br>
</blockquote></div></blockquote></div></div><br></div></div></body></html>