[arch-commits] Commit in cifs-utils/repos/extra-x86_64 (8 files)
Tobias Powalowski
tpowa at gemini.archlinux.org
Sat Apr 30 16:19:39 UTC 2022
Date: Saturday, April 30, 2022 @ 16:19:39
Author: tpowa
Revision: 444346
archrelease: copy trunk to extra-x86_64
Added:
cifs-utils/repos/extra-x86_64/PKGBUILD
(from rev 444345, cifs-utils/trunk/PKGBUILD)
cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch
(from rev 444345, cifs-utils/trunk/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch)
cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch
(from rev 444345, cifs-utils/trunk/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch)
cifs-utils/repos/extra-x86_64/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch
(from rev 444345, cifs-utils/trunk/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch)
Deleted:
cifs-utils/repos/extra-x86_64/PKGBUILD
cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch
cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch
cifs-utils/repos/extra-x86_64/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch
------------------------------------------------------------------+
PKGBUILD | 88
cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch | 202 +-
cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch | 116 -
cifs-utils-6.13_fix-regression-in-kerberos-mount.patch | 986 +++++-----
4 files changed, 696 insertions(+), 696 deletions(-)
Deleted: PKGBUILD
===================================================================
--- PKGBUILD 2022-04-30 16:19:28 UTC (rev 444345)
+++ PKGBUILD 2022-04-30 16:19:39 UTC (rev 444346)
@@ -1,44 +0,0 @@
-# Maintainer: Tobias Powalowski <tpowa at archlinux.org>
-pkgname=cifs-utils
-pkgver=6.14
-pkgrel=1
-pkgdesc="CIFS filesystem user-space tools"
-arch=(x86_64)
-url="https://wiki.samba.org/index.php/LinuxCIFS_utils"
-license=('GPL')
-depends=('libcap' 'keyutils' 'krb5' 'talloc' 'libwbclient' 'pam')
-makedepends=('python-docutils')
-source=("https://download.samba.org/pub/linux-cifs/$pkgname/$pkgname-$pkgver.tar.bz2"{,.asc})
-
-validpgpkeys=('C699981A31F338706C817650DF5BA9D30642D5A0') #cifs-utils Distribution Verification Key <cifs-utils at samba.org>
-sha256sums=('6609e8074b5421295ff012a31f02ccd9a058415c619c81362ebb788dbf0756b8'
- 'SKIP')
-
-prepare() {
- # Fix install to honor DESTDIR
- sed -e 's|cd \$(ROOTSBINDIR)|cd $(DESTDIR)$(ROOTSBINDIR)|g' -i $pkgname-$pkgver/Makefile.am
-}
-
-build() {
- cd "$srcdir/$pkgname-$pkgver"
- # systemd support is broken in mount.cifs
- # https://bugs.archlinux.org/task/30958
- autoreconf -i
- # https://www.spinics.net/lists/linux-cifs/msg21550.html
- # change back to libcap-ng depend when upstream is fixed
- ./configure --prefix=/usr --with-libcap=yes --sbindir=/usr/bin --disable-systemd
- make
-}
-
-package() {
- cd "$srcdir/$pkgname-$pkgver"
- make DESTDIR="$pkgdir" ROOTSBINDIR=/usr/bin install
- mkdir -p "$pkgdir"/etc/request-key.d
- install -m 644 contrib/request-key.d/cifs.idmap.conf "$pkgdir"/etc/request-key.d
- install -m 644 contrib/request-key.d/cifs.spnego.conf "$pkgdir"/etc/request-key.d
- # set mount.cifs uid, to enable none root mounting form fstab
- chmod +s "$pkgdir"/usr/bin/mount.cifs
- # fix idmap-plugin #42052
- mkdir -p "$pkgdir"/etc/cifs-utils
- ln -s /usr/lib/cifs-utils/idmapwb.so "${pkgdir}"/etc/cifs-utils/idmap-plugin
-}
Copied: cifs-utils/repos/extra-x86_64/PKGBUILD (from rev 444345, cifs-utils/trunk/PKGBUILD)
===================================================================
--- PKGBUILD (rev 0)
+++ PKGBUILD 2022-04-30 16:19:39 UTC (rev 444346)
@@ -0,0 +1,44 @@
+# Maintainer: Tobias Powalowski <tpowa at archlinux.org>
+pkgname=cifs-utils
+pkgver=6.15
+pkgrel=1
+pkgdesc="CIFS filesystem user-space tools"
+arch=(x86_64)
+url="https://wiki.samba.org/index.php/LinuxCIFS_utils"
+license=('GPL')
+depends=('libcap' 'keyutils' 'krb5' 'talloc' 'libwbclient' 'pam')
+makedepends=('python-docutils')
+source=("https://download.samba.org/pub/linux-cifs/$pkgname/$pkgname-$pkgver.tar.bz2"{,.asc})
+
+validpgpkeys=('C699981A31F338706C817650DF5BA9D30642D5A0') #cifs-utils Distribution Verification Key <cifs-utils at samba.org>
+sha256sums=('a7b6940e93250c1676a6fa66b6ead91b78cd43a5fee99cc462459c8b9cf1e6f4'
+ 'SKIP')
+
+prepare() {
+ # Fix install to honor DESTDIR
+ sed -e 's|cd \$(ROOTSBINDIR)|cd $(DESTDIR)$(ROOTSBINDIR)|g' -i $pkgname-$pkgver/Makefile.am
+}
+
+build() {
+ cd "$srcdir/$pkgname-$pkgver"
+ # systemd support is broken in mount.cifs
+ # https://bugs.archlinux.org/task/30958
+ autoreconf -i
+ # https://www.spinics.net/lists/linux-cifs/msg21550.html
+ # change back to libcap-ng depend when upstream is fixed
+ ./configure --prefix=/usr --with-libcap=yes --sbindir=/usr/bin --disable-systemd
+ make
+}
+
+package() {
+ cd "$srcdir/$pkgname-$pkgver"
+ make DESTDIR="$pkgdir" ROOTSBINDIR=/usr/bin install
+ mkdir -p "$pkgdir"/etc/request-key.d
+ install -m 644 contrib/request-key.d/cifs.idmap.conf "$pkgdir"/etc/request-key.d
+ install -m 644 contrib/request-key.d/cifs.spnego.conf "$pkgdir"/etc/request-key.d
+ # set mount.cifs uid, to enable none root mounting form fstab
+ chmod +s "$pkgdir"/usr/bin/mount.cifs
+ # fix idmap-plugin #42052
+ mkdir -p "$pkgdir"/etc/cifs-utils
+ ln -s /usr/lib/cifs-utils/idmapwb.so "${pkgdir}"/etc/cifs-utils/idmap-plugin
+}
Deleted: cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch
===================================================================
--- cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch 2022-04-30 16:19:28 UTC (rev 444345)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -1,101 +0,0 @@
-From f4e7c84467152624a288351321c8664dbf3364af Mon Sep 17 00:00:00 2001
-From: Jonas Witschel <diabonas at archlinux.org>
-Date: Sat, 21 Nov 2020 11:41:26 +0100
-Subject: [PATCH 1/2] mount.cifs: update the cap bounding set only when
- CAP_SETPCAP is given
-
-libcap-ng 0.8.1 tightened the error checking on capng_apply, returning an error
-of -4 when trying to update the capability bounding set without having the
-CAP_SETPCAP capability to be able to do so. Previous versions of libcap-ng
-silently skipped updating the bounding set and only updated the normal
-CAPNG_SELECT_CAPS capabilities instead.
-
-Check beforehand whether we have CAP_SETPCAP, in which case we can use
-CAPNG_SELECT_BOTH to update both the normal capabilities and the bounding set.
-Otherwise, we can at least update the normal capabilities, but refrain from
-trying to update the bounding set to avoid getting an error.
-
-Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
----
- mount.cifs.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/mount.cifs.c b/mount.cifs.c
-index 4feb397..88b8b69 100644
---- a/mount.cifs.c
-+++ b/mount.cifs.c
-@@ -338,6 +338,8 @@ static int set_password(struct parsed_mount_info *parsed_info, const char *src)
- static int
- drop_capabilities(int parent)
- {
-+ capng_select_t set = CAPNG_SELECT_CAPS;
-+
- capng_setpid(getpid());
- capng_clear(CAPNG_SELECT_BOTH);
- if (parent) {
-@@ -355,7 +357,10 @@ drop_capabilities(int parent)
- return EX_SYSERR;
- }
- }
-- if (capng_apply(CAPNG_SELECT_BOTH)) {
-+ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
-+ set = CAPNG_SELECT_BOTH;
-+ }
-+ if (capng_apply(set)) {
- fprintf(stderr, "Unable to apply new capability set.\n");
- return EX_SYSERR;
- }
---
-2.29.2
-
-
-From 64dfbafe7a0639a96d67f0b840b6e6498e1f68a9 Mon Sep 17 00:00:00 2001
-From: Jonas Witschel <diabonas at archlinux.org>
-Date: Sat, 21 Nov 2020 11:48:33 +0100
-Subject: [PATCH 2/2] cifs.upall: update the cap bounding set only when
- CAP_SETPCAP is given
-
-libcap-ng 0.8.1 tightened the error checking on capng_apply, returning an error
-of -4 when trying to update the capability bounding set without having the
-CAP_SETPCAP capability to be able to do so. Previous versions of libcap-ng
-silently skipped updating the bounding set and only updated the normal
-CAPNG_SELECT_CAPS capabilities instead.
-
-Check beforehand whether we have CAP_SETPCAP, in which case we can use
-CAPNG_SELECT_BOTH to update both the normal capabilities and the bounding set.
-Otherwise, we can at least update the normal capabilities, but refrain from
-trying to update the bounding set to avoid getting an error.
-
-Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
----
- cifs.upcall.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/cifs.upcall.c b/cifs.upcall.c
-index 1559434..af1a0b0 100644
---- a/cifs.upcall.c
-+++ b/cifs.upcall.c
-@@ -88,6 +88,8 @@ typedef enum _sectype {
- static int
- trim_capabilities(bool need_environ)
- {
-+ capng_select_t set = CAPNG_SELECT_CAPS;
-+
- capng_clear(CAPNG_SELECT_BOTH);
-
- /* SETUID and SETGID to change uid, gid, and grouplist */
-@@ -105,7 +107,10 @@ trim_capabilities(bool need_environ)
- return 1;
- }
-
-- if (capng_apply(CAPNG_SELECT_BOTH)) {
-+ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
-+ set = CAPNG_SELECT_BOTH;
-+ }
-+ if (capng_apply(set)) {
- syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
- return 1;
- }
---
-2.29.2
-
Copied: cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch (from rev 444345, cifs-utils/trunk/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch)
===================================================================
--- cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch (rev 0)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -0,0 +1,101 @@
+From f4e7c84467152624a288351321c8664dbf3364af Mon Sep 17 00:00:00 2001
+From: Jonas Witschel <diabonas at archlinux.org>
+Date: Sat, 21 Nov 2020 11:41:26 +0100
+Subject: [PATCH 1/2] mount.cifs: update the cap bounding set only when
+ CAP_SETPCAP is given
+
+libcap-ng 0.8.1 tightened the error checking on capng_apply, returning an error
+of -4 when trying to update the capability bounding set without having the
+CAP_SETPCAP capability to be able to do so. Previous versions of libcap-ng
+silently skipped updating the bounding set and only updated the normal
+CAPNG_SELECT_CAPS capabilities instead.
+
+Check beforehand whether we have CAP_SETPCAP, in which case we can use
+CAPNG_SELECT_BOTH to update both the normal capabilities and the bounding set.
+Otherwise, we can at least update the normal capabilities, but refrain from
+trying to update the bounding set to avoid getting an error.
+
+Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
+---
+ mount.cifs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/mount.cifs.c b/mount.cifs.c
+index 4feb397..88b8b69 100644
+--- a/mount.cifs.c
++++ b/mount.cifs.c
+@@ -338,6 +338,8 @@ static int set_password(struct parsed_mount_info *parsed_info, const char *src)
+ static int
+ drop_capabilities(int parent)
+ {
++ capng_select_t set = CAPNG_SELECT_CAPS;
++
+ capng_setpid(getpid());
+ capng_clear(CAPNG_SELECT_BOTH);
+ if (parent) {
+@@ -355,7 +357,10 @@ drop_capabilities(int parent)
+ return EX_SYSERR;
+ }
+ }
+- if (capng_apply(CAPNG_SELECT_BOTH)) {
++ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
++ set = CAPNG_SELECT_BOTH;
++ }
++ if (capng_apply(set)) {
+ fprintf(stderr, "Unable to apply new capability set.\n");
+ return EX_SYSERR;
+ }
+--
+2.29.2
+
+
+From 64dfbafe7a0639a96d67f0b840b6e6498e1f68a9 Mon Sep 17 00:00:00 2001
+From: Jonas Witschel <diabonas at archlinux.org>
+Date: Sat, 21 Nov 2020 11:48:33 +0100
+Subject: [PATCH 2/2] cifs.upall: update the cap bounding set only when
+ CAP_SETPCAP is given
+
+libcap-ng 0.8.1 tightened the error checking on capng_apply, returning an error
+of -4 when trying to update the capability bounding set without having the
+CAP_SETPCAP capability to be able to do so. Previous versions of libcap-ng
+silently skipped updating the bounding set and only updated the normal
+CAPNG_SELECT_CAPS capabilities instead.
+
+Check beforehand whether we have CAP_SETPCAP, in which case we can use
+CAPNG_SELECT_BOTH to update both the normal capabilities and the bounding set.
+Otherwise, we can at least update the normal capabilities, but refrain from
+trying to update the bounding set to avoid getting an error.
+
+Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
+---
+ cifs.upcall.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/cifs.upcall.c b/cifs.upcall.c
+index 1559434..af1a0b0 100644
+--- a/cifs.upcall.c
++++ b/cifs.upcall.c
+@@ -88,6 +88,8 @@ typedef enum _sectype {
+ static int
+ trim_capabilities(bool need_environ)
+ {
++ capng_select_t set = CAPNG_SELECT_CAPS;
++
+ capng_clear(CAPNG_SELECT_BOTH);
+
+ /* SETUID and SETGID to change uid, gid, and grouplist */
+@@ -105,7 +107,10 @@ trim_capabilities(bool need_environ)
+ return 1;
+ }
+
+- if (capng_apply(CAPNG_SELECT_BOTH)) {
++ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
++ set = CAPNG_SELECT_BOTH;
++ }
++ if (capng_apply(set)) {
+ syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
+ return 1;
+ }
+--
+2.29.2
+
Deleted: cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch
===================================================================
--- cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch 2022-04-30 16:19:28 UTC (rev 444345)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -1,58 +0,0 @@
-From 0fddcee4b1b9c9f16b3cfe1b2daec87d2b8b19dd Mon Sep 17 00:00:00 2001
-From: Alexander Koch <mail at alexanderkoch.net>
-Date: Wed, 16 Dec 2020 18:02:31 +0100
-Subject: [PATCH] cifs.upcall: drop bounding capabilities only if CAP_SETPCAP
- is given
-
-Make drop_call_capabilities() in cifs.upcall update the bounding capabilities
-only if CAP_SETCAP is present.
-
-This is an addendum to the patch recently provided in [1]. Without this
-additional change, cifs.upcall can still fail while trying to mount a CIFS
-network share with krb5:
-
- kernel: CIFS: Attempting to mount //server.domain.lan/myshare
- cifs.upcall[39484]: key description: cifs.spnego;0;0;39010000;ver=0x2;host=server.domain.lan>
- cifs.upcall[39484]: ver=2
- cifs.upcall[39484]: host=server.domain.lan
- cifs.upcall[39484]: ip=172.22.3.14
- cifs.upcall[39484]: sec=1
- cifs.upcall[39484]: uid=1000
- cifs.upcall[39484]: creduid=1000
- cifs.upcall[39484]: user=username
- cifs.upcall[39484]: pid=39481
- cifs.upcall[39484]: get_cachename_from_process_env: pathname=/proc/39481/environ
- cifs.upcall[39484]: get_cachename_from_process_env: cachename = FILE:/tmp/.krb5cc_1000
- cifs.upcall[39484]: drop_all_capabilities: Unable to apply capability set: Success
- cifs.upcall[39484]: Exit status 1
-
-[1] https://marc.info/?l=linux-cifs&m=160595758021261
-
-Signed-off-by: Alexander Koch <mail at alexanderkoch.net>
-Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
----
- cifs.upcall.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/cifs.upcall.c b/cifs.upcall.c
-index 1559434..b62ab50 100644
---- a/cifs.upcall.c
-+++ b/cifs.upcall.c
-@@ -115,8 +115,13 @@ trim_capabilities(bool need_environ)
- static int
- drop_all_capabilities(void)
- {
-+ capng_select_t set = CAPNG_SELECT_CAPS;
-+
- capng_clear(CAPNG_SELECT_BOTH);
-- if (capng_apply(CAPNG_SELECT_BOTH)) {
-+ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
-+ set = CAPNG_SELECT_BOTH;
-+ }
-+ if (capng_apply(set)) {
- syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
- return 1;
- }
---
-2.29.2
-
Copied: cifs-utils/repos/extra-x86_64/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch (from rev 444345, cifs-utils/trunk/cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch)
===================================================================
--- cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch (rev 0)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -0,0 +1,58 @@
+From 0fddcee4b1b9c9f16b3cfe1b2daec87d2b8b19dd Mon Sep 17 00:00:00 2001
+From: Alexander Koch <mail at alexanderkoch.net>
+Date: Wed, 16 Dec 2020 18:02:31 +0100
+Subject: [PATCH] cifs.upcall: drop bounding capabilities only if CAP_SETPCAP
+ is given
+
+Make drop_call_capabilities() in cifs.upcall update the bounding capabilities
+only if CAP_SETCAP is present.
+
+This is an addendum to the patch recently provided in [1]. Without this
+additional change, cifs.upcall can still fail while trying to mount a CIFS
+network share with krb5:
+
+ kernel: CIFS: Attempting to mount //server.domain.lan/myshare
+ cifs.upcall[39484]: key description: cifs.spnego;0;0;39010000;ver=0x2;host=server.domain.lan>
+ cifs.upcall[39484]: ver=2
+ cifs.upcall[39484]: host=server.domain.lan
+ cifs.upcall[39484]: ip=172.22.3.14
+ cifs.upcall[39484]: sec=1
+ cifs.upcall[39484]: uid=1000
+ cifs.upcall[39484]: creduid=1000
+ cifs.upcall[39484]: user=username
+ cifs.upcall[39484]: pid=39481
+ cifs.upcall[39484]: get_cachename_from_process_env: pathname=/proc/39481/environ
+ cifs.upcall[39484]: get_cachename_from_process_env: cachename = FILE:/tmp/.krb5cc_1000
+ cifs.upcall[39484]: drop_all_capabilities: Unable to apply capability set: Success
+ cifs.upcall[39484]: Exit status 1
+
+[1] https://marc.info/?l=linux-cifs&m=160595758021261
+
+Signed-off-by: Alexander Koch <mail at alexanderkoch.net>
+Signed-off-by: Jonas Witschel <diabonas at archlinux.org>
+---
+ cifs.upcall.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/cifs.upcall.c b/cifs.upcall.c
+index 1559434..b62ab50 100644
+--- a/cifs.upcall.c
++++ b/cifs.upcall.c
+@@ -115,8 +115,13 @@ trim_capabilities(bool need_environ)
+ static int
+ drop_all_capabilities(void)
+ {
++ capng_select_t set = CAPNG_SELECT_CAPS;
++
+ capng_clear(CAPNG_SELECT_BOTH);
+- if (capng_apply(CAPNG_SELECT_BOTH)) {
++ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
++ set = CAPNG_SELECT_BOTH;
++ }
++ if (capng_apply(set)) {
+ syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
+ return 1;
+ }
+--
+2.29.2
+
Deleted: cifs-utils-6.13_fix-regression-in-kerberos-mount.patch
===================================================================
--- cifs-utils-6.13_fix-regression-in-kerberos-mount.patch 2022-04-30 16:19:28 UTC (rev 444345)
+++ cifs-utils-6.13_fix-regression-in-kerberos-mount.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -1,493 +0,0 @@
-From 7f9711dd902a239c499682015d708f73ec884af2 Mon Sep 17 00:00:00 2001
-From: Aurelien Aptel <aaptel at suse.com>
-Date: Wed, 21 Apr 2021 16:22:15 +0200
-Subject: [PATCH] cifs.upcall: fix regression in kerberos mount
-
-The fix for CVE-2021-20208 in commit e461afd ("cifs.upcall: try to use
-container ipc/uts/net/pid/mnt/user namespaces") introduced a
-regression for kerberos mounts when cifs-utils is built with
-libcap-ng. It makes mount fail with ENOKEY "Required key not
-available".
-
-Current state:
-
-mount.cifs
- '---> mount() ---> kernel
- negprot, session setup (need security blob for krb)
- request_key("cifs.spnego", payload="pid=%d;username=...")
- upcall
- /sbin/request-key <--------------'
- reads /etc/request-keys.conf
- dispatch cifs.spnego request
- calls /usr/sbin/cifs.upcall <key id>
- - drop privileges (capabilities)
- - fetch keyid
- - parse payload
- - switch to mount.cifs namespaces
- - call krb5_xxx() funcs
- - generate security blob
- - set key value to security blob
- '-----------------------------------> kernel
- put blob in session setup packet
- continue auth
- open tcon
- get share root
- setup superblock
-mount.cifs mount() returns <-----------'
-
-By the time cifs.upcall tries to switch to namespaces, enough
-capabilities have dropped in trim_capabilities() that it makes setns()
-fail with EPERM.
-
-setns() requires CAP_SYS_ADMIN.
-
-With libcap trim_capabilities() is a no-op.
-
-This fix:
-
-- moves the namespace switch earlier so that operations like
- setgroups(), setgid(), scanning of pid environment, ... happens in the
- contained namespaces.
-- moves trim_capabilities() after the namespace switch
-- moves the string processing to decode the key request payload in a
- child process with minimum capabilities. the decoded data is shared
- with the parent process via shared memory obtained with mmap().
-
-Fixes: e461afd ("cifs.upcall: try to use container ipc/uts/net/pid/mnt/user namespaces")
-Signed-off-by: Aurelien Aptel <aaptel at suse.com>
----
- cifs.upcall.c | 214 ++++++++++++++++++++++++++++++++------------------
- 1 file changed, 139 insertions(+), 75 deletions(-)
-
-diff --git a/cifs.upcall.c b/cifs.upcall.c
-index e413934..ad04301 100644
---- a/cifs.upcall.c
-+++ b/cifs.upcall.c
-@@ -52,6 +52,9 @@
- #include <stdbool.h>
- #include <errno.h>
- #include <sched.h>
-+#include <sys/mman.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-
- #include "data_blob.h"
- #include "spnego.h"
-@@ -787,6 +790,25 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
- return retval;
- }
-
-+
-+
-+struct decoded_args {
-+ int ver;
-+ char hostname[NI_MAXHOST + 1];
-+ char ip[NI_MAXHOST + 1];
-+
-+/* Max user name length. */
-+#define MAX_USERNAME_SIZE 256
-+ char username[MAX_USERNAME_SIZE + 1];
-+
-+ uid_t uid;
-+ uid_t creduid;
-+ pid_t pid;
-+ sectype_t sec;
-+
-+/*
-+ * Flags to keep track of what was provided
-+ */
- #define DKD_HAVE_HOSTNAME 0x1
- #define DKD_HAVE_VERSION 0x2
- #define DKD_HAVE_SEC 0x4
-@@ -796,23 +818,13 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
- #define DKD_HAVE_CREDUID 0x40
- #define DKD_HAVE_USERNAME 0x80
- #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
--
--struct decoded_args {
-- int ver;
-- char *hostname;
-- char *ip;
-- char *username;
-- uid_t uid;
-- uid_t creduid;
-- pid_t pid;
-- sectype_t sec;
-+ int have;
- };
-
- static unsigned int
--decode_key_description(const char *desc, struct decoded_args *arg)
-+__decode_key_description(const char *desc, struct decoded_args *arg)
- {
-- int len;
-- int retval = 0;
-+ size_t len;
- char *pos;
- const char *tkn = desc;
-
-@@ -826,13 +838,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- len = pos - tkn;
-
- len -= 5;
-- free(arg->hostname);
-- arg->hostname = strndup(tkn + 5, len);
-- if (arg->hostname == NULL) {
-- syslog(LOG_ERR, "Unable to allocate memory");
-+ if (len > sizeof(arg->hostname)-1) {
-+ syslog(LOG_ERR, "host= value too long for buffer");
- return 1;
- }
-- retval |= DKD_HAVE_HOSTNAME;
-+ memset(arg->hostname, 0, sizeof(arg->hostname));
-+ strncpy(arg->hostname, tkn + 5, len);
-+ arg->have |= DKD_HAVE_HOSTNAME;
- syslog(LOG_DEBUG, "host=%s", arg->hostname);
- } else if (!strncmp(tkn, "ip4=", 4) || !strncmp(tkn, "ip6=", 4)) {
- if (pos == NULL)
-@@ -841,13 +853,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- len = pos - tkn;
-
- len -= 4;
-- free(arg->ip);
-- arg->ip = strndup(tkn + 4, len);
-- if (arg->ip == NULL) {
-- syslog(LOG_ERR, "Unable to allocate memory");
-+ if (len > sizeof(arg->ip)-1) {
-+ syslog(LOG_ERR, "ip[46]= value too long for buffer");
- return 1;
- }
-- retval |= DKD_HAVE_IP;
-+ memset(arg->ip, 0, sizeof(arg->ip));
-+ strncpy(arg->ip, tkn + 4, len);
-+ arg->have |= DKD_HAVE_IP;
- syslog(LOG_DEBUG, "ip=%s", arg->ip);
- } else if (strncmp(tkn, "user=", 5) == 0) {
- if (pos == NULL)
-@@ -856,13 +868,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- len = pos - tkn;
-
- len -= 5;
-- free(arg->username);
-- arg->username = strndup(tkn + 5, len);
-- if (arg->username == NULL) {
-- syslog(LOG_ERR, "Unable to allocate memory");
-+ if (len > sizeof(arg->username)-1) {
-+ syslog(LOG_ERR, "user= value too long for buffer");
- return 1;
- }
-- retval |= DKD_HAVE_USERNAME;
-+ memset(arg->username, 0, sizeof(arg->username));
-+ strncpy(arg->username, tkn + 5, len);
-+ arg->have |= DKD_HAVE_USERNAME;
- syslog(LOG_DEBUG, "user=%s", arg->username);
- } else if (strncmp(tkn, "pid=", 4) == 0) {
- errno = 0;
-@@ -873,13 +885,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- return 1;
- }
- syslog(LOG_DEBUG, "pid=%u", arg->pid);
-- retval |= DKD_HAVE_PID;
-+ arg->have |= DKD_HAVE_PID;
- } else if (strncmp(tkn, "sec=", 4) == 0) {
- if (strncmp(tkn + 4, "krb5", 4) == 0) {
-- retval |= DKD_HAVE_SEC;
-+ arg->have |= DKD_HAVE_SEC;
- arg->sec = KRB5;
- } else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
-- retval |= DKD_HAVE_SEC;
-+ arg->have |= DKD_HAVE_SEC;
- arg->sec = MS_KRB5;
- }
- syslog(LOG_DEBUG, "sec=%d", arg->sec);
-@@ -891,7 +903,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- strerror(errno));
- return 1;
- }
-- retval |= DKD_HAVE_UID;
-+ arg->have |= DKD_HAVE_UID;
- syslog(LOG_DEBUG, "uid=%u", arg->uid);
- } else if (strncmp(tkn, "creduid=", 8) == 0) {
- errno = 0;
-@@ -901,7 +913,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- strerror(errno));
- return 1;
- }
-- retval |= DKD_HAVE_CREDUID;
-+ arg->have |= DKD_HAVE_CREDUID;
- syslog(LOG_DEBUG, "creduid=%u", arg->creduid);
- } else if (strncmp(tkn, "ver=", 4) == 0) { /* if version */
- errno = 0;
-@@ -911,14 +923,56 @@ decode_key_description(const char *desc, struct decoded_args *arg)
- strerror(errno));
- return 1;
- }
-- retval |= DKD_HAVE_VERSION;
-+ arg->have |= DKD_HAVE_VERSION;
- syslog(LOG_DEBUG, "ver=%d", arg->ver);
- }
- if (pos == NULL)
- break;
- tkn = pos + 1;
- } while (tkn);
-- return retval;
-+ return 0;
-+}
-+
-+static unsigned int
-+decode_key_description(const char *desc, struct decoded_args **arg)
-+{
-+ pid_t pid;
-+ pid_t rc;
-+ int status;
-+
-+ /*
-+ * Do all the decoding/string processing in a child process
-+ * with low privileges.
-+ */
-+
-+ *arg = mmap(NULL, sizeof(struct decoded_args), PROT_READ | PROT_WRITE,
-+ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
-+ if (*arg == MAP_FAILED) {
-+ syslog(LOG_ERR, "%s: mmap failed: %s", __func__, strerror(errno));
-+ return -1;
-+ }
-+
-+ pid = fork();
-+ if (pid < 0) {
-+ syslog(LOG_ERR, "%s: fork failed: %s", __func__, strerror(errno));
-+ munmap(*arg, sizeof(struct decoded_args));
-+ *arg = NULL;
-+ return -1;
-+ }
-+ if (pid == 0) {
-+ /* do the parsing in child */
-+ drop_all_capabilities();
-+ exit(__decode_key_description(desc, *arg));
-+ }
-+
-+ rc = waitpid(pid, &status, 0);
-+ if (rc < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-+ munmap(*arg, sizeof(struct decoded_args));
-+ *arg = NULL;
-+ return 1;
-+ }
-+
-+ return 0;
- }
-
- static int setup_key(const key_serial_t key, const void *data, size_t datalen)
-@@ -1098,7 +1152,7 @@ int main(const int argc, char *const argv[])
- bool try_dns = false, legacy_uid = false , env_probe = true;
- char *buf;
- char hostbuf[NI_MAXHOST], *host;
-- struct decoded_args arg;
-+ struct decoded_args *arg = NULL;
- const char *oid;
- uid_t uid;
- char *keytab_name = NULL;
-@@ -1109,7 +1163,6 @@ int main(const int argc, char *const argv[])
- const char *key_descr = NULL;
-
- hostbuf[0] = '\0';
-- memset(&arg, 0, sizeof(arg));
-
- openlog(prog, 0, LOG_DAEMON);
-
-@@ -1150,9 +1203,6 @@ int main(const int argc, char *const argv[])
- }
- }
-
-- if (trim_capabilities(env_probe))
-- goto out;
--
- /* is there a key? */
- if (argc <= optind) {
- usage();
-@@ -1178,6 +1228,10 @@ int main(const int argc, char *const argv[])
-
- syslog(LOG_DEBUG, "key description: %s", buf);
-
-+ /*
-+ * If we are requested a simple DNS query, do it and exit
-+ */
-+
- if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0)
- key_descr = ".cifs.resolver";
- else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)
-@@ -1187,33 +1241,42 @@ int main(const int argc, char *const argv[])
- goto out;
- }
-
-- have = decode_key_description(buf, &arg);
-+ /*
-+ * Otherwise, it's a spnego key request
-+ */
-+
-+ rc = decode_key_description(buf, &arg);
- free(buf);
-- if ((have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
-+ if (rc) {
-+ syslog(LOG_ERR, "failed to decode key description");
-+ goto out;
-+ }
-+
-+ if ((arg->have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
- syslog(LOG_ERR, "unable to get necessary params from key "
- "description (0x%x)", have);
- rc = 1;
- goto out;
- }
-
-- if (arg.ver > CIFS_SPNEGO_UPCALL_VERSION) {
-+ if (arg->ver > CIFS_SPNEGO_UPCALL_VERSION) {
- syslog(LOG_ERR, "incompatible kernel upcall version: 0x%x",
-- arg.ver);
-+ arg->ver);
- rc = 1;
- goto out;
- }
-
-- if (strlen(arg.hostname) >= NI_MAXHOST) {
-+ if (strlen(arg->hostname) >= NI_MAXHOST) {
- syslog(LOG_ERR, "hostname provided by kernel is too long");
- rc = 1;
- goto out;
-
- }
-
-- if (!legacy_uid && (have & DKD_HAVE_CREDUID))
-- uid = arg.creduid;
-- else if (have & DKD_HAVE_UID)
-- uid = arg.uid;
-+ if (!legacy_uid && (arg->have & DKD_HAVE_CREDUID))
-+ uid = arg->creduid;
-+ else if (arg->have & DKD_HAVE_UID)
-+ uid = arg->uid;
- else {
- /* no uid= or creduid= parm -- something is wrong */
- syslog(LOG_ERR, "No uid= or creduid= parm specified");
-@@ -1221,6 +1284,21 @@ int main(const int argc, char *const argv[])
- goto out;
- }
-
-+ /*
-+ * Change to the process's namespace. This means that things will work
-+ * acceptably in containers, because we'll be looking at the correct
-+ * filesystem and have the correct network configuration.
-+ */
-+ rc = switch_to_process_ns(arg->pid);
-+ if (rc == -1) {
-+ syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno));
-+ rc = 1;
-+ goto out;
-+ }
-+
-+ if (trim_capabilities(env_probe))
-+ goto out;
-+
- /*
- * The kernel doesn't pass down the gid, so we resort here to scraping
- * one out of the passwd nss db. Note that this might not reflect the
-@@ -1266,20 +1344,7 @@ int main(const int argc, char *const argv[])
- * look at the environ file.
- */
- env_cachename =
-- get_cachename_from_process_env(env_probe ? arg.pid : 0);
--
-- /*
-- * Change to the process's namespace. This means that things will work
-- * acceptably in containers, because we'll be looking at the correct
-- * filesystem and have the correct network configuration.
-- */
-- rc = switch_to_process_ns(arg.pid);
-- if (rc == -1) {
-- syslog(LOG_ERR, "unable to switch to process namespace: %s",
-- strerror(errno));
-- rc = 1;
-- goto out;
-- }
-+ get_cachename_from_process_env(env_probe ? arg->pid : 0);
-
- rc = setuid(uid);
- if (rc == -1) {
-@@ -1301,18 +1366,18 @@ int main(const int argc, char *const argv[])
-
- ccache = get_existing_cc(env_cachename);
- /* Couldn't find credcache? Try to use keytab */
-- if (ccache == NULL && arg.username != NULL)
-- ccache = init_cc_from_keytab(keytab_name, arg.username);
-+ if (ccache == NULL && arg->username[0] != '\0')
-+ ccache = init_cc_from_keytab(keytab_name, arg->username);
-
- if (ccache == NULL) {
- rc = 1;
- goto out;
- }
-
-- host = arg.hostname;
-+ host = arg->hostname;
-
- // do mech specific authorization
-- switch (arg.sec) {
-+ switch (arg->sec) {
- case MS_KRB5:
- case KRB5:
- /*
-@@ -1328,7 +1393,7 @@ int main(const int argc, char *const argv[])
- * TRY only:
- * cifs/bar.example.com at REALM
- */
-- if (arg.sec == MS_KRB5)
-+ if (arg->sec == MS_KRB5)
- oid = OID_KERBEROS5_OLD;
- else
- oid = OID_KERBEROS5;
-@@ -1385,10 +1450,10 @@ retry_new_hostname:
- break;
- }
-
-- if (!try_dns || !(have & DKD_HAVE_IP))
-+ if (!try_dns || !(arg->have & DKD_HAVE_IP))
- break;
-
-- rc = ip_to_fqdn(arg.ip, hostbuf, sizeof(hostbuf));
-+ rc = ip_to_fqdn(arg->ip, hostbuf, sizeof(hostbuf));
- if (rc)
- break;
-
-@@ -1396,7 +1461,7 @@ retry_new_hostname:
- host = hostbuf;
- goto retry_new_hostname;
- default:
-- syslog(LOG_ERR, "sectype: %d is not implemented", arg.sec);
-+ syslog(LOG_ERR, "sectype: %d is not implemented", arg->sec);
- rc = 1;
- break;
- }
-@@ -1414,7 +1479,7 @@ retry_new_hostname:
- rc = 1;
- goto out;
- }
-- keydata->version = arg.ver;
-+ keydata->version = arg->ver;
- keydata->flags = 0;
- keydata->sesskey_len = sess_key.length;
- keydata->secblob_len = secblob.length;
-@@ -1440,11 +1505,10 @@ out:
- krb5_cc_close(context, ccache);
- if (context)
- krb5_free_context(context);
-- free(arg.hostname);
-- free(arg.ip);
-- free(arg.username);
- free(keydata);
- free(env_cachename);
-+ if (arg)
-+ munmap(arg, sizeof(*arg));
- syslog(LOG_DEBUG, "Exit status %ld", rc);
- return rc;
- }
---
-2.33.0
-
Copied: cifs-utils/repos/extra-x86_64/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch (from rev 444345, cifs-utils/trunk/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch)
===================================================================
--- cifs-utils-6.13_fix-regression-in-kerberos-mount.patch (rev 0)
+++ cifs-utils-6.13_fix-regression-in-kerberos-mount.patch 2022-04-30 16:19:39 UTC (rev 444346)
@@ -0,0 +1,493 @@
+From 7f9711dd902a239c499682015d708f73ec884af2 Mon Sep 17 00:00:00 2001
+From: Aurelien Aptel <aaptel at suse.com>
+Date: Wed, 21 Apr 2021 16:22:15 +0200
+Subject: [PATCH] cifs.upcall: fix regression in kerberos mount
+
+The fix for CVE-2021-20208 in commit e461afd ("cifs.upcall: try to use
+container ipc/uts/net/pid/mnt/user namespaces") introduced a
+regression for kerberos mounts when cifs-utils is built with
+libcap-ng. It makes mount fail with ENOKEY "Required key not
+available".
+
+Current state:
+
+mount.cifs
+ '---> mount() ---> kernel
+ negprot, session setup (need security blob for krb)
+ request_key("cifs.spnego", payload="pid=%d;username=...")
+ upcall
+ /sbin/request-key <--------------'
+ reads /etc/request-keys.conf
+ dispatch cifs.spnego request
+ calls /usr/sbin/cifs.upcall <key id>
+ - drop privileges (capabilities)
+ - fetch keyid
+ - parse payload
+ - switch to mount.cifs namespaces
+ - call krb5_xxx() funcs
+ - generate security blob
+ - set key value to security blob
+ '-----------------------------------> kernel
+ put blob in session setup packet
+ continue auth
+ open tcon
+ get share root
+ setup superblock
+mount.cifs mount() returns <-----------'
+
+By the time cifs.upcall tries to switch to namespaces, enough
+capabilities have dropped in trim_capabilities() that it makes setns()
+fail with EPERM.
+
+setns() requires CAP_SYS_ADMIN.
+
+With libcap trim_capabilities() is a no-op.
+
+This fix:
+
+- moves the namespace switch earlier so that operations like
+ setgroups(), setgid(), scanning of pid environment, ... happens in the
+ contained namespaces.
+- moves trim_capabilities() after the namespace switch
+- moves the string processing to decode the key request payload in a
+ child process with minimum capabilities. the decoded data is shared
+ with the parent process via shared memory obtained with mmap().
+
+Fixes: e461afd ("cifs.upcall: try to use container ipc/uts/net/pid/mnt/user namespaces")
+Signed-off-by: Aurelien Aptel <aaptel at suse.com>
+---
+ cifs.upcall.c | 214 ++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 139 insertions(+), 75 deletions(-)
+
+diff --git a/cifs.upcall.c b/cifs.upcall.c
+index e413934..ad04301 100644
+--- a/cifs.upcall.c
++++ b/cifs.upcall.c
+@@ -52,6 +52,9 @@
+ #include <stdbool.h>
+ #include <errno.h>
+ #include <sched.h>
++#include <sys/mman.h>
++#include <sys/types.h>
++#include <sys/wait.h>
+
+ #include "data_blob.h"
+ #include "spnego.h"
+@@ -787,6 +790,25 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
+ return retval;
+ }
+
++
++
++struct decoded_args {
++ int ver;
++ char hostname[NI_MAXHOST + 1];
++ char ip[NI_MAXHOST + 1];
++
++/* Max user name length. */
++#define MAX_USERNAME_SIZE 256
++ char username[MAX_USERNAME_SIZE + 1];
++
++ uid_t uid;
++ uid_t creduid;
++ pid_t pid;
++ sectype_t sec;
++
++/*
++ * Flags to keep track of what was provided
++ */
+ #define DKD_HAVE_HOSTNAME 0x1
+ #define DKD_HAVE_VERSION 0x2
+ #define DKD_HAVE_SEC 0x4
+@@ -796,23 +818,13 @@ handle_krb5_mech(const char *oid, const char *host, DATA_BLOB * secblob,
+ #define DKD_HAVE_CREDUID 0x40
+ #define DKD_HAVE_USERNAME 0x80
+ #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
+-
+-struct decoded_args {
+- int ver;
+- char *hostname;
+- char *ip;
+- char *username;
+- uid_t uid;
+- uid_t creduid;
+- pid_t pid;
+- sectype_t sec;
++ int have;
+ };
+
+ static unsigned int
+-decode_key_description(const char *desc, struct decoded_args *arg)
++__decode_key_description(const char *desc, struct decoded_args *arg)
+ {
+- int len;
+- int retval = 0;
++ size_t len;
+ char *pos;
+ const char *tkn = desc;
+
+@@ -826,13 +838,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ len = pos - tkn;
+
+ len -= 5;
+- free(arg->hostname);
+- arg->hostname = strndup(tkn + 5, len);
+- if (arg->hostname == NULL) {
+- syslog(LOG_ERR, "Unable to allocate memory");
++ if (len > sizeof(arg->hostname)-1) {
++ syslog(LOG_ERR, "host= value too long for buffer");
+ return 1;
+ }
+- retval |= DKD_HAVE_HOSTNAME;
++ memset(arg->hostname, 0, sizeof(arg->hostname));
++ strncpy(arg->hostname, tkn + 5, len);
++ arg->have |= DKD_HAVE_HOSTNAME;
+ syslog(LOG_DEBUG, "host=%s", arg->hostname);
+ } else if (!strncmp(tkn, "ip4=", 4) || !strncmp(tkn, "ip6=", 4)) {
+ if (pos == NULL)
+@@ -841,13 +853,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ len = pos - tkn;
+
+ len -= 4;
+- free(arg->ip);
+- arg->ip = strndup(tkn + 4, len);
+- if (arg->ip == NULL) {
+- syslog(LOG_ERR, "Unable to allocate memory");
++ if (len > sizeof(arg->ip)-1) {
++ syslog(LOG_ERR, "ip[46]= value too long for buffer");
+ return 1;
+ }
+- retval |= DKD_HAVE_IP;
++ memset(arg->ip, 0, sizeof(arg->ip));
++ strncpy(arg->ip, tkn + 4, len);
++ arg->have |= DKD_HAVE_IP;
+ syslog(LOG_DEBUG, "ip=%s", arg->ip);
+ } else if (strncmp(tkn, "user=", 5) == 0) {
+ if (pos == NULL)
+@@ -856,13 +868,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ len = pos - tkn;
+
+ len -= 5;
+- free(arg->username);
+- arg->username = strndup(tkn + 5, len);
+- if (arg->username == NULL) {
+- syslog(LOG_ERR, "Unable to allocate memory");
++ if (len > sizeof(arg->username)-1) {
++ syslog(LOG_ERR, "user= value too long for buffer");
+ return 1;
+ }
+- retval |= DKD_HAVE_USERNAME;
++ memset(arg->username, 0, sizeof(arg->username));
++ strncpy(arg->username, tkn + 5, len);
++ arg->have |= DKD_HAVE_USERNAME;
+ syslog(LOG_DEBUG, "user=%s", arg->username);
+ } else if (strncmp(tkn, "pid=", 4) == 0) {
+ errno = 0;
+@@ -873,13 +885,13 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ return 1;
+ }
+ syslog(LOG_DEBUG, "pid=%u", arg->pid);
+- retval |= DKD_HAVE_PID;
++ arg->have |= DKD_HAVE_PID;
+ } else if (strncmp(tkn, "sec=", 4) == 0) {
+ if (strncmp(tkn + 4, "krb5", 4) == 0) {
+- retval |= DKD_HAVE_SEC;
++ arg->have |= DKD_HAVE_SEC;
+ arg->sec = KRB5;
+ } else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
+- retval |= DKD_HAVE_SEC;
++ arg->have |= DKD_HAVE_SEC;
+ arg->sec = MS_KRB5;
+ }
+ syslog(LOG_DEBUG, "sec=%d", arg->sec);
+@@ -891,7 +903,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ strerror(errno));
+ return 1;
+ }
+- retval |= DKD_HAVE_UID;
++ arg->have |= DKD_HAVE_UID;
+ syslog(LOG_DEBUG, "uid=%u", arg->uid);
+ } else if (strncmp(tkn, "creduid=", 8) == 0) {
+ errno = 0;
+@@ -901,7 +913,7 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ strerror(errno));
+ return 1;
+ }
+- retval |= DKD_HAVE_CREDUID;
++ arg->have |= DKD_HAVE_CREDUID;
+ syslog(LOG_DEBUG, "creduid=%u", arg->creduid);
+ } else if (strncmp(tkn, "ver=", 4) == 0) { /* if version */
+ errno = 0;
+@@ -911,14 +923,56 @@ decode_key_description(const char *desc, struct decoded_args *arg)
+ strerror(errno));
+ return 1;
+ }
+- retval |= DKD_HAVE_VERSION;
++ arg->have |= DKD_HAVE_VERSION;
+ syslog(LOG_DEBUG, "ver=%d", arg->ver);
+ }
+ if (pos == NULL)
+ break;
+ tkn = pos + 1;
+ } while (tkn);
+- return retval;
++ return 0;
++}
++
++static unsigned int
++decode_key_description(const char *desc, struct decoded_args **arg)
++{
++ pid_t pid;
++ pid_t rc;
++ int status;
++
++ /*
++ * Do all the decoding/string processing in a child process
++ * with low privileges.
++ */
++
++ *arg = mmap(NULL, sizeof(struct decoded_args), PROT_READ | PROT_WRITE,
++ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
++ if (*arg == MAP_FAILED) {
++ syslog(LOG_ERR, "%s: mmap failed: %s", __func__, strerror(errno));
++ return -1;
++ }
++
++ pid = fork();
++ if (pid < 0) {
++ syslog(LOG_ERR, "%s: fork failed: %s", __func__, strerror(errno));
++ munmap(*arg, sizeof(struct decoded_args));
++ *arg = NULL;
++ return -1;
++ }
++ if (pid == 0) {
++ /* do the parsing in child */
++ drop_all_capabilities();
++ exit(__decode_key_description(desc, *arg));
++ }
++
++ rc = waitpid(pid, &status, 0);
++ if (rc < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
++ munmap(*arg, sizeof(struct decoded_args));
++ *arg = NULL;
++ return 1;
++ }
++
++ return 0;
+ }
+
+ static int setup_key(const key_serial_t key, const void *data, size_t datalen)
+@@ -1098,7 +1152,7 @@ int main(const int argc, char *const argv[])
+ bool try_dns = false, legacy_uid = false , env_probe = true;
+ char *buf;
+ char hostbuf[NI_MAXHOST], *host;
+- struct decoded_args arg;
++ struct decoded_args *arg = NULL;
+ const char *oid;
+ uid_t uid;
+ char *keytab_name = NULL;
+@@ -1109,7 +1163,6 @@ int main(const int argc, char *const argv[])
+ const char *key_descr = NULL;
+
+ hostbuf[0] = '\0';
+- memset(&arg, 0, sizeof(arg));
+
+ openlog(prog, 0, LOG_DAEMON);
+
+@@ -1150,9 +1203,6 @@ int main(const int argc, char *const argv[])
+ }
+ }
+
+- if (trim_capabilities(env_probe))
+- goto out;
+-
+ /* is there a key? */
+ if (argc <= optind) {
+ usage();
+@@ -1178,6 +1228,10 @@ int main(const int argc, char *const argv[])
+
+ syslog(LOG_DEBUG, "key description: %s", buf);
+
++ /*
++ * If we are requested a simple DNS query, do it and exit
++ */
++
+ if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0)
+ key_descr = ".cifs.resolver";
+ else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)
+@@ -1187,33 +1241,42 @@ int main(const int argc, char *const argv[])
+ goto out;
+ }
+
+- have = decode_key_description(buf, &arg);
++ /*
++ * Otherwise, it's a spnego key request
++ */
++
++ rc = decode_key_description(buf, &arg);
+ free(buf);
+- if ((have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
++ if (rc) {
++ syslog(LOG_ERR, "failed to decode key description");
++ goto out;
++ }
++
++ if ((arg->have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
+ syslog(LOG_ERR, "unable to get necessary params from key "
+ "description (0x%x)", have);
+ rc = 1;
+ goto out;
+ }
+
+- if (arg.ver > CIFS_SPNEGO_UPCALL_VERSION) {
++ if (arg->ver > CIFS_SPNEGO_UPCALL_VERSION) {
+ syslog(LOG_ERR, "incompatible kernel upcall version: 0x%x",
+- arg.ver);
++ arg->ver);
+ rc = 1;
+ goto out;
+ }
+
+- if (strlen(arg.hostname) >= NI_MAXHOST) {
++ if (strlen(arg->hostname) >= NI_MAXHOST) {
+ syslog(LOG_ERR, "hostname provided by kernel is too long");
+ rc = 1;
+ goto out;
+
+ }
+
+- if (!legacy_uid && (have & DKD_HAVE_CREDUID))
+- uid = arg.creduid;
+- else if (have & DKD_HAVE_UID)
+- uid = arg.uid;
++ if (!legacy_uid && (arg->have & DKD_HAVE_CREDUID))
++ uid = arg->creduid;
++ else if (arg->have & DKD_HAVE_UID)
++ uid = arg->uid;
+ else {
+ /* no uid= or creduid= parm -- something is wrong */
+ syslog(LOG_ERR, "No uid= or creduid= parm specified");
+@@ -1221,6 +1284,21 @@ int main(const int argc, char *const argv[])
+ goto out;
+ }
+
++ /*
++ * Change to the process's namespace. This means that things will work
++ * acceptably in containers, because we'll be looking at the correct
++ * filesystem and have the correct network configuration.
++ */
++ rc = switch_to_process_ns(arg->pid);
++ if (rc == -1) {
++ syslog(LOG_ERR, "unable to switch to process namespace: %s", strerror(errno));
++ rc = 1;
++ goto out;
++ }
++
++ if (trim_capabilities(env_probe))
++ goto out;
++
+ /*
+ * The kernel doesn't pass down the gid, so we resort here to scraping
+ * one out of the passwd nss db. Note that this might not reflect the
+@@ -1266,20 +1344,7 @@ int main(const int argc, char *const argv[])
+ * look at the environ file.
+ */
+ env_cachename =
+- get_cachename_from_process_env(env_probe ? arg.pid : 0);
+-
+- /*
+- * Change to the process's namespace. This means that things will work
+- * acceptably in containers, because we'll be looking at the correct
+- * filesystem and have the correct network configuration.
+- */
+- rc = switch_to_process_ns(arg.pid);
+- if (rc == -1) {
+- syslog(LOG_ERR, "unable to switch to process namespace: %s",
+- strerror(errno));
+- rc = 1;
+- goto out;
+- }
++ get_cachename_from_process_env(env_probe ? arg->pid : 0);
+
+ rc = setuid(uid);
+ if (rc == -1) {
+@@ -1301,18 +1366,18 @@ int main(const int argc, char *const argv[])
+
+ ccache = get_existing_cc(env_cachename);
+ /* Couldn't find credcache? Try to use keytab */
+- if (ccache == NULL && arg.username != NULL)
+- ccache = init_cc_from_keytab(keytab_name, arg.username);
++ if (ccache == NULL && arg->username[0] != '\0')
++ ccache = init_cc_from_keytab(keytab_name, arg->username);
+
+ if (ccache == NULL) {
+ rc = 1;
+ goto out;
+ }
+
+- host = arg.hostname;
++ host = arg->hostname;
+
+ // do mech specific authorization
+- switch (arg.sec) {
++ switch (arg->sec) {
+ case MS_KRB5:
+ case KRB5:
+ /*
+@@ -1328,7 +1393,7 @@ int main(const int argc, char *const argv[])
+ * TRY only:
+ * cifs/bar.example.com at REALM
+ */
+- if (arg.sec == MS_KRB5)
++ if (arg->sec == MS_KRB5)
+ oid = OID_KERBEROS5_OLD;
+ else
+ oid = OID_KERBEROS5;
+@@ -1385,10 +1450,10 @@ retry_new_hostname:
+ break;
+ }
+
+- if (!try_dns || !(have & DKD_HAVE_IP))
++ if (!try_dns || !(arg->have & DKD_HAVE_IP))
+ break;
+
+- rc = ip_to_fqdn(arg.ip, hostbuf, sizeof(hostbuf));
++ rc = ip_to_fqdn(arg->ip, hostbuf, sizeof(hostbuf));
+ if (rc)
+ break;
+
+@@ -1396,7 +1461,7 @@ retry_new_hostname:
+ host = hostbuf;
+ goto retry_new_hostname;
+ default:
+- syslog(LOG_ERR, "sectype: %d is not implemented", arg.sec);
++ syslog(LOG_ERR, "sectype: %d is not implemented", arg->sec);
+ rc = 1;
+ break;
+ }
+@@ -1414,7 +1479,7 @@ retry_new_hostname:
+ rc = 1;
+ goto out;
+ }
+- keydata->version = arg.ver;
++ keydata->version = arg->ver;
+ keydata->flags = 0;
+ keydata->sesskey_len = sess_key.length;
+ keydata->secblob_len = secblob.length;
+@@ -1440,11 +1505,10 @@ out:
+ krb5_cc_close(context, ccache);
+ if (context)
+ krb5_free_context(context);
+- free(arg.hostname);
+- free(arg.ip);
+- free(arg.username);
+ free(keydata);
+ free(env_cachename);
++ if (arg)
++ munmap(arg, sizeof(*arg));
+ syslog(LOG_DEBUG, "Exit status %ld", rc);
+ return rc;
+ }
+--
+2.33.0
+
More information about the arch-commits
mailing list