diff --git a/better_handle_failures_to_chown.patch b/better_handle_failures_to_chown.patch new file mode 100644 index 0000000..ce1414b --- /dev/null +++ b/better_handle_failures_to_chown.patch @@ -0,0 +1,75 @@ +From 44ed6a1724bac01cd1c1dd25defb62237df5f379 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +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 +--- + 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 + diff --git a/libteam.changes b/libteam.changes index 38ec455..1ee7c40 100644 --- a/libteam.changes +++ b/libteam.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Fri Nov 5 17:14:17 UTC 2021 - Otto Hollmann + +- teamd: better handle failures to chown(TEAMD_RUN_DIR) during + teamd_drop_privileges() (bsc#1185424) + [+ better_handle_failures_to_chown.patch] + ------------------------------------------------------------------- Fri Oct 15 07:32:26 UTC 2021 - Johannes Segitz diff --git a/libteam.spec b/libteam.spec index c5434fc..6737756 100644 --- a/libteam.spec +++ b/libteam.spec @@ -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 @@ Patch2: start_teamd_from_usr_sbin.patch 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 @@ python ./setup.py install --root="$b" --prefix="%_prefix" popd %endif +# Install /usr/lib/tmpfiles.d/libteam.conf +mkdir -p %{buildroot}%{_tmpfilesdir} +cat > %{buildroot}%{_tmpfilesdir}/libteam.conf </dev/null || : %if 0%{?_unitdir:1} @@ -217,6 +230,7 @@ fi %if 0%{?_unitdir:1} %_unitdir %endif +%{_tmpfilesdir}/libteam.conf %if %{with python2} %files -n python-libteam