Date: Friday, September 24, 2021 @ 15:06:17
  Author: tpowa
Revision: 424657

archrelease: copy trunk to extra-x86_64

Added:
  cifs-utils/repos/extra-x86_64/PKGBUILD
    (from rev 424656, 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 424656, 
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 424656, 
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 424656, 
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                                                         |   92 
 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(+), 700 deletions(-)

Deleted: PKGBUILD
===================================================================
--- PKGBUILD    2021-09-24 15:06:08 UTC (rev 424656)
+++ PKGBUILD    2021-09-24 15:06:17 UTC (rev 424657)
@@ -1,48 +0,0 @@
-# Maintainer: Tobias Powalowski <[email protected]>
-pkgname=cifs-utils
-pkgver=6.13
-pkgrel=3
-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}
-        "cifs-utils-6.13_fix-regression-in-kerberos-mount.patch")
-
-validpgpkeys=('C699981A31F338706C817650DF5BA9D30642D5A0') #cifs-utils 
Distribution Verification Key <[email protected]>
-sha256sums=('43d8786c8613caccfa84913081c1d62bc2409575854cf895b05b48af0863d056'
-            'SKIP'
-            'ae3c2dca120d39995b4a24c7c4d3024c6ba16e342010d1811680a1236520731a')
-
-prepare() {
-  # Fix install to honor DESTDIR
-  sed -e 's|cd \$(ROOTSBINDIR)|cd $(DESTDIR)$(ROOTSBINDIR)|g' -i 
$pkgname-$pkgver/Makefile.am
-  cd "$srcdir/$pkgname-$pkgver"
-  patch -Np1 -i 
"$srcdir/cifs-utils-6.13_fix-regression-in-kerberos-mount.patch"
-}
-
-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 424656, 
cifs-utils/trunk/PKGBUILD)
===================================================================
--- PKGBUILD                            (rev 0)
+++ PKGBUILD    2021-09-24 15:06:17 UTC (rev 424657)
@@ -0,0 +1,44 @@
+# Maintainer: Tobias Powalowski <[email protected]>
+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 <[email protected]>
+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
+}

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   2021-09-24 
15:06:08 UTC (rev 424656)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1.patch   2021-09-24 
15:06:17 UTC (rev 424657)
@@ -1,101 +0,0 @@
-From f4e7c84467152624a288351321c8664dbf3364af Mon Sep 17 00:00:00 2001
-From: Jonas Witschel <[email protected]>
-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 <[email protected]>
----
- 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 <[email protected]>
-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 <[email protected]>
----
- 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 424656, 
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   2021-09-24 
15:06:17 UTC (rev 424657)
@@ -0,0 +1,101 @@
+From f4e7c84467152624a288351321c8664dbf3364af Mon Sep 17 00:00:00 2001
+From: Jonas Witschel <[email protected]>
+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 <[email protected]>
+---
+ 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 <[email protected]>
+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 <[email protected]>
+---
+ 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    
2021-09-24 15:06:08 UTC (rev 424656)
+++ cifs-utils-6.11_fix_capng_apply_for_libcap-ng-0.8.1_part-2.patch    
2021-09-24 15:06:17 UTC (rev 424657)
@@ -1,58 +0,0 @@
-From 0fddcee4b1b9c9f16b3cfe1b2daec87d2b8b19dd Mon Sep 17 00:00:00 2001
-From: Alexander Koch <[email protected]>
-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 <[email protected]>
-Signed-off-by: Jonas Witschel <[email protected]>
----
- 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 424656, 
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    
2021-09-24 15:06:17 UTC (rev 424657)
@@ -0,0 +1,58 @@
+From 0fddcee4b1b9c9f16b3cfe1b2daec87d2b8b19dd Mon Sep 17 00:00:00 2001
+From: Alexander Koch <[email protected]>
+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 <[email protected]>
+Signed-off-by: Jonas Witschel <[email protected]>
+---
+ 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      2021-09-24 
15:06:08 UTC (rev 424656)
+++ cifs-utils-6.13_fix-regression-in-kerberos-mount.patch      2021-09-24 
15:06:17 UTC (rev 424657)
@@ -1,493 +0,0 @@
-From 7f9711dd902a239c499682015d708f73ec884af2 Mon Sep 17 00:00:00 2001
-From: Aurelien Aptel <[email protected]>
-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 <[email protected]>
----
- 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@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 424656, 
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      2021-09-24 
15:06:17 UTC (rev 424657)
@@ -0,0 +1,493 @@
+From 7f9711dd902a239c499682015d708f73ec884af2 Mon Sep 17 00:00:00 2001
+From: Aurelien Aptel <[email protected]>
+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 <[email protected]>
+---
+ 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@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
+

Reply via email to