From ae44e11d4615aced6b1216685c999accfa29c626 Mon Sep 17 00:00:00 2001 From: zhaoyuxing Date: Fri, 17 Sep 2021 09:01:52 +0800 Subject: [PATCH] fix memory leak --- ...e-the-module-import-list-on-the-heap.patch | 43 ++++++++++ ...mory-leak-in-a-MIB-parser-error-path.patch | 81 +++++++++++++++++++ ...-undefined-behavior-in-asn_build_int.patch | 29 +++++++ ...rt-libsnmp-Fix-the-getoid-error-path.patch | 33 ++++++++ ...-undefined-behavior-in-asn_build_int.patch | 29 +++++++ backport-libsnmp-Increase-MAX_IMPORTS.patch | 30 +++++++ backport-libsnmp-Rework-parse_imports.patch | 77 ++++++++++++++++++ net-snmp.spec | 20 ++++- 8 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 backport-libsnmp-Allocate-the-module-import-list-on-the-heap.patch create mode 100644 backport-libsnmp-Fix-a-memory-leak-in-a-MIB-parser-error-path.patch create mode 100644 backport-libsnmp-Fix-more-undefined-behavior-in-asn_build_int.patch create mode 100644 backport-libsnmp-Fix-the-getoid-error-path.patch create mode 100644 backport-libsnmp-Fix-undefined-behavior-in-asn_build_int.patch create mode 100644 backport-libsnmp-Increase-MAX_IMPORTS.patch create mode 100644 backport-libsnmp-Rework-parse_imports.patch diff --git a/backport-libsnmp-Allocate-the-module-import-list-on-the-heap.patch b/backport-libsnmp-Allocate-the-module-import-list-on-the-heap.patch new file mode 100644 index 0000000..2602178 --- /dev/null +++ b/backport-libsnmp-Allocate-the-module-import-list-on-the-heap.patch @@ -0,0 +1,43 @@ +From e34f0793b641998eb4f9bedb4f7929bb0e3051b8 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 6 Sep 2020 15:13:58 -0700 +Subject: [PATCH] libsnmp: Allocate the module import list on the heap + +Since that list occupies 8 KiB, allocate it on the heap instead of on the +stack. +--- + snmplib/parse.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/snmplib/parse.c b/snmplib/parse.c +index 27b37a1..e1609cc 100644 +--- a/snmplib/parse.c ++++ b/snmplib/parse.c +@@ -3637,13 +3637,15 @@ parse_imports(FILE * fp) + char token[MAXTOKEN]; + char modbuf[256]; + #define MAX_IMPORTS 512 +- struct module_import import_list[MAX_IMPORTS]; ++ struct module_import *import_list; + int this_module; + struct module *mp; + + int import_count = 0; /* Total number of imported descriptors */ + int i = 0, old_i; /* index of first import from each module */ + ++ import_list = malloc(MAX_IMPORTS * sizeof(*import_list)); ++ + type = get_token(fp, token, MAXTOKEN); + + /* +@@ -3732,6 +3734,7 @@ parse_imports(FILE * fp) + print_module_not_found(module_name(current_module, modbuf)); + + out: ++ free(import_list); + return; + } + +-- +1.8.3.1 + diff --git a/backport-libsnmp-Fix-a-memory-leak-in-a-MIB-parser-error-path.patch b/backport-libsnmp-Fix-a-memory-leak-in-a-MIB-parser-error-path.patch new file mode 100644 index 0000000..c885926 --- /dev/null +++ b/backport-libsnmp-Fix-a-memory-leak-in-a-MIB-parser-error-path.patch @@ -0,0 +1,81 @@ +From d0277ca1ccd6ec8d786355a433717a9dbf41112e Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sat, 7 Aug 2021 08:32:03 -0700 +Subject: [PATCH] libsnmp: Fix a memory leak in a MIB parser error path + +This patch should fix +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36879. +--- + snmplib/parse.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/snmplib/parse.c b/snmplib/parse.c +index 6d9d84a..5eb675b 100644 +--- a/snmplib/parse.c ++++ b/snmplib/parse.c +@@ -1865,18 +1865,22 @@ do_linkup(struct module *mp, struct node *np) + } + + +-/* ++/** ++ * Read an OID from a file. ++ * @param[in] file File to read from. ++ * @param[out] id_arg Array to store the OID in. ++ * @param[in] length Number of elements in the @id_arg array. ++ * + * Takes a list of the form: + * { iso org(3) dod(6) 1 } + * and creates several nodes, one for each parent-child pair. + * Returns 0 on error. + */ + static int +-getoid(FILE * fp, struct subid_s *id, /* an array of subids */ +- int length) +-{ /* the length of the array */ +- register int count; +- int type; ++getoid(FILE * fp, struct subid_s *id_arg, int length) ++{ ++ struct subid_s *id = id_arg; ++ int i, count, type; + char token[MAXTOKEN]; + + if ((type = get_token(fp, token, MAXTOKEN)) != LEFTBRACKET) { +@@ -1904,11 +1908,11 @@ getoid(FILE * fp, struct subid_s *id, /* an array of subids */ + get_token(fp, token, MAXTOKEN)) != RIGHTPAREN) { + print_error("Expected a closing parenthesis", + token, type); +- return 0; ++ goto free_labels; + } + } else { + print_error("Expected a number", token, type); +- return 0; ++ goto free_labels; + } + } else { + continue; +@@ -1920,11 +1924,18 @@ getoid(FILE * fp, struct subid_s *id, /* an array of subids */ + id->subid = strtoul(token, NULL, 10); + } else { + print_error("Expected label or number", token, type); +- return 0; ++ goto free_labels; + } + type = get_token(fp, token, MAXTOKEN); + } + print_error("Too long OID", token, type); ++ ++free_labels: ++ for (i = 0; i < count; i++) { ++ free(id[i].label); ++ id[i].label = NULL; ++ } ++ + return 0; + } + +-- +1.8.3.1 + diff --git a/backport-libsnmp-Fix-more-undefined-behavior-in-asn_build_int.patch b/backport-libsnmp-Fix-more-undefined-behavior-in-asn_build_int.patch new file mode 100644 index 0000000..6a362ad --- /dev/null +++ b/backport-libsnmp-Fix-more-undefined-behavior-in-asn_build_int.patch @@ -0,0 +1,29 @@ +From b9308221b1d0c1f77c8b2511e196376dc2870211 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 29 Aug 2021 09:25:06 -0700 +Subject: [PATCH] libsnmp: Fix more undefined behavior in asn_build_int() + +According to the C standard, triggering an overflow by shifting a signed +integer left results in undefined behavior. Fix this by inserting a cast. + +Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=37808 +--- + snmplib/asn1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/snmplib/asn1.c b/snmplib/asn1.c +index 959ae21..07bdcc6 100644 +--- a/snmplib/asn1.c ++++ b/snmplib/asn1.c +@@ -771,7 +771,7 @@ asn_build_int(u_char * data, + while ((((integer & mask) == 0) || ((integer & mask) == mask)) + && intsize > 1) { + intsize--; +- integer <<= 8; ++ integer = (u_long)integer << 8; + } + data = asn_build_header(data, datalength, type, intsize); + if (_asn_build_header_check(errpre, data, *datalength, intsize)) +-- +1.8.3.1 + diff --git a/backport-libsnmp-Fix-the-getoid-error-path.patch b/backport-libsnmp-Fix-the-getoid-error-path.patch new file mode 100644 index 0000000..001053f --- /dev/null +++ b/backport-libsnmp-Fix-the-getoid-error-path.patch @@ -0,0 +1,33 @@ +From 413b17eecd6af8e8247501805b5a366b709828bf Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Mon, 9 Aug 2021 14:07:20 -0700 +Subject: [PATCH] libsnmp: Fix the getoid() error path + +Fixes: d0277ca1ccd6 ("libsnmp: Fix a memory leak in a MIB parser error path") +--- + snmplib/parse.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/snmplib/parse.c b/snmplib/parse.c +index 5eb675b..19ccc0f 100644 +--- a/snmplib/parse.c ++++ b/snmplib/parse.c +@@ -1929,11 +1929,12 @@ getoid(FILE * fp, struct subid_s *id_arg, int length) + type = get_token(fp, token, MAXTOKEN); + } + print_error("Too long OID", token, type); ++ --count; + + free_labels: +- for (i = 0; i < count; i++) { +- free(id[i].label); +- id[i].label = NULL; ++ for (i = 0; i <= count; i++) { ++ free(id_arg[i].label); ++ id_arg[i].label = NULL; + } + + return 0; +-- +1.8.3.1 + diff --git a/backport-libsnmp-Fix-undefined-behavior-in-asn_build_int.patch b/backport-libsnmp-Fix-undefined-behavior-in-asn_build_int.patch new file mode 100644 index 0000000..5a796a8 --- /dev/null +++ b/backport-libsnmp-Fix-undefined-behavior-in-asn_build_int.patch @@ -0,0 +1,29 @@ +From 277d75633d8008cde468d026694289ca32f2cb6d Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 26 Aug 2021 10:17:11 -0700 +Subject: [PATCH] libsnmp: Fix undefined behavior in asn_build_int() + +According to the C standard, triggering an overflow by shifting a signed +integer results in undefined behavior. Fix this by inserting a cast. + +Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=37579 +--- + snmplib/asn1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/snmplib/asn1.c b/snmplib/asn1.c +index d5d7eb6..959ae21 100644 +--- a/snmplib/asn1.c ++++ b/snmplib/asn1.c +@@ -784,7 +784,7 @@ asn_build_int(u_char * data, + */ + while (intsize--) { + *data++ = (u_char) ((integer & mask) >> (8 * (sizeof(long) - 1))); +- integer <<= 8; ++ integer = (u_long)integer << 8; + } + DEBUGDUMPSETUP("send", initdatap, data - initdatap); + DEBUGMSG(("dumpv_send", " Integer:\t%ld (0x%.2lX)\n", *intp, *intp)); +-- +1.8.3.1 + diff --git a/backport-libsnmp-Increase-MAX_IMPORTS.patch b/backport-libsnmp-Increase-MAX_IMPORTS.patch new file mode 100644 index 0000000..3626cc5 --- /dev/null +++ b/backport-libsnmp-Increase-MAX_IMPORTS.patch @@ -0,0 +1,30 @@ +From 893b9baa6ae81a877e76842c29a637eeb2cbd0e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Guido=20J=C3=A4kel?= +Date: Thu, 3 Sep 2020 17:03:33 +0200 +Subject: [PATCH] libsnmp: Increase MAX_IMPORTS + +Today, I stepped into an well-known old issue +(https://sourceforge.net/p/net-snmp/mailman/message/16927159/) using MIBs +for a CISCO device. + +[bvanassche: edited commit message] +--- + snmplib/parse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/snmplib/parse.c b/snmplib/parse.c +index ac5a36d..96588a4 100644 +--- a/snmplib/parse.c ++++ b/snmplib/parse.c +@@ -3636,7 +3636,7 @@ parse_imports(FILE * fp) + register int type; + char token[MAXTOKEN]; + char modbuf[256]; +-#define MAX_IMPORTS 256 ++#define MAX_IMPORTS 512 + struct module_import import_list[MAX_IMPORTS]; + int this_module; + struct module *mp; +-- +1.8.3.1 + diff --git a/backport-libsnmp-Rework-parse_imports.patch b/backport-libsnmp-Rework-parse_imports.patch new file mode 100644 index 0000000..dd79cc9 --- /dev/null +++ b/backport-libsnmp-Rework-parse_imports.patch @@ -0,0 +1,77 @@ +From ed4c8e85cb44e84ada5b8d2ff58e903de7ede737 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 6 Sep 2020 15:12:48 -0700 +Subject: [PATCH] libsnmp: Rework parse_imports() + +Do not cast pointers passed to free(). Reduce the number of return +statements in this function to one. Surround multiline statements with +braces. +--- + snmplib/parse.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/snmplib/parse.c b/snmplib/parse.c +index 96588a4..27b37a1 100644 +--- a/snmplib/parse.c ++++ b/snmplib/parse.c +@@ -3656,7 +3656,7 @@ parse_imports(FILE * fp) + do { + type = get_token(fp, token, MAXTOKEN); + } while (type != SEMI && type != ENDOFFILE); +- return; ++ goto out; + } + import_list[import_count++].label = strdup(token); + } else if (type == FROM) { +@@ -3693,10 +3693,10 @@ parse_imports(FILE * fp) + * Save the import information + * in the global module table + */ +- for (mp = module_head; mp; mp = mp->next) ++ for (mp = module_head; mp; mp = mp->next) { + if (mp->modid == current_module) { + if (import_count == 0) +- return; ++ goto out; + if (mp->imports && (mp->imports != root_imports)) { + /* + * this can happen if all modules are in one source file. +@@ -3706,14 +3706,14 @@ parse_imports(FILE * fp) + "#### freeing Module %d '%s' %d\n", + mp->modid, mp->imports[i].label, + mp->imports[i].modid)); +- free((char *) mp->imports[i].label); ++ free(mp->imports[i].label); + } +- free((char *) mp->imports); ++ free(mp->imports); + } + mp->imports = (struct module_import *) + calloc(import_count, sizeof(struct module_import)); + if (mp->imports == NULL) +- return; ++ goto out; + for (i = 0; i < import_count; ++i) { + mp->imports[i].label = import_list[i].label; + mp->imports[i].modid = import_list[i].modid; +@@ -3722,13 +3722,16 @@ parse_imports(FILE * fp) + mp->imports[i].label, mp->imports[i].modid)); + } + mp->no_imports = import_count; +- return; ++ goto out; + } ++ } + + /* + * Shouldn't get this far + */ + print_module_not_found(module_name(current_module, modbuf)); ++ ++out: + return; + } + +-- +1.8.3.1 + diff --git a/net-snmp.spec b/net-snmp.spec index eb01a44..578d337 100644 --- a/net-snmp.spec +++ b/net-snmp.spec @@ -3,7 +3,7 @@ Name: net-snmp Version: 5.8 -Release: 14 +Release: 15 Epoch: 1 Summary: SNMP Daemon License: BSD @@ -43,6 +43,13 @@ Patch20: CVE-2019-20892-5.patch Patch21: CVE-2019-20892-6.patch Patch22: CVE-2020-15862.patch Patch23: CVE-2020-15861.patch +Patch25: backport-libsnmp-Fix-more-undefined-behavior-in-asn_build_int.patch +Patch26: backport-libsnmp-Fix-undefined-behavior-in-asn_build_int.patch +Patch27: backport-libsnmp-Rework-parse_imports.patch +Patch28: backport-libsnmp-Increase-MAX_IMPORTS.patch +Patch29: backport-libsnmp-Allocate-the-module-import-list-on-the-heap.patch +Patch30: backport-libsnmp-Fix-a-memory-leak-in-a-MIB-parser-error-path.patch +Patch31: backport-libsnmp-Fix-the-getoid-error-path.patch %{?systemd_requires} BuildRequires: systemd gcc openssl-devel bzip2-devel elfutils-devel libselinux-devel @@ -322,6 +329,17 @@ LD_LIBRARY_PATH=%{buildroot}/%{_libdir} make test %{_mandir}/man1/fixproc* %changelog +* Fri Sep 17 2021 gaihuiying - 5.8-15 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Fix undefined behavior in asn_build_int() + libsnmp: Rework parse_imports() + libsnmp: Increase MAX_IMPORTS + libsnmp: Allocate the module import list on the heap + libsnmp: Fix a memory leak in a MIB parser error path + libsnmp: Fix the getoid() error path + * Tue Dec 15 2020 xihaochen - 5.8-14 - Type:requirement - ID:NA -- Gitee