Openembedded Core Discussions
 help / color / mirror / Atom feed
From: Patrick Ohly <patrick.ohly@intel.com>
To: Adrian Freihofer <adrian.freihofer@neratec.com>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: runqemu + dhcp server
Date: Tue, 07 Apr 2015 17:57:43 +0200	[thread overview]
Message-ID: <1428422263.23267.14.camel@intel.com> (raw)
In-Reply-To: <4426580.xeKXhTzLUy@chl500346>

[-- Attachment #1: Type: text/plain, Size: 2519 bytes --]

On Mon, 2014-11-10 at 22:57 +0100, Adrian Freihofer wrote:
> Did you ever run the automated image tests? If I remember correctly
> the image tests are somehow related to the current implementation of
> the network configuration. At least the tests require a hostname
> starting with "qemu" and probably they run from NFS rootfs.

After investigating this, I found that testimage.bbclass itself does not
support NFS rootfs. It is only runqemu which (in combination with
runqemu-extract-sdk) can run in NFS mode. That mode works in combination
with a running dhcpd, I tested that.

> Would be nice, if you get the DHCP based network configuration
> fulfilling these requirements. An alternative approach is implemented
> in systemd networkd. I guess it does not touch interfaces which are
> already configured e.g. by kernel boot parameters. This could be done
> in connman as well. It would allow you to run the productive image in
> qemu.

I'm starting to agree here, for two reasons: one is that I am working
less with genuine Tizen these days (so the need for having a DHCP server
is less urgent), the other is that I noticed a problem with usermode
dhcp via capabilities.

The problem is that setting capabilities disables the ORIGIN components
in RPATH (due to security concerns, see http://blog.tinola.com/?e=7),
causing the binary to pick up libcrypto from the host, which happens
to work but is not guaranteed. On OpenSUSE it leads to a warning
about "libcrypto.so.1.0.0: no version information available".

I tried restoring absolute RPATH in the dhcpd binary, but that failed
because apparently chrpath can only shorten the search path: once
chrpath.bbclass has replaced the longer path with the one using ORIGIN,
that cannot be undone.

So at this point I don't have a good solution. The patch happens to
work, but clearly is not ready for inclusion and might never be. I'm
attaching updated patches anyway, because some more work was needed to
get bind compiled natively again after the "prevent accidental usage of
config scripts patch".

Perhaps dhcpd should get brought up together with tap0 in runqemu-ifup
and kept running, instead of starting it on demand in runqemu-internal?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



[-- Attachment #2: 0001-recipes-connectivity-enable-native-bind-and-dhcp.patch --]
[-- Type: text/x-patch, Size: 3825 bytes --]

From f20aa3fd411486d2df6ecbfc5430f03c79bf6989 Mon Sep 17 00:00:00 2001
From: Patrick Ohly <patrick.ohly@intel.com>
Date: Mon, 3 Nov 2014 17:37:20 +0100
Subject: [PATCH 1/2] recipes-connectivity: enable native bind and dhcp

This depends on bind-native. It is needed for running a user-space
dhcpd for qemu guests. The bind .pc patch had to be updated such
that it prefers the .pc file, because during native compilation
the xml2-config script is found but intentionally not usable
to catch accidental usages of it. This worked for target compilation
because there the script gets moved into a crossscripts directory
such that it was not found.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
---
 ...d-crosscripts-search-path-for-xml2-config.patch | 31 ++++++++++++----------
 meta/recipes-connectivity/bind/bind_9.9.5.bb       |  1 +
 meta/recipes-connectivity/dhcp/dhcp.inc            |  2 ++
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/meta/recipes-connectivity/bind/bind/bind-add-crosscripts-search-path-for-xml2-config.patch b/meta/recipes-connectivity/bind/bind/bind-add-crosscripts-search-path-for-xml2-config.patch
index 4f1a3f8..6171c1f 100644
--- a/meta/recipes-connectivity/bind/bind/bind-add-crosscripts-search-path-for-xml2-config.patch
+++ b/meta/recipes-connectivity/bind/bind/bind-add-crosscripts-search-path-for-xml2-config.patch
@@ -8,28 +8,31 @@ bin folder is not copied to sysroot so the test was failing. Added another
 condition to test libxml-2.0.pc which is present in lib folder. Used pkg-config
 to get libs and cflags information.
 
+[Patrick Ohly: swaped checks to look for .pc file first. xml2-config, if present,
+is intentionally returning garbage to catch recipes which continue using it.]
+
 Upstream-Status: Inappropriate [ openembedded specific ]
 
 Signed-off-by: Joe MacDonald <joe_macdonald@mentor.com>
 Signed-off-by: Noor Ahsan <noor_ahsan@mentor.com>
+Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
 ---
  configure.in | 3 +++
  1 file changed, 3 insertions(+)
 
-diff --git a/configure.in b/configure.in
-index 3d04f4c..6032f67 100644
---- a/configure.in
-+++ b/configure.in
-@@ -1433,6 +1433,9 @@ case "$use_libxml2" in
- 		if test -f "$use_libxml2/bin/xml2-config" ; then
- 			libxml2_libs=`$use_libxml2/bin/xml2-config --libs`
- 			libxml2_cflags=`$use_libxml2/bin/xml2-config --cflags`
-+		elif test -f "$use_libxml2/lib/pkgconfig/libxml-2.0.pc" ; then
+Index: bind-9.9.5/configure.in
+===================================================================
+--- bind-9.9.5.orig/configure.in
++++ bind-9.9.5/configure.in
+@@ -1430,7 +1430,10 @@ case "$use_libxml2" in
+ 		esac
+ 		;;
+ 	*)
+-		if test -f "$use_libxml2/bin/xml2-config" ; then
++		if test -f "$use_libxml2/lib/pkgconfig/libxml-2.0.pc" ; then
 +			libxml2_libs=`pkg-config libxml-2.0 --libs`
 +			libxml2_cflags=`pkg-config libxml-2.0 --cflags`
++		elif test -f "$use_libxml2/bin/xml2-config" ; then
+ 			libxml2_libs=`$use_libxml2/bin/xml2-config --libs`
+ 			libxml2_cflags=`$use_libxml2/bin/xml2-config --cflags`
  		fi
- 		;;
- esac
--- 
-1.9.1
-
diff --git a/meta/recipes-connectivity/bind/bind_9.9.5.bb b/meta/recipes-connectivity/bind/bind_9.9.5.bb
index e34cded..6bbc2be 100644
--- a/meta/recipes-connectivity/bind/bind_9.9.5.bb
+++ b/meta/recipes-connectivity/bind/bind_9.9.5.bb
@@ -103,3 +103,4 @@ CONFFILES_${PN} = " \
 	${sysconfdir}/bind/db.root \
 	"
 
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-connectivity/dhcp/dhcp.inc b/meta/recipes-connectivity/dhcp/dhcp.inc
index 6ced775..b4b4384 100644
--- a/meta/recipes-connectivity/dhcp/dhcp.inc
+++ b/meta/recipes-connectivity/dhcp/dhcp.inc
@@ -109,3 +109,5 @@ pkg_postrm_dhcp-client() {
         echo "Not removing ${localstatedir}/lib/dhcp as it is non-empty."
     fi
 }
+
+BBCLASSEXTEND = "native"
-- 
1.8.4.5


[-- Attachment #3: 0002-runqemu-automatically-run-DHCP-server.patch --]
[-- Type: text/x-patch, Size: 6400 bytes --]

From 70b8a99bfbfb8c586e36545afd47aa3990d8f547 Mon Sep 17 00:00:00 2001
From: Patrick Ohly <patrick.ohly@intel.com>
Date: Mon, 3 Nov 2014 17:42:19 +0100
Subject: [PATCH 2/2] runqemu: automatically run DHCP server

Some images are not able to configure their Ethernet based on the
"ip" kernel parameter, for example Tizen. Instead of having to
modify images, it is easier to provide what these images expect
and have a DHCP server running on the host.

At the moment, the modified scripts expect that "dhcp-native" was
built for the host. runqemu-ifup sets capabilities such that the dhcpd
can be run as normal user with just minimal privileges and then
runqemu-internal takes care of bringing the daemon up and taking it
down again. All dhcpd files are stored together with the tap lock file
under /tmp. dhcpd output goes to stdout.

This approach needs further work: due to the additional capabilities,
the ORIGIN RPATH gets ignored, causing dhcpd to run with the host's
libcrypto. See comment in runqemu-ifup for details.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
---
 scripts/runqemu-ifup     | 36 +++++++++++++++++++++++++++
 scripts/runqemu-internal | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/scripts/runqemu-ifup b/scripts/runqemu-ifup
index b5a3db9..f581334 100755
--- a/scripts/runqemu-ifup
+++ b/scripts/runqemu-ifup
@@ -57,6 +57,14 @@ if [ ! -x "$TUNCTL" ]; then
 	exit 1
 fi
 
+# TODO: make dhcpd optional?
+DHCPD=$NATIVE_SYSROOT_DIR/usr/sbin/dhcpd
+if [ ! -x "$DHCPD" ]; then
+	# TODO (?): integrate into qemu-helper-native
+	echo "Error: Unable to find dhcpd binary in '$NATIVE_SYSROOT_DIR/usr/sbin', please bitbake dhcp-native"
+	exit 1
+fi
+
 TAP=`$TUNCTL -b $GROUP 2>&1`
 STATUS=$?
 if [ $STATUS -ne 0 ]; then
@@ -89,6 +97,15 @@ if [ ! -x "$IPTABLES" ]; then
 	exit 1
 fi
 
+SETCAP=`which setcap 2> /dev/null`
+if [ "x$SETCAP" = "x" ]; then
+	SETCAP=/sbin/setcap
+fi
+if [ ! -x "$SETCAP" ]; then
+	echo "$SETCAP cannot be executed"
+	exit 1
+fi
+
 n=$[ (`echo $TAP | sed 's/tap//'` * 2) + 1 ]
 $IFCONFIG addr add 192.168.7.$n/32 broadcast 192.168.7.255 dev $TAP
 $IFCONFIG link set dev $TAP up
@@ -103,4 +120,23 @@ echo 1 > /proc/sys/net/ipv4/ip_forward
 echo 1 > /proc/sys/net/ipv4/conf/$TAP/proxy_arp
 $IPTABLES -P FORWARD ACCEPT
 
+# Allow running dhcpd as normal user: let the process obtain
+# the necessary capabilities from the file. This causes ld.so
+# to ignore the relative $ORIGIN RPATH, so we have to add
+# back absolute paths.
+#
+# Setting capabilities disables the ORIGIN components in RPATH
+# (due to security concerns, see http://blog.tinola.com/?e=7), causing
+# the binary to pick up libcrypto from the host, which happens
+# to work but is not guaranteed. On OpenSUSE it leads to a warning
+# about "libcrypto.so.1.0.0: no version information available".
+#
+# TODO: somehow install a copy of dhcpd with absolute paths
+#
+# Note that adding the absolute paths back here does not work because
+# apparently chrpath can only shorten the search path: once
+# chrpath.bbclass has replaced the longer path with the one using
+# ORIGIN, that cannot be undone.
+$SETCAP cap_net_bind_service,cap_net_raw+ep $DHCPD
+
 echo $TAP
diff --git a/scripts/runqemu-internal b/scripts/runqemu-internal
index 2db5566..fc1a5e6 100755
--- a/scripts/runqemu-internal
+++ b/scripts/runqemu-internal
@@ -111,6 +111,24 @@ if [ -z "$QEMUIFDOWN" -o ! -x "$QEMUIFDOWN" ]; then
        exit 1
 fi
 
+GETCAP=`PATH=$PATH:/sbin:/usr/sbin which getcap 2> /dev/null`
+if [ "x$GETCAP" = "x" ]; then
+	GETCAP=/sbin/getcap
+fi
+if [ ! -x "$GETCAP" ]; then
+	echo "$GETCAP cannot be executed"
+	exit 1
+fi
+
+SETCAP=`PATH=$PATH:/sbin:/usr/sbin which setcap 2> /dev/null`
+if [ "x$SETCAP" = "x" ]; then
+	SETCAP=/sbin/setcap
+fi
+if [ ! -x "$SETCAP" ]; then
+	echo "$SETCAP cannot be executed"
+	exit 1
+fi
+
 NFSRUNNING="false"
 
 #capture original stty values
@@ -179,6 +197,17 @@ else
                exit 1
         fi
 
+        DHCPD_CAPABILITIES="cap_net_bind_service,cap_net_raw+ep"
+        DHCPD=$OECORE_NATIVE_SYSROOT/usr/sbin/dhcpd
+        if [ ! -x "$DHCPD" ]; then
+            echo "Error: Unable to find dhcpd binary in '$NATIVE_SYSROOT_DIR/usr/sbin', please bitbake qemu-helper-native"
+            exit 1
+        fi
+        if [ "$($GETCAP "$DHCPD" | sed -e 's/.* = //')" != $DHCPD_CAPABILITIES ]; then
+	    echo "Error: $DHCPD does not have the required capabilities to run as non-root. Run sudo $SETCAP $DHCPD_CAPABILITIES $DHCPD"
+	    exit 1
+        fi
+
         POSSIBLE=`$IFCONFIG link | grep 'tap' | awk '{print $2}' | sed s/://`
         TAP=""
         LOCKFILE=""
@@ -229,6 +258,10 @@ else
         fi
 
         cleanup() {
+            # Ensure that we don't kill an unrelated process.
+            if [ ! -e "$DHCPPID" ] && [ -s $DHCPPID ] && ps $(cat $DHCPPID) | grep -q dhcpd; then
+                kill $(cat $DHCPPID)
+            fi
             if [ ! -e "$NOSUDO_FLAG" -a "$USE_PRECONF_TAP" = "no" ]; then
                 # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded
                 # but inactive. This looks scary but is harmless
@@ -256,6 +289,38 @@ else
         n1=$(($n0 * 2 + 1))
         n2=$(($n1 + 1))
 
+        DHCPDIR=$LOCKFILE.dhcp
+        rm -rf $DHCPDIR
+        mkdir $DHCPDIR
+        DHCPCONF=$DHCPDIR/dhcpd.conf
+        DHCPLEASE=$DHCPDIR/dhcpd.leases
+        DHCPPID=$DHCPDIR/dhcpd.pid
+        cat >$DHCPCONF <<EOF
+option domain-name "localdomain";
+authoritative;
+
+# Basically forever...
+default-lease-time 60000;
+max-lease-time 60000;
+
+subnet 192.168.7.0 netmask 255.255.255.0 {
+  range 192.168.7.$n2 192.168.7.$n2;
+  option routers 192.168.7.$n1;
+}
+EOF
+        touch $DHCPLEASE
+        echo $DHCPD -d -cf $DHCPCONF -lf $DHCPLEASE -pf $DHCPPID $TAP
+        # TODO: where should output go?
+        $DHCPD -d -cf $DHCPCONF -lf $DHCPLEASE -pf $DHCPPID $TAP &
+        pid=$!
+        while [ ! -s $DHCPPID ]; do
+            sleep 1
+            if ! ps $pid | grep -q dhcpd; then
+                echo "$DHCPD terminated unexpectedly."
+                return 1
+            fi
+        done
+
         KERNEL_NETWORK_CMD="ip=192.168.7.$n2::192.168.7.$n1:255.255.255.0"
         QEMU_TAP_CMD="-net tap,vlan=0,ifname=$TAP,script=no,downscript=no"
         if [ "$KVM_ACTIVE" = "yes" ]; then
-- 
1.8.4.5


  parent reply	other threads:[~2015-04-07 15:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-04  8:09 runqemu + dhcp server Patrick Ohly
2014-11-05 10:29 ` Adrian Freihofer
2014-11-07 10:12   ` Patrick Ohly
2014-11-10 21:57     ` Adrian Freihofer
2015-02-17 10:34       ` Patrick Ohly
2015-02-17 16:24         ` Adrian Freihofer
2015-04-07 15:57       ` Patrick Ohly [this message]
2014-11-05 16:29 ` Burton, Ross
2014-11-11 15:58   ` Patrick Ohly

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1428422263.23267.14.camel@intel.com \
    --to=patrick.ohly@intel.com \
    --cc=adrian.freihofer@neratec.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox