Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libteam for openSUSE:Factory checked in at 2021-11-09 23:53:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libteam (Old) and /work/SRC/openSUSE:Factory/.libteam.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libteam" Tue Nov 9 23:53:49 2021 rev:22 rq:929785 version:1.31 Changes: -------- --- /work/SRC/openSUSE:Factory/libteam/libteam.changes 2021-10-19 23:03:35.421266491 +0200 +++ /work/SRC/openSUSE:Factory/.libteam.new.1890/libteam.changes 2021-11-09 23:54:00.979934452 +0100 @@ -1,0 +2,7 @@ +Fri Nov 5 17:14:17 UTC 2021 - Otto Hollmann <otto.hollm...@suse.com> + +- teamd: better handle failures to chown(TEAMD_RUN_DIR) during + teamd_drop_privileges() (bsc#1185424) + [+ better_handle_failures_to_chown.patch] + +------------------------------------------------------------------- New: ---- better_handle_failures_to_chown.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libteam.spec ++++++ --- /var/tmp/diff_new_pack.wEQAUH/_old 2021-11-09 23:54:01.575934757 +0100 +++ /var/tmp/diff_new_pack.wEQAUH/_new 2021-11-09 23:54:01.579934760 +0100 @@ -17,6 +17,8 @@ %bcond_without python2 +# _tmpfilesdir is not defined in systemd macros up to openSUSE 13.2 +%{!?_tmpfilesdir: %global _tmpfilesdir %{_libexecdir}/tmpfiles.d } Name: libteam Version: 1.31 Release: 0 @@ -32,6 +34,7 @@ Patch3: ignore_ebusy_for_team_hwaddr_set.patch Patch4: 0001-allow-send_interface-dbus.patch Patch5: harden_teamd@.service.patch +Patch6: better_handle_failures_to_chown.patch BuildRequires: doxygen BuildRequires: libcap-devel BuildRequires: libtool @@ -145,6 +148,14 @@ popd %endif +# Install /usr/lib/tmpfiles.d/libteam.conf +mkdir -p %{buildroot}%{_tmpfilesdir} +cat > %{buildroot}%{_tmpfilesdir}/libteam.conf <<EOF +# See tmpfiles.d(5) for details +# Type(d=directory) Path Mode UID GID Age(until delete when cleaning) +d %teamd_daemon_directory 0755 %teamd_user %teamd_group - +EOF + rm -f "$b/%_libdir"/*.la %if 0%{?_unitdir:1} mkdir -p "$b/%_unitdir" @@ -168,6 +179,8 @@ %endif %post tools +# Use %%tmpfiles_create when 13.2 is oldest in support scope +/usr/bin/systemd-tmpfiles --create %{_tmpfilesdir}/libteam.conf || : # reload dbus to apply new teamd's policy systemctl reload dbus.service 2>/dev/null || : %if 0%{?_unitdir:1} @@ -217,6 +230,7 @@ %if 0%{?_unitdir:1} %_unitdir %endif +%{_tmpfilesdir}/libteam.conf %if %{with python2} %files -n python-libteam ++++++ better_handle_failures_to_chown.patch ++++++ >From 44ed6a1724bac01cd1c1dd25defb62237df5f379 Mon Sep 17 00:00:00 2001 From: Thomas Haller <thal...@redhat.com> Date: Fri, 21 May 2021 18:32:07 +0200 Subject: [PATCH 1/1] teamd: better handle failures to chown(TEAMD_RUN_DIR) during teamd_drop_privileges() NetworkManager is exec-ing teamd while running without CAP_CHOWN. When teamd is configured to drop privileges, then it will call chown while still running as root user. But the command will fail because of lack of CAP_CHOWN. Note that chown() succeeds if the calling process has CAP_CHOWN or if the file already is owned by the calling user/group (whereas, changing the group will still work, if the user is a member of that group). The directory might have already been prepared with the right user/group. Let's handle that. If the first chown() as root succeeds, we are good. If it fails, we will retry after changing the user id. If the directory already has the right/compatible user, this command will succeeds too and teamd can proceed. See-also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/722 Signed-off-by: Thomas Haller <thal...@redhat.com> --- teamd/teamd.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/teamd/teamd.c b/teamd/teamd.c index b310140570c5..3ef3d6cf09f6 100644 --- a/teamd/teamd.c +++ b/teamd/teamd.c @@ -1714,6 +1714,7 @@ static int teamd_drop_privileges() cap_t my_caps; struct passwd *pw = NULL; struct group *grpent = NULL; + int chown_succeeded; if ((pw = getpwnam(TEAMD_USER)) == NULL) { fprintf(stderr, "Error reading user %s entry (%m)\n", TEAMD_USER); @@ -1734,11 +1735,12 @@ static int teamd_drop_privileges() goto error; } - if (chown(TEAMD_RUN_DIR, pw->pw_uid, pw->pw_gid) < 0) { - fprintf(stderr, "Unable to change ownership of %s to %s/%s (%m)\n", - TEAMD_RUN_DIR, TEAMD_USER, TEAMD_GROUP); - goto error; - } + /* Try to change owner while still being root. We might not have + * capabilities, so this might fail. At this point, we accept that, + * because the directory might have been prepared with a suitable owner + * already. But on failure, we will retry as the new user below. + */ + chown_succeeded = (chown(TEAMD_RUN_DIR, pw->pw_uid, pw->pw_gid) == 0); if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) goto error; @@ -1758,6 +1760,12 @@ static int teamd_drop_privileges() goto error; } + if (!chown_succeeded && chown(TEAMD_RUN_DIR, pw->pw_uid, pw->pw_gid) < 0) { + fprintf(stderr, "Unable to change ownership of %s to %s/%s (%m)\n", + TEAMD_RUN_DIR, TEAMD_USER, TEAMD_GROUP); + goto error; + } + if ((my_caps = cap_init()) == NULL) goto error; if (cap_set_flag(my_caps, CAP_EFFECTIVE, ARRAY_SIZE(cv), cv, CAP_SET) < 0) -- 2.31.1