[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#932522: marked as done (buster-pu: package pam-u2f/1.0.7-1)



Your message dated Sat, 07 Sep 2019 14:34:49 +0100
with message-id <[🔎] f49e2985d8466065c49c03185c24465a32228fb5.camel@adam-barratt.org.uk>
and subject line Closing bugs for fixes including in 10.1 point release
has caused the Debian Bug report #932522,
regarding buster-pu: package pam-u2f/1.0.7-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
932522: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=932522
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster security
User: release.debian.org@packages.debian.org
Usertags: pu
Control: block 930021 by -1
Control: block 930023 by -1

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Dear release team,

I prepared a proposed update for pam-u2f, backporting fixes from upstream:

  * multiple security fixes
     + Fix insecure debug file handling CVE-2019-12209. (Closes: #930021)
     + Fix debug file descriptor leak CVE-2019-12210. (Closes: #930023)
     + Fix a non-critical buffer out-of-bounds access.

  * reliability fix
    pam-u2f could previously segfault following a failure to allocate a buffer.


Regarding the security fixes, Salvatore stated in #931991 that the issues do not
warrant issuing a DSA, making them elligible for a fix via -pu.

Please find the debdiff attached.


Best,

  nicoo

- -- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 4.19.0-5-amd64 (SMP w/4 CPU cores)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

-----BEGIN PGP SIGNATURE-----

iQJFBAEBCgAvFiEEU7EqA8ZVHYoLJhPE5vmO4pLV7MsFAl0y/UERHG5pY29vQGRl
Ymlhbi5vcmcACgkQ5vmO4pLV7MtAiBAAqhUt6lU/n5LFHqairAg5msDvEZ7IvyJf
dH/yqFj2StXU6K6UBnz4nO0rc3z25+NEa/IkRxnJdIoxhEFULhg1nBKlM+VSWdUw
HvKIJ0q5VV5iNY9U6XG9gXu2CHVlxMrMwhmrv2d37Pmu40AUcvRfWYWQUOgoLKHf
R2/ydppF+UpxRJVo6DkgaNJwl/Eb/K2M8Ghq51hivPBB7xiTAXP9XW0tydSBe0SU
WDgBexfxf53dfGgSqNovoLCFpikQHRnF5Kr46Lwy94YiDMwnGHPwsEFSNBTtzFEv
YJvtRGT3Vu09Emp1w1fT7JRbYzuc0VYm47dA8KWN3t4QnPaVovfv7wGGtQU3enic
9xZGlvrscOBeP6LNuICCdSwmsmrvWiFH9HQD/aamOSJTDrV1R93SpJPnpIXctPjw
sEsWB8zXDfPkHfrCl/XxY1SuxpcIY1FJbsyfuh5uIL5y5b9BSYoyUjel8HkmSQWE
Nvc4IWl4AoFIwc/i3JwdPFUk34Kj79ogQitjrhVHQc78uFivUaHmvp5Kkhn/fe+4
bdEBPXLpxwUlS49XzjVPA3nhtnZrLotaqUxpMVdQV4P/8e7UEyILDgCe0SRRLQ2w
BSbMBsYrRHCQQvvqeV1taIB/UvRcQY8UPSQrYOe1rkNBYWX8K4yDJnZlPng9gBcJ
VJu/aURTTD4=
=Gn9T
-----END PGP SIGNATURE-----
diff -Nru pam-u2f-1.0.7/debian/changelog pam-u2f-1.0.7/debian/changelog
--- pam-u2f-1.0.7/debian/changelog	2018-05-29 14:33:06.000000000 +0200
+++ pam-u2f-1.0.7/debian/changelog	2019-07-20 13:29:57.000000000 +0200
@@ -1,3 +1,15 @@
+pam-u2f (1.0.7-1+deb10u1) buster-proposed-updates; urgency=high
+
+  * Backport multiple security fixes
+     + Fix insecure debug file handling CVE-2019-12209. (Closes: #930021)
+     + Fix debug file descriptor leak CVE-2019-12210. (Closes: #930023)
+     + Fix a non-critical buffer out-of-bounds access.
+
+  * Backport a reliability fix
+    pam-u2f could previously segfault following a failure to allocate a buffer.
+
+ -- Nicolas Braud-Santoni <nicoo@debian.org>  Sat, 20 Jul 2019 13:29:57 +0200
+
 pam-u2f (1.0.7-1) unstable; urgency=high
 
   * New upstream version 1.0.7 (2018-05-15)
diff -Nru pam-u2f-1.0.7/debian/patches/0001-Do-not-leak-file-descriptor-when-doing-exec.patch pam-u2f-1.0.7/debian/patches/0001-Do-not-leak-file-descriptor-when-doing-exec.patch
--- pam-u2f-1.0.7/debian/patches/0001-Do-not-leak-file-descriptor-when-doing-exec.patch	1970-01-01 01:00:00.000000000 +0100
+++ pam-u2f-1.0.7/debian/patches/0001-Do-not-leak-file-descriptor-when-doing-exec.patch	2019-07-20 13:29:57.000000000 +0200
@@ -0,0 +1,164 @@
+Subject: Do not leak file descriptor when doing exec
+
+When opening a custom debug file, the descriptor would stay
+open when calling exec and leak to the child process.
+
+Make sure all files are opened with close-on-exec.
+
+This fixes CVE-2019-12210.
+
+Thanks to Matthias Gerstner of the SUSE Security Team for reporting
+the issue.
+---
+ pam-u2f.c | 35 +++++++++++++++++++++++++----------
+ util.c    | 10 +++++++---
+ util.h    |  3 ++-
+ 3 files changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/pam-u2f.c b/pam-u2f.c
+index 55d5708..071d005 100644
+Origin: commit:18b1914e32b74ff52000f10e97067e841e5fff62
+Bug: 930023
+From: Gabriel Kihlman <g.kihlman@yubico.com>
+Reviewed-by: Nicolas Braud-Santoni <nicoo@debian.org>
+Last-Update: 2019-07-20
+Applied-Upstream: b0c6b7216f064e051c1dd42629ca062f721eea5f
+
+--- a/pam-u2f.c
++++ b/pam-u2f.c
+@@ -1,5 +1,5 @@
+ /*
+- *  Copyright (C) 2014-2018 Yubico AB - See COPYING
++ *  Copyright (C) 2014-2019 Yubico AB - See COPYING
+  */
+ 
+ /* Define which PAM interfaces we provide */
+@@ -31,7 +31,11 @@ char *secure_getenv(const char *name) {
+ #endif
+ 
+ static void parse_cfg(int flags, int argc, const char **argv, cfg_t *cfg) {
++  struct stat st;
++  FILE *file = NULL;
++  int fd = -1;
+   int i;
++
+   memset(cfg, 0, sizeof(cfg_t));
+   cfg->debug_file = stderr;
+ 
+@@ -76,14 +80,14 @@ static void parse_cfg(int flags, int argc, const char **argv, cfg_t *cfg) {
+         cfg->debug_file = (FILE *)-1;
+       }
+       else {
+-        struct stat st;
+-        FILE *file;
+-        if(lstat(filename, &st) == 0) {
+-          if(S_ISREG(st.st_mode)) {
+-            file = fopen(filename, "a");
+-            if(file != NULL) {
+-              cfg->debug_file = file;
+-            }
++        fd = open(filename, O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_NOCTTY);
++        if (fd >= 0 && (fstat(fd, &st) == 0) && S_ISREG(st.st_mode)) {
++          file = fdopen(fd, "a");
++          if(file != NULL) {
++            cfg->debug_file = file;
++            cfg->is_custom_debug_file = 1;
++            file = NULL;
++            fd = -1;
+           }
+         }
+       }
+@@ -111,6 +115,12 @@ static void parse_cfg(int flags, int argc, const char **argv, cfg_t *cfg) {
+     D(cfg->debug_file, "appid=%s", cfg->appid ? cfg->appid : "(null)");
+     D(cfg->debug_file, "prompt=%s", cfg->prompt ? cfg->prompt : "(null)");
+   }
++
++  if (fd != -1)
++    close(fd);
++
++  if (file != NULL)
++    fclose(file);
+ }
+ 
+ #ifdef DBG
+@@ -317,7 +327,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+     DBG("Using file '%s' for emitting touch request notifications", cfg->authpending_file);
+ 
+     // Open (or create) the authpending_file to indicate that we start waiting for a touch
+-    authpending_file_descriptor = open(cfg->authpending_file, O_RDONLY | O_CREAT, 0664);
++    authpending_file_descriptor =
++      open(cfg->authpending_file, O_RDONLY | O_CREAT | O_CLOEXEC | O_NOFOLLOW | O_NOCTTY, 0664);
+     if (authpending_file_descriptor < 0) {
+       DBG("Unable to emit 'authentication started' notification by opening the file '%s', (%s)",
+           cfg->authpending_file, strerror(errno));
+@@ -385,6 +396,10 @@ done:
+   }
+   DBG("done. [%s]", pam_strerror(pamh, retval));
+ 
++  if (cfg->is_custom_debug_file) {
++    fclose(cfg->debug_file);
++  }
++
+   return retval;
+ }
+ 
+diff --git a/util.c b/util.c
+index e7d8ecc..c17a0e6 100644
+--- a/util.c
++++ b/util.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2014-2018 Yubico AB - See COPYING
++ * Copyright (C) 2014-2019 Yubico AB - See COPYING
+  */
+ 
+ #include "util.h"
+@@ -36,7 +36,7 @@ int get_devices_from_authfile(const char *authfile, const char *username,
+   /* Ensure we never return uninitialized count. */
+   *n_devs = 0;
+ 
+-  fd = open(authfile, O_RDONLY, 0);
++  fd = open(authfile, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+   if (fd < 0) {
+     if (verbose)
+       D(debug_file, "Cannot open file: %s (%s)", authfile, strerror(errno));
+@@ -83,6 +83,8 @@ int get_devices_from_authfile(const char *authfile, const char *username,
+     if (verbose)
+       D(debug_file, "fdopen: %s", strerror(errno));
+     goto err;
++  } else {
++    fd = -1; /* fd belongs to opwfile */
+   }
+ 
+   buf = malloc(sizeof(char) * (DEVSIZE * max_devs));
+@@ -211,8 +213,10 @@ out:
+ 
+   if (opwfile)
+     fclose(opwfile);
+-  else if (fd >= 0)
++
++  if (fd != -1)
+     close(fd);
++
+   return retval;
+ }
+ 
+diff --git a/util.h b/util.h
+index 82c3542..d2e7a4d 100644
+--- a/util.h
++++ b/util.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2014-2018 Yubico AB - See COPYING
++ * Copyright (C) 2014-2019 Yubico AB - See COPYING
+  */
+ 
+ #ifndef UTIL_H
+@@ -45,6 +45,7 @@ typedef struct {
+   const char *appid;
+   const char *prompt;
+   FILE *debug_file;
++  int is_custom_debug_file;
+ } cfg_t;
+ 
+ typedef struct {
diff -Nru pam-u2f-1.0.7/debian/patches/0002-Drop-privileges-by-default-when-opening-user-related.patch pam-u2f-1.0.7/debian/patches/0002-Drop-privileges-by-default-when-opening-user-related.patch
--- pam-u2f-1.0.7/debian/patches/0002-Drop-privileges-by-default-when-opening-user-related.patch	1970-01-01 01:00:00.000000000 +0100
+++ pam-u2f-1.0.7/debian/patches/0002-Drop-privileges-by-default-when-opening-user-related.patch	2019-07-20 13:29:57.000000000 +0200
@@ -0,0 +1,407 @@
+Subject: Drop privileges by default when opening user-related files
+
+The module is typically executed as root and would sometimes
+open files or follow symlinks that could be controlled from the
+outside.
+
+Drop privileges to the target user before opening any files.
+
+Fixes CVE-2019-12209.
+
+Thanks to Matthias Gerstner of the SUSE Security Team for reporting
+the issue.
+---
+ Makefile.am  |   1 +
+ README       |  18 +++++++++
+ configure.ac |   4 ++
+ drop_privs.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ drop_privs.h |  64 +++++++++++++++++++++++++++++
+ pam-u2f.c    |  31 +++++++++-----
+ 6 files changed, 238 insertions(+), 9 deletions(-)
+ create mode 100644 drop_privs.c
+ create mode 100644 drop_privs.h
+
+diff --git a/Makefile.am b/Makefile.am
+index c0d2d1e..d761939 100644
+Origin: commit:7db3386fcdb454e33a3ea30dcfb8e8960d4c3aa3
+Bug: 930021
+From: Gabriel Kihlman <g.kihlman@yubico.com>
+Reviewed-by: Nicolas Braud-Santoni <nicoo@debian.org>
+Last-Update: 2019-07-20
+Applied-Upstream: b0c6b7216f064e051c1dd42629ca062f721eea5f
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -13,6 +13,7 @@ lib_LTLIBRARIES = pam_u2f.la
+ 
+ pam_u2f_la_SOURCES = pam-u2f.c
+ pam_u2f_la_SOURCES += util.c util.h
++pam_u2f_la_SOURCES += drop_privs.h drop_privs.c
+ 
+ pam_u2f_la_LIBADD = -lpam
+ pam_u2f_la_LIBADD += $(LIBU2FHOST_LIBS) $(LIBU2FSERVER_LIBS)
+diff --git a/README b/README
+index 1589f7e..ac2cae2 100644
+--- a/README
++++ b/README
+@@ -114,6 +114,8 @@ openasuser::
+ Setuid to the authenticating user when opening the authfile. Useful when the
+ user's home is stored on an NFS volume mounted with the root_squash option
+ (which maps root to nobody which will not be able to read the file).
++Note that after release 1.0.8 this is done by default when no global
++authfile or XDG_CONFIG_HOME environment variable has been set.
+ 
+ alwaysok::
+ Set to enable all authentication attempts to succeed (aka presentation mode).
+@@ -164,6 +166,11 @@ mappings will not be used and the opposite applies if user home directory
+ mappings are being used, the central authorization mappings file will not
+ be used.
+ 
++By default the mapping file inside a home directory will be opened as
++the target user, whereas the central file will be opened as `root`. If
++the `XDG_CONFIG_HOME` variable is set, privileges will not be dropped
++unless the `openasuser` configuration setting is set.
++
+ IMPORTANT: Using pam-u2f to secure the login to a computer while
+ storing the mapping file in an encrypted home directory, will result
+ in the impossibility of logging into the system. The partition is
+@@ -184,6 +191,10 @@ looks like:
+ 
+  auth sufficient pam_u2f.so authfile=/etc/u2f_mappings
+ 
++If you do not set the `openasuser` setting, the authfile will be opened
++and parsed as `root` so make sure it has the correct owner and
++permissions set.
++
+ IMPORTANT: On dynamics networks (e.g. where hostnames are set by DHCP),
+ users should not rely on the default origin and appid ("pam://$HOSTNAME")
+ but set those parameters explicitly to the same value.
+@@ -197,6 +208,13 @@ line:
+ 
+ This is much the same concept as the SSH authorized_keys file.
+ 
++In this case, pam-u2f will drop privileges and read the mapping file
++as that user. This happens regardless of the `openasuser` option being
++set.
++
++Note that if you set the XDG_CONFIG_HOME variable, privileges will not
++be dropped by default. Consider also setting `openasuser` in that case.
++
+ [[registration]]
+ Obtaining key-handles and public keys
+ -------------------------------------
+diff --git a/configure.ac b/configure.ac
+index 63be054..d4b090e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -37,6 +37,8 @@ AC_CHECK_HEADERS([security/pam_modules.h security/_pam_macros.h security/pam_mod
+    #include <security/pam_appl.h>])
+ AC_CHECK_LIB([pam], [pam_start])
+ 
++AC_SEARCH_LIBS([pam_modutil_drop_priv], ["pam"], [AC_DEFINE([HAVE_PAM_MODUTIL_DROP_PRIV], [1])])
++
+ case "$host" in
+      *darwin*)  PAMDIR="/usr/lib/pam";;
+      *linux*)   PAMDIR="/lib/x86_64-linux-gnu/security";;
+@@ -71,6 +73,8 @@ AC_ARG_VAR([CWFLAGS], [Warning flags])
+ AX_CHECK_COMPILE_FLAG([-Wall], [CWFLAGS="-Wall"])
+ AX_CHECK_COMPILE_FLAG([-Wextra], [CWFLAGS="$CWFLAGS -Wextra"])
+ AX_CHECK_COMPILE_FLAG([-Wconversion], [CWFLAGS="$CWFLAGS -Wconversion"])
++# Because pam headers are doing sign-conversion, see PAM_MODUTIL_DEF_PRIVS in pam_modutil.h
++AX_CHECK_COMPILE_FLAG([-Wconversion], [CWFLAGS="$CWFLAGS -Wno-sign-conversion"])
+ AX_CHECK_COMPILE_FLAG([-Wpedantic], [CWFLAGS="$CWFLAGS -Wpedantic"])
+ AX_CHECK_COMPILE_FLAG([-Wformat=2], [CWFLAGS="$CWFLAGS -Wformat=2"])
+ AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], [CWFLAGS="$CWFLAGS -Wstrict-prototypes"])
+diff --git a/drop_privs.c b/drop_privs.c
+new file mode 100644
+index 0000000..7fe35c5
+--- /dev/null
++++ b/drop_privs.c
+@@ -0,0 +1,129 @@
++/* Written by Ricky Zhou <ricky@fedoraproject.org>
++ * Fredrik Thulin <fredrik@yubico.com> implemented pam_modutil_drop_priv
++ *
++ * Copyright (c) 2011-2014 Yubico AB
++ * Copyright (c) 2011 Ricky Zhou <ricky@fedoraproject.org>
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are
++ * met:
++ *
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *
++ *     * Redistributions in binary form must reproduce the above
++ *       copyright notice, this list of conditions and the following
++ *       disclaimer in the documentation and/or other materials provided
++ *       with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#ifndef HAVE_PAM_MODUTIL_DROP_PRIV
++
++#include <unistd.h>
++#include <pwd.h>
++#include <grp.h>
++#include <errno.h>
++#include <string.h>
++#include <stdlib.h>
++
++#include "drop_privs.h"
++#include "util.h"
++
++#ifdef HAVE_SECURITY_PAM_APPL_H
++#include <security/pam_appl.h>
++#endif
++#ifdef HAVE_SECURITY_PAM_MODULES_H
++#include <security/pam_modules.h>
++#endif
++
++
++int pam_modutil_drop_priv(pam_handle_t *pamh, struct _ykpam_privs *privs, struct passwd *pw) {
++    privs->saved_euid = geteuid();
++    privs->saved_egid = getegid();
++
++    if ((privs->saved_euid == pw->pw_uid) && (privs->saved_egid == pw->pw_gid)) {
++        D (privs->debug_file, "Privilges already dropped, pretend it is all right");
++        return 0;
++    }
++
++    privs->saved_groups_length = getgroups(0, NULL);
++    if (privs->saved_groups_length < 0) {
++        D (privs->debug_file, "getgroups: %s", strerror(errno));
++        return -1;
++    }
++
++    if (privs->saved_groups_length > SAVED_GROUPS_MAX_LEN) {
++        D (privs->debug_file, "too many groups, limiting.");
++        privs->saved_groups_length = SAVED_GROUPS_MAX_LEN;
++    }
++
++    if (privs->saved_groups_length > 0) {
++        if (getgroups(privs->saved_groups_length, privs->saved_groups) < 0) {
++            D (privs->debug_file, "getgroups: %s", strerror(errno));
++            goto free_out;
++        }
++    }
++
++    if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
++        D (privs->debug_file, "initgroups: %s", strerror(errno));
++        goto free_out;
++    }
++
++    if (setegid(pw->pw_gid) < 0) {
++        D (privs->debug_file, "setegid: %s", strerror(errno));
++        goto free_out;
++    }
++
++    if (seteuid(pw->pw_uid) < 0) {
++        D (privs->debug_file, "seteuid: %s", strerror(errno));
++        goto free_out;
++    }
++
++    return 0;
++free_out:
++    return -1;
++}
++
++int pam_modutil_regain_priv(pam_handle_t *pamh, struct _ykpam_privs *privs) {
++    if ((privs->saved_euid == geteuid()) && (privs->saved_egid == getegid())) {
++        D (privs->debug_file, "Privilges already as requested, pretend it is all right");
++        return 0;
++    }
++
++    if (seteuid(privs->saved_euid) < 0) {
++        D (privs->debug_file, "seteuid: %s", strerror(errno));
++        return -1;
++    }
++
++    if (setegid(privs->saved_egid) < 0) {
++        D (privs->debug_file, "setegid: %s", strerror(errno));
++        return -1;
++    }
++
++    if (setgroups(privs->saved_groups_length, privs->saved_groups) < 0) {
++        D (privs->debug_file, "setgroups: %s", strerror(errno));
++        return -1;
++    }
++
++    return 0;
++}
++
++#else
++
++// drop_privs.c:124: warning: ISO C forbids an empty translation unit [-Wpedantic]
++typedef int make_iso_compilers_happy;
++
++#endif // HAVE_PAM_MODUTIL_DROP_PRIV
+diff --git a/drop_privs.h b/drop_privs.h
+new file mode 100644
+index 0000000..2d25a19
+--- /dev/null
++++ b/drop_privs.h
+@@ -0,0 +1,64 @@
++/* Copyright (c) 2011-2014 Yubico AB
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are
++ * met:
++ *
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *
++ *     * Redistributions in binary form must reproduce the above
++ *       copyright notice, this list of conditions and the following
++ *       disclaimer in the documentation and/or other materials provided
++ *       with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#ifndef __PAM_U2F_DROP_PRIVS_H_INCLUDED__
++#define __PAM_U2F_DROP_PRIVS_H_INCLUDED__
++
++#ifdef HAVE_PAM_MODUTIL_DROP_PRIV
++#include <security/pam_modutil.h>
++#else
++
++#include <pwd.h>
++#include <stdio.h>
++
++#ifdef HAVE_SECURITY_PAM_APPL_H
++#include <security/pam_appl.h>
++#endif
++#ifdef HAVE_SECURITY_PAM_MODULES_H
++#include <security/pam_modules.h>
++#endif
++
++#define SAVED_GROUPS_MAX_LEN 64 /* as pam_modutil.. */
++
++struct _ykpam_privs {
++  uid_t saved_euid;
++  gid_t saved_egid;
++  gid_t *saved_groups;
++  int saved_groups_length;
++  FILE *debug_file;
++};
++
++#define PAM_MODUTIL_DEF_PRIVS(n) \
++  gid_t n##_saved_groups[SAVED_GROUPS_MAX_LEN]; \
++  struct _ykpam_privs n = {-1, -1, n##_saved_groups, SAVED_GROUPS_MAX_LEN, cfg->debug_file}
++
++int pam_modutil_drop_priv(pam_handle_t *, struct _ykpam_privs *, struct passwd *);
++int pam_modutil_regain_priv(pam_handle_t *, struct _ykpam_privs *);
++
++#endif
++#endif
+diff --git a/pam-u2f.c b/pam-u2f.c
+index 071d005..b01697c 100644
+--- a/pam-u2f.c
++++ b/pam-u2f.c
+@@ -20,6 +20,7 @@
+ #include <errno.h>
+ 
+ #include "util.h"
++#include "drop_privs.h"
+ 
+ /* If secure_getenv is not defined, define it here */
+ #ifndef HAVE_SECURE_GETENV
+@@ -148,11 +149,12 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+   int retval = PAM_IGNORE;
+   device_t *devices = NULL;
+   unsigned n_devices = 0;
+-  int openasuser;
++  int openasuser = 0;
+   int should_free_origin = 0;
+   int should_free_appid = 0;
+   int should_free_auth_file = 0;
+   int should_free_authpending_file = 0;
++  PAM_MODUTIL_DEF_PRIVS(privs);
+ 
+   parse_cfg(flags, argc, argv, cfg);
+ 
+@@ -235,6 +237,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+         goto done;
+       }
+ 
++      /* Opening a file in a users $HOME, need to drop privs for security */
++      openasuser = geteuid() == 0 ? 1 : 0;
++
+       snprintf(buf, authfile_dir_len,
+                "%s/.config%s", pw->pw_dir, DEFAULT_AUTHFILE);
+     } else {
+@@ -250,9 +255,14 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ 
+       snprintf(buf, authfile_dir_len,
+                "%s%s", authfile_dir, DEFAULT_AUTHFILE);
++
++      if (!openasuser) {
++	DBG("WARNING: not dropping privileges when reading %s, please "
++	    "consider setting openasuser=1 in the module configuration", buf);
++      }
+     }
+ 
+-    DBG("Using default authentication file %s", buf);
++    DBG("Using authentication file %s", buf);
+ 
+     cfg->auth_file = buf; /* cfg takes ownership */
+     should_free_auth_file = 1;
+@@ -261,25 +271,28 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+     DBG("Using authentication file %s", cfg->auth_file);
+   }
+ 
+-  openasuser = geteuid() == 0 && cfg->openasuser;
++  if (!openasuser) {
++    openasuser = geteuid() == 0 && cfg->openasuser;
++  }
+   if (openasuser) {
+-    if (seteuid(pw_s.pw_uid)) {
+-      DBG("Unable to switch user to uid %i", pw_s.pw_uid);
++    DBG("Dropping privileges");
++    if (pam_modutil_drop_priv(pamh, &privs, pw)) {
++      DBG("Unable to switch user to uid %i", pw->pw_uid);
+       retval = PAM_IGNORE;
+       goto done;
+     }
+-    DBG("Switched to uid %i", pw_s.pw_uid);
++    DBG("Switched to uid %i", pw->pw_uid);
+   }
+   retval = get_devices_from_authfile(cfg->auth_file, user, cfg->max_devs,
+                                      cfg->debug, cfg->debug_file,
+                                      devices, &n_devices);
+   if (openasuser) {
+-    if (seteuid(0)) {
+-      DBG("Unable to switch back to uid 0");
++    if (pam_modutil_regain_priv(pamh, &privs)) {
++      DBG("could not restore privileges");
+       retval = PAM_IGNORE;
+       goto done;
+     }
+-    DBG("Switched back to uid 0");
++    DBG("Restored privileges");
+   }
+ 
+   if (retval != 1) {
diff -Nru pam-u2f-1.0.7/debian/patches/0003-Fix-out-of-bound-accesses.patch pam-u2f-1.0.7/debian/patches/0003-Fix-out-of-bound-accesses.patch
--- pam-u2f-1.0.7/debian/patches/0003-Fix-out-of-bound-accesses.patch	1970-01-01 01:00:00.000000000 +0100
+++ pam-u2f-1.0.7/debian/patches/0003-Fix-out-of-bound-accesses.patch	2019-07-20 13:29:57.000000000 +0200
@@ -0,0 +1,52 @@
+Subject: Fix out-of-bound accesses
+
+---
+ util.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/util.c b/util.c
+index c17a0e6..de48963 100644
+Origin: commit:aab0c31a3bfed8912a271685d6ec909f61380155
+From: Gabriel Kihlman <g.kihlman@yubico.com>
+Reviewed-by: Nicolas Braud-Santoni <nicoo@debian.org>
+Last-Update: 2019-07-20
+Applied-Upstream: b0c6b7216f064e051c1dd42629ca062f721eea5f
+
+--- a/util.c
++++ b/util.c
+@@ -97,8 +97,9 @@ int get_devices_from_authfile(const char *authfile, const char *username,
+   retval = -2;
+   while (fgets(buf, (int)(DEVSIZE * (max_devs - 1)), opwfile)) {
+     char *saveptr = NULL;
+-    if (buf[strlen(buf) - 1] == '\n')
+-      buf[strlen(buf) - 1] = '\0';
++    size_t len = strlen(buf);
++    if (len > 0 && buf[len - 1] == '\n')
++      buf[len - 1] = '\0';
+ 
+     if (verbose)
+       D(debug_file, "Authorization line: %s", buf);
+@@ -121,17 +122,17 @@ int get_devices_from_authfile(const char *authfile, const char *username,
+ 
+       i = 0;
+       while ((s_token = strtok_r(NULL, ",", &saveptr))) {
+-        devices[i].keyHandle = NULL;
+-        devices[i].publicKey = NULL;
+-
+-        if ((*n_devs)++ > MAX_DEVS - 1) {
+-          *n_devs = MAX_DEVS;
++        if ((*n_devs)++ > max_devs - 1) {
++          *n_devs = max_devs;
+           if (verbose)
+             D(debug_file, "Found more than %d devices, ignoring the remaining ones",
+-               MAX_DEVS);
++               max_devs);
+           break;
+         }
+ 
++        devices[i].keyHandle = NULL;
++        devices[i].publicKey = NULL;
++
+         if (verbose)
+           D(debug_file, "KeyHandle for device number %d: %s", i + 1, s_token);
+ 
diff -Nru pam-u2f-1.0.7/debian/patches/0004-Handle-malloc-failing-when-logging.patch pam-u2f-1.0.7/debian/patches/0004-Handle-malloc-failing-when-logging.patch
--- pam-u2f-1.0.7/debian/patches/0004-Handle-malloc-failing-when-logging.patch	1970-01-01 01:00:00.000000000 +0100
+++ pam-u2f-1.0.7/debian/patches/0004-Handle-malloc-failing-when-logging.patch	2019-07-20 13:29:57.000000000 +0200
@@ -0,0 +1,38 @@
+Subject: Handle malloc failing when logging
+
+If the size of string to log was bigger than BUFSIZE we use malloc
+but if malloc fails we should try and handle it gracefully by
+logging that we failed to allocate instead of segfaulting.
+---
+ util.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/util.c b/util.c
+index de48963..6e2b311 100644
+Origin: commit:525aacfb821e86ffef3c960ba13173dab825fd3c
+From: Gabriel Kihlman <g.kihlman@yubico.com>
+Reviewed-by: Nicolas Braud-Santoni <nicoo@debian.org>
+Last-Update: 2019-07-20
+Applied-Upstream: db86a442a624b9e13d9f833c518e92abf354827e
+
+--- a/util.c
++++ b/util.c
+@@ -565,9 +565,15 @@ void _debug(FILE *debug_file, const char *file, int line, const char *func, cons
+     out = malloc(size);
+   }
+ 
+-  size = (unsigned int)sprintf(out, DEBUG_STR, file, line, func);
+-  vsprintf(&out[size], fmt, ap);
+-  va_end(ap);
++  if (out) {
++    size = (unsigned int)sprintf(out, DEBUG_STR, file, line, func);
++    vsprintf(&out[size], fmt, ap);
++    va_end(ap);
++  }
++  else {
++    out = buffer;
++    sprintf(out, "debug(pam_u2f): malloc failed when trying to log\n");
++  }
+ 
+   if (debug_file == (FILE *)-1) {
+     syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", out);
diff -Nru pam-u2f-1.0.7/debian/patches/series pam-u2f-1.0.7/debian/patches/series
--- pam-u2f-1.0.7/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ pam-u2f-1.0.7/debian/patches/series	2019-07-20 13:29:57.000000000 +0200
@@ -0,0 +1,4 @@
+0001-Do-not-leak-file-descriptor-when-doing-exec.patch
+0002-Drop-privileges-by-default-when-opening-user-related.patch
+0003-Fix-out-of-bound-accesses.patch
+0004-Handle-malloc-failing-when-logging.patch

--- End Message ---
--- Begin Message ---
Version: 10.1

Hi,

The fixes referenced by each of these bugs were included in today's
buster point release.

Regards,

Adam

--- End Message ---

Reply to: