From 2037f1f93c18279bebbb6ed04d640d816d1d1cb1 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 27 Jul 2016 17:01:54 +0200 Subject: [PATCH] ostro: enable static user and group IDs It turned out that swupd currently does not handle updates where user or group IDs change. Avoiding such changes makes sense also without that problem, but has implications for developers using Ostro OS: if they change anything that adds new users or groups, they must define a static mapping or disable the feature. Right now instructions are only given in the ostro.conf file; more user-visible documentation should be added later. Our custom systemd sysusers support class gets extended to also support static IDs. That's a feature also missing in the corresponding OE-core code, so we can't switch to that. Quite the opposite, we now have to make sure that it doesn't run before our own improved code. The ostro-group and ostro-passwd files were copied from the ostro-image-swupd image, build #486. They were then sorted alphabetically (order was fairly random in the image), uids were changed to match the corresponding gids, and some entries where added which seem to be used only during the build (dbus, dbus-x11). Fixes: IOTOS-1712 Signed-off-by: Patrick Ohly --- meta-ostro/classes/systemd-sysusers.bbclass | 44 +++++++++++++++++++++ meta-ostro/conf/distro/include/ostro-group | 34 ++++++++++++++++ meta-ostro/conf/distro/include/ostro-passwd | 13 ++++++ meta-ostro/conf/distro/ostro.conf | 44 +++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 meta-ostro/conf/distro/include/ostro-group create mode 100644 meta-ostro/conf/distro/include/ostro-passwd diff --git a/meta-ostro/classes/systemd-sysusers.bbclass b/meta-ostro/classes/systemd-sysusers.bbclass index 5da9a1e..c414cca 100644 --- a/meta-ostro/classes/systemd-sysusers.bbclass +++ b/meta-ostro/classes/systemd-sysusers.bbclass @@ -1,5 +1,35 @@ inherit useradd_base +# Generates shell code for systemd_sysusers_create() which looks up +# $name in the gid or uid tables to determine a new value for $id. +# Very simplistic, better solution is expected to come from OE-core +# (see below). +# Example output: +# case $name in foo) id=10;; bar) id=20;; *) bbfatal "...";; esac +def systemd_sysusers_lookup_staticid(tables_variable, d): + if d.getVar('USERADDEXTENSION', True) != 'useradd-staticids': + return '' + result = [ 'case $name in' ] + bbpath = d.getVar('BBPATH', True) + tables = d.getVar(tables_variable, True) + for conf_file in tables.split(): + path = bb.utils.which(bbpath, conf_file) + with open(path) as f: + for line in f: + if not line.startswith('#'): + columns = line.strip().split(':') + if len(columns) >= 3: + # Same format for passwd and groups. Only these two + # entries are supported for systemd sysusers, the + # rest is ignored. + name = columns[0] + id = columns[2] + result.append('%s) id=%s;;' % (name, id)) + if d.getVar('USERADD_ERROR_DYNAMIC', True) in ('1', 'error'): + result.append('*) bbfatal "systemd sysuser $name of type $type in $conf has no static ID. Search for ' + tables_variable + ' in ostro.conf for further information.";;') + result.append('esac') + return ' '.join(result) + systemd_sysusers_create () { set -x opts="--system --root ${IMAGE_ROOTFS}" @@ -10,6 +40,10 @@ systemd_sysusers_create () { g) if [ "$id" = "-" ]; then gid="" + ${@systemd_sysusers_lookup_staticid('USERADD_GID_TABLES', d)} + if [ "$id" != "-" ]; then + gid="--gid $id" + fi else gid="--gid $id" fi @@ -18,6 +52,10 @@ systemd_sysusers_create () { u) if [ "$id" = "-" ]; then uid="" + ${@systemd_sysusers_lookup_staticid('USERADD_UID_TABLES', d)} + if [ "$id" != "-" ]; then + uid="--uid $id" + fi else uid="--uid $id" fi @@ -37,3 +75,9 @@ systemd_sysusers_create () { } ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd_sysusers_create;', '', d)}" + +# The code above was written before some similar code was made +# available in OE-core. However, that code is still not suitable +# (https://bugzilla.yoctoproject.org/show_bug.cgi?id=9789) and thus we +# have to use our own version. +ROOTFS_POSTPROCESS_COMMAND_remove = "systemd_create_users" diff --git a/meta-ostro/conf/distro/include/ostro-group b/meta-ostro/conf/distro/include/ostro-group new file mode 100644 index 0000000..9ae6813 --- /dev/null +++ b/meta-ostro/conf/distro/include/ostro-group @@ -0,0 +1,34 @@ +adm:x:990: +appfwtest-commonapp:x:1004: +audio:x:986: +cdrom:x:985: +dbus:1501 +dbus-x11:1500 +dialout:x:984: +disk:x:983: +evil-bad-groups:x:1003: +foodine-pythontest:x:1002: +input:x:982: +iodine-nodetest:x:1001: +kmem:x:988: +lock:x:997: +lp:x:981: +messagebus:x:998: +netdev:x:999: +nobody:x:65534: +nogroup:x:65533: +restful:x:991: +rfkill:x:50: +root:x:0: +sshd:x:992: +systemd-bus-proxy:x:993: +systemd-journal:x:996: +systemd-network:x:994: +systemd-timesync:x:995: +tape:x:980: +tty:x:5: +users:x:978: +utmp:x:987: +video:x:979: +wheel:x:989: +yoyodine-nativetest:x:1000: diff --git a/meta-ostro/conf/distro/include/ostro-passwd b/meta-ostro/conf/distro/include/ostro-passwd new file mode 100644 index 0000000..7d91cac --- /dev/null +++ b/meta-ostro/conf/distro/include/ostro-passwd @@ -0,0 +1,13 @@ +appfwtest-commonapp:x:1004:1004::/home/appfwtest-commonapp:/sbin/nologin +evil-bad-groups:x:1003:1003::/home/evil-bad-groups:/sbin/nologin +foodine-pythontest:x:1002:1002::/home/foodine-pythontest:/sbin/nologin +iodine-nodetest:x:1001:1001::/home/iodine-nodetest:/sbin/nologin +messagebus:x:998:998::/var/lib/dbus:/bin/false +nobody:x:65534:65534:nobody:/nonexistent:/bin/sh +restful:x:991:991::/var/lib/empty:/bin/false +root:x:0:0:root:/home/root:/bin/sh +sshd:x:992:992::/var/run/sshd:/bin/false +systemd-bus-proxy:x:993:993::/:/bin/nologin +systemd-network:x:994:994::/:/bin/nologin +systemd-timesync:x:995:995::/:/bin/nologin +yoyodine-nativetest:x:1000:1000::/home/yoyodine-nativetest:/sbin/nologin diff --git a/meta-ostro/conf/distro/ostro.conf b/meta-ostro/conf/distro/ostro.conf index 1f36281..87e364b 100644 --- a/meta-ostro/conf/distro/ostro.conf +++ b/meta-ostro/conf/distro/ostro.conf @@ -164,6 +164,50 @@ ERROR_QA_append = " ${WARN_TO_ERROR_QA}" # Add some Ostro OS specific checks in addition to those provided by sanity.bbclass. INHERIT += "ostro-sanity" +# The swupd update mechanism currently does not cope with user or +# group IDs that change between builds +# (https://github.com/clearlinux/swupd-client/issues/101). Even if it +# did, changing IDs would make the update more complicated (larger +# delta, daemons need to be restarted, etc.), so it is better to +# ensure that IDs are static. +# +# Ostro OS uses the static uid and gid mechanism from OE-core for that +# (http://www.yoctoproject.org/docs/latest/mega-manual/mega-manual.html#ref-classes-useradd), +# with custom support for adding systemd sysusers in Ostro's +# systemd-sysusers.bbclass. The OE-core mechanism for that currently +# lacks support for static IDs and thus cannot be used yet +# (https://bugzilla.yoctoproject.org/show_bug.cgi?id=9789). +# +# Dynamically assigned IDs are detected and lead to an error during +# the build. For example, the dbus recipe creates a "messagebus" +# group. Not defining that group causes an error when parsing the +# recipe and makes it unusable, leading to the following errors +# during "bitbake dbus": +# ERROR: Nothing PROVIDES 'dbus' +# ERROR: dbus was skipped: Function failed: dbus - dbus: username messagebus does not have a static ID defined. +# +# When building images, the errors shows up as missing components +# which are required for the build, as in "bitbake ostro-image-noswupd": +# ERROR: Nothing RPROVIDES 'udev' (but /work/ostro-os/meta/recipes-core/packagegroups/packagegroup-core-boot.bb, /work/ostro-os/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb RDEPENDS on or otherwise requires it) +# ERROR: Required build target 'ostro-image-noswupd' has no buildable providers. +# +# The advantage of this mechanism is the decentralized assignment of +# IDs without modifying the OS or recipes. +# +# Developers who need to add new entries should add their own mapping +# file to USERADD_UID_TABLES and/or USERADD_GID_TABLES, either in a +# derived distro config or in their local.conf. Ostro OS reserves +# the value range < 2000. +# +# For experiments and builds not involving swupd it is also possible to +# disable the mechanism by modifying USERADD_ERROR_DYNAMIC: +# "warn" merely prints a warning, empty value silently allows dynamic +# ID allocation. +USERADDEXTENSION = "useradd-staticids" +USERADD_ERROR_DYNAMIC ??= "error" +USERADD_UID_TABLES += "conf/distro/include/ostro-passwd" +USERADD_GID_TABLES += "conf/distro/include/ostro-group" + # Only specific recipes are supported by the Ostro Project. Those # recipes are listed in the following file. #