diff -Nru sysstat-11.6.1/debian/changelog sysstat-11.6.1/debian/changelog --- sysstat-11.6.1/debian/changelog 2020-01-17 11:24:09.000000000 +0000 +++ sysstat-11.6.1/debian/changelog 2022-11-25 18:19:17.000000000 +0000 @@ -1,3 +1,17 @@ +sysstat (11.6.1-1ubuntu0.2) bionic-security; urgency=medium + + * SECURITY UPDATE: overflow in arithmetic multiplication + - debian/patches/CVE-2022-39377-1.patch: fix size_t overflow in + common.c, common.h, sa_common.c. + - debian/patches/CVE-2022-39377-2.patch: add more overflow checks in + common.c, common.h, sa_common.c, sadc.c. + - debian/patches/CVE-2022-39377-3.patch: make sure values to be + compared are unsigned integers in common.c, common.h, sa_common.c, + sadc.c. + - CVE-2022-39377 + + -- Marc Deslauriers Fri, 25 Nov 2022 13:19:17 -0500 + sysstat (11.6.1-1ubuntu0.1) bionic-security; urgency=medium * SECURITY UPDATE: double free diff -Nru sysstat-11.6.1/debian/patches/CVE-2022-39377-1.patch sysstat-11.6.1/debian/patches/CVE-2022-39377-1.patch --- sysstat-11.6.1/debian/patches/CVE-2022-39377-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ sysstat-11.6.1/debian/patches/CVE-2022-39377-1.patch 2022-11-25 18:14:18.000000000 +0000 @@ -0,0 +1,80 @@ +Backport of: + +From 9c4eaf150662ad40607923389d4519bc83b93540 Mon Sep 17 00:00:00 2001 +From: Sebastien +Date: Sat, 15 Oct 2022 14:24:22 +0200 +Subject: [PATCH] Fix size_t overflow in sa_common.c (GHSL-2022-074) + +allocate_structures function located in sa_common.c insufficiently +checks bounds before arithmetic multiplication allowing for an +overflow in the size allocated for the buffer representing system +activities. + +This patch checks that the post-multiplied value is not greater than +UINT_MAX. + +Signed-off-by: Sebastien +--- + common.c | 25 +++++++++++++++++++++++++ + common.h | 2 ++ + sa_common.c | 6 ++++++ + 3 files changed, 33 insertions(+) + +--- a/common.c ++++ b/common.c +@@ -1491,3 +1491,28 @@ int parse_values(char *strargv, unsigned + + return 0; + } ++ ++/* ++ *************************************************************************** ++ * Check if the multiplication of the 3 values may be greater than UINT_MAX. ++ * ++ * IN: ++ * @val1 First value. ++ * @val2 Second value. ++ * @val3 Third value. ++ *************************************************************************** ++ */ ++void check_overflow(size_t val1, size_t val2, size_t val3) ++{ ++ if ((unsigned long long) val1 * ++ (unsigned long long) val2 * ++ (unsigned long long) val3 > UINT_MAX) { ++#ifdef DEBUG ++ fprintf(stderr, "%s: Overflow detected (%llu). Aborting...\n", ++ __FUNCTION__, ++ (unsigned long long) val1 * (unsigned long long) val2 * (unsigned long long) val3); ++#endif ++ exit(4); ++ } ++} ++ +--- a/common.h ++++ b/common.h +@@ -233,6 +233,8 @@ struct ext_disk_stats { + void compute_ext_disk_stats + (struct stats_disk *, struct stats_disk *, unsigned long long, + struct ext_disk_stats *); ++void check_overflow ++ (size_t, size_t, size_t); + int count_bits + (void *, int); + int count_csvalues +--- a/sa_common.c ++++ b/sa_common.c +@@ -62,7 +62,13 @@ void allocate_structures(struct activity + int i, j; + + for (i = 0; i < NR_ACT; i++) { ++ + if (act[i]->nr > 0) { ++ ++ /* Look for a possible overflow */ ++ check_overflow((size_t) act[i]->msize, (size_t) act[i]->nr, ++ (size_t) act[i]->nr2); ++ + for (j = 0; j < 3; j++) { + SREALLOC(act[i]->buf[j], void, + (size_t) act[i]->msize * (size_t) act[i]->nr * (size_t) act[i]->nr2); diff -Nru sysstat-11.6.1/debian/patches/CVE-2022-39377-2.patch sysstat-11.6.1/debian/patches/CVE-2022-39377-2.patch --- sysstat-11.6.1/debian/patches/CVE-2022-39377-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ sysstat-11.6.1/debian/patches/CVE-2022-39377-2.patch 2022-11-25 18:19:17.000000000 +0000 @@ -0,0 +1,101 @@ +Backport of: + +From c9a11d35df4aecfcf22aef827bac6cd57def9d4e Mon Sep 17 00:00:00 2001 +From: Sebastien GODARD +Date: Sun, 23 Oct 2022 16:22:28 +0200 +Subject: [PATCH] Add more overflow checks + +Signed-off-by: Sebastien GODARD +--- + common.c | 45 +++++++++++++++++++++------------------------ + common.h | 4 ++-- + sa_common.c | 9 +++++++-- + sadc.c | 6 ++++++ + 4 files changed, 36 insertions(+), 28 deletions(-) + +--- a/common.c ++++ b/common.c +@@ -1493,7 +1493,7 @@ int parse_values(char *strargv, unsigned + } + + /* +- *************************************************************************** ++ * ************************************************************************** + * Check if the multiplication of the 3 values may be greater than UINT_MAX. + * + * IN: +@@ -1502,17 +1502,15 @@ int parse_values(char *strargv, unsigned + * @val3 Third value. + *************************************************************************** + */ +-void check_overflow(size_t val1, size_t val2, size_t val3) ++void check_overflow(unsigned long long val1, unsigned long long val2, ++ unsigned long long val3) + { +- if ((unsigned long long) val1 * +- (unsigned long long) val2 * +- (unsigned long long) val3 > UINT_MAX) { ++ if (val1 * val2 * val3 > UINT_MAX) { + #ifdef DEBUG + fprintf(stderr, "%s: Overflow detected (%llu). Aborting...\n", +- __FUNCTION__, +- (unsigned long long) val1 * (unsigned long long) val2 * (unsigned long long) val3); ++ __FUNCTION__, val1 * val2 * val3); + #endif + exit(4); +- } ++ } + } + +--- a/common.h ++++ b/common.h +@@ -234,7 +234,7 @@ void compute_ext_disk_stats + (struct stats_disk *, struct stats_disk *, unsigned long long, + struct ext_disk_stats *); + void check_overflow +- (size_t, size_t, size_t); ++ (unsigned long long, unsigned long long, unsigned long long); + int count_bits + (void *, int); + int count_csvalues +--- a/sa_common.c ++++ b/sa_common.c +@@ -66,8 +66,9 @@ void allocate_structures(struct activity + if (act[i]->nr > 0) { + + /* Look for a possible overflow */ +- check_overflow((size_t) act[i]->msize, (size_t) act[i]->nr, +- (size_t) act[i]->nr2); ++ check_overflow((unsigned long long) act[i]->msize, ++ (unsigned long long) act[i]->nr, ++ (unsigned long long) act[i]->nr2); + + for (j = 0; j < 3; j++) { + SREALLOC(act[i]->buf[j], void, +@@ -1438,6 +1439,11 @@ int reallocate_vol_act_structures(struct + + act[p]->nr = act_nr; + ++ /* Look for a possible overflow */ ++ check_overflow((unsigned long long) act[p]->msize, ++ (unsigned long long) act[p]->nr, ++ (unsigned long long) act[p]->nr2); ++ + for (j = 0; j < 3; j++) { + SREALLOC(act[p]->buf[j], void, + (size_t) act[p]->msize * (size_t) act[p]->nr * (size_t) act[p]->nr2); +--- a/sadc.c ++++ b/sadc.c +@@ -334,6 +334,12 @@ void sa_sys_init(void) + } + + if (act[i]->nr > 0) { ++ ++ /* Look for a possible overflow */ ++ check_overflow((unsigned long long) act[i]->msize, ++ (unsigned long long) act[i]->nr, ++ (unsigned long long) act[i]->nr2); ++ + /* Allocate structures for current activity */ + SREALLOC(act[i]->_buf0, void, + (size_t) act[i]->msize * (size_t) act[i]->nr * (size_t) act[i]->nr2); diff -Nru sysstat-11.6.1/debian/patches/CVE-2022-39377-3.patch sysstat-11.6.1/debian/patches/CVE-2022-39377-3.patch --- sysstat-11.6.1/debian/patches/CVE-2022-39377-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ sysstat-11.6.1/debian/patches/CVE-2022-39377-3.patch 2022-11-25 18:19:17.000000000 +0000 @@ -0,0 +1,94 @@ +Backport of: + +From 44f1dc159242c1e434a3b836cda49f084c5a96cc Mon Sep 17 00:00:00 2001 +From: Sebastien GODARD +Date: Sun, 6 Nov 2022 15:48:16 +0100 +Subject: [PATCH] Make sure values to be compared are unsigned integers + +It seems safer to make sure that input values are unsigned int before +casting them to unsigned long long and making the comparison. + +Signed-off-by: Sebastien GODARD +--- + common.c | 10 ++++++---- + common.h | 2 +- + sa_common.c | 10 +++++----- + sadc.c | 6 +++--- + 4 files changed, 15 insertions(+), 13 deletions(-) + +--- a/common.c ++++ b/common.c +@@ -1502,13 +1502,15 @@ int parse_values(char *strargv, unsigned + * @val3 Third value. + *************************************************************************** + */ +-void check_overflow(unsigned long long val1, unsigned long long val2, +- unsigned long long val3) ++void check_overflow(unsigned int val1, unsigned int val2, ++ unsigned int val3) + { +- if (val1 * val2 * val3 > UINT_MAX) { ++ if ((unsigned long long) val1 * (unsigned long long) val2 * ++ (unsigned long long) val3 > UINT_MAX) { + #ifdef DEBUG + fprintf(stderr, "%s: Overflow detected (%llu). Aborting...\n", +- __FUNCTION__, val1 * val2 * val3); ++ __FUNCTION__, (unsigned long long) val1 * (unsigned long long) val2 * ++ (unsigned long long) val3); + #endif + exit(4); + } +--- a/common.h ++++ b/common.h +@@ -234,7 +234,7 @@ void compute_ext_disk_stats + (struct stats_disk *, struct stats_disk *, unsigned long long, + struct ext_disk_stats *); + void check_overflow +- (unsigned long long, unsigned long long, unsigned long long); ++ (unsigned int, unsigned int, unsigned int); + int count_bits + (void *, int); + int count_csvalues +--- a/sa_common.c ++++ b/sa_common.c +@@ -66,9 +66,9 @@ void allocate_structures(struct activity + if (act[i]->nr > 0) { + + /* Look for a possible overflow */ +- check_overflow((unsigned long long) act[i]->msize, +- (unsigned long long) act[i]->nr, +- (unsigned long long) act[i]->nr2); ++ check_overflow((unsigned int) act[i]->msize, ++ (unsigned int) act[i]->nr, ++ (unsigned int) act[i]->nr2); + + for (j = 0; j < 3; j++) { + SREALLOC(act[i]->buf[j], void, +@@ -1440,9 +1440,9 @@ int reallocate_vol_act_structures(struct + act[p]->nr = act_nr; + + /* Look for a possible overflow */ +- check_overflow((unsigned long long) act[p]->msize, +- (unsigned long long) act[p]->nr, +- (unsigned long long) act[p]->nr2); ++ check_overflow((unsigned int) act[p]->msize, ++ (unsigned int) act[p]->nr, ++ (unsigned int) act[p]->nr2); + + for (j = 0; j < 3; j++) { + SREALLOC(act[p]->buf[j], void, +--- a/sadc.c ++++ b/sadc.c +@@ -336,9 +336,9 @@ void sa_sys_init(void) + if (act[i]->nr > 0) { + + /* Look for a possible overflow */ +- check_overflow((unsigned long long) act[i]->msize, +- (unsigned long long) act[i]->nr, +- (unsigned long long) act[i]->nr2); ++ check_overflow((unsigned int) act[i]->msize, ++ (unsigned int) act[i]->nr, ++ (unsigned int) act[i]->nr2); + + /* Allocate structures for current activity */ + SREALLOC(act[i]->_buf0, void, diff -Nru sysstat-11.6.1/debian/patches/series sysstat-11.6.1/debian/patches/series --- sysstat-11.6.1/debian/patches/series 2020-01-17 11:23:39.000000000 +0000 +++ sysstat-11.6.1/debian/patches/series 2022-11-25 18:17:27.000000000 +0000 @@ -6,3 +6,6 @@ 06-exec.patch 08-scripts.patch CVE-2019-19725.patch +CVE-2022-39377-1.patch +CVE-2022-39377-2.patch +CVE-2022-39377-3.patch