Bug#989509: buster-pu: package klibc/2.0.6-1+deb10u1
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: debian-kernel@lists.debian.org, mirabilos <tg@debian.org>
[ Reason ]
There are open security issues that were triaged as no-dsa by the
security team. These affect the heap functions (malloc and calloc)
and the cpio utility.
setjmp and longjmp are implemented incorrectly on s390x.
[ Impact ]
Some programs built using klibc may have potential heap overflows
that can be exploited for privilege escalation.
On s390x, programs using setjmp and longjmp may misbehave in
unpredictable ways.
[ Tests ]
malloc, calloc, setjmp, and longjmp are exercised by the test suite
that runs during build. However the setjmp/longjmp test was not
sufficient to detect the bug.
Thorsten Glaser tested the s390x fix in unstable. It has not (yet)
been manually tested in this version.
I have tested the cpio utility manually.
[ Risks ]
The changes are localised and seem comparatively low-risk to me.
[ Checklist ]
[X] *all* changes are documented in the d/changelog
[X] I reviewed all changes and I approve them
[X] attach debdiff against the package in (old)stable
[X] the issue is verified as fixed in unstable
[ Changes ]
All but one of the patches fixes a single bug or CVE as detailed in
its patch header.
The patch "malloc: Set errno on failure" is applied as a dependency
of "malloc: Fail if requested size > PTRDIFF_MAX".
[ Other info ]
diff -Nru klibc-2.0.6/debian/changelog klibc-2.0.6/debian/changelog
--- klibc-2.0.6/debian/changelog 2019-02-01 06:00:57.000000000 +0100
+++ klibc-2.0.6/debian/changelog 2021-06-05 20:20:42.000000000 +0200
@@ -1,3 +1,19 @@
+klibc (2.0.6-1+deb10u1) buster; urgency=medium
+
+ [ Ben Hutchings ]
+ * Apply security fixes from 2.0.9 (Closes: #989505):
+ - malloc: Set errno on failure
+ - malloc: Fail if requested size > PTRDIFF_MAX (CVE-2021-31873)
+ - calloc: Fail if multiplication overflows (CVE-2021-31870)
+ - cpio: Fix possible integer overflow on 32-bit systems (CVE-2021-31872)
+ - cpio: Fix possible crash on 64-bit systems (CVE-2021-31871)
+
+ [ Thorsten Glaser ]
+ * {set,long}jmp [s390x]: save/restore the correct FPU registers
+ (f8‥f15 not f1/f3/f5/f7) (Closes: #943425)
+
+ -- Ben Hutchings <benh@debian.org> Sat, 05 Jun 2021 20:20:42 +0200
+
klibc (2.0.6-1) unstable; urgency=medium
* New upstream version:
diff -Nru klibc-2.0.6/debian/patches/0035-klibc-malloc-Set-errno-on-failure.patch klibc-2.0.6/debian/patches/0035-klibc-malloc-Set-errno-on-failure.patch
--- klibc-2.0.6/debian/patches/0035-klibc-malloc-Set-errno-on-failure.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0035-klibc-malloc-Set-errno-on-failure.patch 2021-04-30 04:30:16.000000000 +0200
@@ -0,0 +1,32 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Apr 2021 03:57:39 +0200
+Subject: [klibc] malloc: Set errno on failure
+Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=7f6626d12daa2f1efd9953d1f4ba2065348dc5cd
+
+malloc() is specified to set errno = ENOMEM on failure, so do that.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ usr/klibc/malloc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/usr/klibc/malloc.c b/usr/klibc/malloc.c
+index 413b7337..bb57c9f6 100644
+--- a/usr/klibc/malloc.c
++++ b/usr/klibc/malloc.c
+@@ -8,6 +8,7 @@
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include <assert.h>
++#include <errno.h>
+ #include "malloc.h"
+
+ /* Both the arena list and the free memory list are double linked
+@@ -169,6 +170,7 @@ void *malloc(size_t size)
+ #endif
+
+ if (fp == (struct free_arena_header *)MAP_FAILED) {
++ errno = ENOMEM;
+ return NULL; /* Failed to get a block */
+ }
+
diff -Nru klibc-2.0.6/debian/patches/0036-klibc-malloc-Fail-if-requested-size-PTRDIFF_MAX.patch klibc-2.0.6/debian/patches/0036-klibc-malloc-Fail-if-requested-size-PTRDIFF_MAX.patch
--- klibc-2.0.6/debian/patches/0036-klibc-malloc-Fail-if-requested-size-PTRDIFF_MAX.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0036-klibc-malloc-Fail-if-requested-size-PTRDIFF_MAX.patch 2021-04-30 04:30:16.000000000 +0200
@@ -0,0 +1,41 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Apr 2021 04:03:49 +0200
+Subject: [klibc] malloc: Fail if requested size > PTRDIFF_MAX
+Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=a31ae8c508fc8d1bca4f57e9f9f88127572d5202
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-31873
+
+malloc() adds some overhead to the requested size, which may result in
+an integer overflow and subsequent buffer overflow if it is close to
+SIZE_MAX. It should fail if size is large enough for this to happen.
+
+Further, it's not legal for a C object to be larger than
+PTRDIFF_MAX (half of SIZE_MAX) as pointer arithmetic within it could
+overflow. So return failure immediately if size is greater than that.
+
+CVE-2021-31873
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ usr/klibc/malloc.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/usr/klibc/malloc.c b/usr/klibc/malloc.c
+index bb57c9f6..abda84c2 100644
+--- a/usr/klibc/malloc.c
++++ b/usr/klibc/malloc.c
+@@ -147,6 +147,15 @@ void *malloc(size_t size)
+ if (size == 0)
+ return NULL;
+
++ /* Various additions below will overflow if size is close to
++ SIZE_MAX. Further, it's not legal for a C object to be
++ larger than PTRDIFF_MAX (half of SIZE_MAX) as pointer
++ arithmetic within it could overflow. */
++ if (size > PTRDIFF_MAX) {
++ errno = ENOMEM;
++ return NULL;
++ }
++
+ /* Add the obligatory arena header, and round up */
+ size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
+
diff -Nru klibc-2.0.6/debian/patches/0037-klibc-calloc-Fail-if-multiplication-overflows.patch klibc-2.0.6/debian/patches/0037-klibc-calloc-Fail-if-multiplication-overflows.patch
--- klibc-2.0.6/debian/patches/0037-klibc-calloc-Fail-if-multiplication-overflows.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0037-klibc-calloc-Fail-if-multiplication-overflows.patch 2021-04-30 04:30:16.000000000 +0200
@@ -0,0 +1,43 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Apr 2021 04:29:50 +0200
+Subject: [klibc] calloc: Fail if multiplication overflows
+Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=292650f04c2b5348b4efbad61fb014ed09b4f3f2
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-31870
+
+calloc() multiplies its 2 arguments together and passes the result to
+malloc(). Since the factors and product both have type size_t, this
+can result in an integer overflow and subsequent buffer overflow.
+Check for this and fail if it happens.
+
+CVE-2021-31870
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ usr/klibc/calloc.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/usr/klibc/calloc.c b/usr/klibc/calloc.c
+index 53dcc6b2..4a81cda1 100644
+--- a/usr/klibc/calloc.c
++++ b/usr/klibc/calloc.c
+@@ -2,12 +2,17 @@
+ * calloc.c
+ */
+
++#include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+-/* FIXME: This should look for multiplication overflow */
+-
+ void *calloc(size_t nmemb, size_t size)
+ {
+- return zalloc(nmemb * size);
++ unsigned long prod;
++
++ if (__builtin_umull_overflow(nmemb, size, &prod)) {
++ errno = ENOMEM;
++ return NULL;
++ }
++ return zalloc(prod);
+ }
diff -Nru klibc-2.0.6/debian/patches/0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch klibc-2.0.6/debian/patches/0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch
--- klibc-2.0.6/debian/patches/0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch 2021-04-30 04:30:16.000000000 +0200
@@ -0,0 +1,68 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Apr 2021 05:16:34 +0200
+Subject: [klibc] cpio: Fix possible integer overflow on 32-bit systems
+Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=9b1c91577aef7f2e72c3aa11a27749160bd278ff
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-31872
+
+The maximum name and file sizes in the "new" header format are 32-bit
+unsigned values. However, the I/O functions mostly use long for sizes
+and offsets, so that sizes >= 2^31 are handled wrongly on 32-bit
+systems.
+
+The current GNU cpio code doesn't seem to have this problem, but the
+divergence between this version and that is large enough that I can't
+simply cherry-pick a fix for it.
+
+As a short-term fix, in read_in_new_ascii(), fail if c_namesize or
+c_filesize is > LONG_MAX.
+
+CVE-2021-31872
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ usr/utils/cpio.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/usr/utils/cpio.c b/usr/utils/cpio.c
+index cb616791..ac481310 100644
+--- a/usr/utils/cpio.c
++++ b/usr/utils/cpio.c
+@@ -17,6 +17,7 @@
+
+ #include <errno.h>
+ #include <fcntl.h>
++#include <limits.h>
+ #include <malloc.h>
+ #include <stdbool.h>
+ #include <stdio.h>
+@@ -904,6 +905,15 @@ static void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des)
+ file_hdr->c_hdr[i] = strtoul(hexbuf, NULL, 16);
+ ah += 8;
+ }
++
++ /* Sizes > LONG_MAX can currently result in integer overflow
++ in various places. Fail if name is too large. */
++ if (file_hdr->c_namesize > LONG_MAX) {
++ fprintf(stderr, "%s: name size out of range\n",
++ progname);
++ exit(1);
++ }
++
+ /* Read file name from input. */
+ free(file_hdr->c_name);
+ file_hdr->c_name = (char *)xmalloc(file_hdr->c_namesize);
+@@ -914,6 +924,14 @@ static void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des)
+ is rounded up to the next long-word, so we might need to drop
+ 1-3 bytes. */
+ tape_skip_padding(in_des, file_hdr->c_namesize + 110);
++
++ /* Fail if file is too large. We could check this earlier
++ but it's helpful to report the name. */
++ if (file_hdr->c_filesize > LONG_MAX) {
++ fprintf(stderr, "%s: %s: file size out of range\n",
++ progname, file_hdr->c_name);
++ exit(1);
++ }
+ }
+
+ /* Return 16-bit integer I with the bytes swapped. */
diff -Nru klibc-2.0.6/debian/patches/0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch klibc-2.0.6/debian/patches/0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch
--- klibc-2.0.6/debian/patches/0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch 2021-04-30 04:30:16.000000000 +0200
@@ -0,0 +1,32 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 28 Apr 2021 19:46:47 +0200
+Subject: [klibc] cpio: Fix possible crash on 64-bit systems
+Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=2e48a12ab1e30d43498c2d53e878a11a1b5102d5
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-31871
+
+copyin_link() tries to allocate (unsigned int)c_filesize + 1 bytes.
+If c_filesize == UINT_MAX, this works out as 0 bytes, resulting in a
+null pointer and a subsequent SIGSEGV.
+
+The previous commit made this impossible on 32-bit systems.
+
+CVE-2021-31871
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ usr/utils/cpio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/usr/utils/cpio.c b/usr/utils/cpio.c
+index ac481310..9b0b6ae9 100644
+--- a/usr/utils/cpio.c
++++ b/usr/utils/cpio.c
+@@ -832,7 +832,7 @@ static void copyin_link(struct new_cpio_header *file_hdr, int in_file_des)
+ char *link_name = NULL; /* Name of hard and symbolic links. */
+ int res; /* Result of various function calls. */
+
+- link_name = (char *)xmalloc((unsigned int)file_hdr->c_filesize + 1);
++ link_name = (char *)xmalloc(file_hdr->c_filesize + 1);
+ link_name[file_hdr->c_filesize] = '\0';
+ tape_buffered_read(link_name, in_file_des, file_hdr->c_filesize);
+ tape_skip_padding(in_file_des, file_hdr->c_filesize);
diff -Nru klibc-2.0.6/debian/patches/0041-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch klibc-2.0.6/debian/patches/0041-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch
--- klibc-2.0.6/debian/patches/0041-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch 1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.6/debian/patches/0041-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch 2021-06-05 20:19:52.000000000 +0200
@@ -0,0 +1,57 @@
+Description: {set,long}jmp [s390x]: save/restore the correct registers
+ The s390x ABI actually has FPU registers f8‥f15, not f1/f3/f5/f7,
+ to be saved. (Closes: Debian #943425)
+Author: mirabilos <tg@debian.org>
+Forwarded: https://lists.zytor.com/archives/klibc/2021-May/004620.html
+
+--- a/usr/include/arch/s390/klibc/archsetjmp.h
++++ b/usr/include/arch/s390/klibc/archsetjmp.h
+@@ -16,7 +16,7 @@ struct __jmp_buf {
+
+ struct __jmp_buf {
+ uint64_t __gregs[10]; /* general registers r6-r15 */
+- uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */
++ uint64_t __fpregs[8]; /* fp registers f8-f15 */
+ };
+
+ #endif /* __s390x__ */
+--- a/usr/klibc/arch/s390/setjmp.S
++++ b/usr/klibc/arch/s390/setjmp.S
+@@ -38,10 +38,14 @@ longjmp:
+
+ setjmp:
+ stmg %r6,%r15,0(%r2) # save all general registers
+- std %f1,80(%r2) # save fp registers f4 and f6
+- std %f3,88(%r2)
+- std %f5,96(%r2)
+- std %f7,104(%r2)
++ std %f8,80(%r2) # save fp registers f8 to f15
++ std %f9,88(%r2)
++ std %f10,96(%r2)
++ std %f11,104(%r2)
++ std %f12,112(%r2)
++ std %f13,120(%r2)
++ std %f14,128(%r2)
++ std %f15,136(%r2)
+ lghi %r2,0 # return 0
+ br %r14
+
+@@ -54,10 +58,14 @@ setjmp:
+ longjmp:
+ lgr %r1,%r2 # jmp_buf
+ lgr %r2,%r3 # return value
+- ld %f7,104(%r1) # restore all saved registers
+- ld %f5,96(%r1)
+- ld %f3,88(%r1)
+- ld %f1,80(%r1)
++ ld %f15,136(%r1) # restore all saved registers
++ ld %f14,128(%r1)
++ ld %f13,120(%r1)
++ ld %f12,112(%r1)
++ ld %f11,104(%r1)
++ ld %f10,96(%r1)
++ ld %f9,88(%r1)
++ ld %f8,80(%r1)
+ lmg %r6,%r15,0(%r1)
+ br %r14 # return to restored address
+
diff -Nru klibc-2.0.6/debian/patches/series klibc-2.0.6/debian/patches/series
--- klibc-2.0.6/debian/patches/series 2019-02-01 06:00:06.000000000 +0100
+++ klibc-2.0.6/debian/patches/series 2021-06-05 20:19:52.000000000 +0200
@@ -1 +1,7 @@
resume-backward-compatibility-for-resume_offset.patch
+0035-klibc-malloc-Set-errno-on-failure.patch
+0036-klibc-malloc-Fail-if-requested-size-PTRDIFF_MAX.patch
+0037-klibc-calloc-Fail-if-multiplication-overflows.patch
+0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch
+0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch
+0041-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch
Reply to: