Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: debian-ker...@lists.debian.org, mirabilos <t...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <b...@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 <t...@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