diff options
| author | Ovidiu Panait <ovidiu.panait@windriver.com> | 2020-09-01 12:22:00 +0300 |
|---|---|---|
| committer | Armin Kuster <akuster808@gmail.com> | 2020-09-03 08:28:37 -0700 |
| commit | d7b41ced4b9a9a68083b0fcceff3b226298cff8b (patch) | |
| tree | 03ec3cfb6aa87e35f4fa14fc3af29e0994765c4c | |
| parent | b72b233d268c51376ecfa277ea8346621f632467 (diff) | |
| download | meta-openembedded-d7b41ced4b9a9a68083b0fcceff3b226298cff8b.tar.gz | |
net-snmp: Fix CVE-2020-15861 and CVE-2020-15862
Net-SNMP through 5.7.3 allows Escalation of Privileges because of UNIX symbolic
link (symlink) following.
Net-SNMP through 5.7.3 has Improper Privilege Management because SNMP WRITE
access to the EXTEND MIB provides the ability to run arbitrary commands as
root.
References:
https://nvd.nist.gov/vuln/detail/CVE-2020-15861
https://nvd.nist.gov/vuln/detail/CVE-2020-15862
Upstream patches:
https://github.com/net-snmp/net-snmp/commit/2b3e300ade4add03b889e61d610b0db77d300fc3
https://github.com/net-snmp/net-snmp/commit/9cfb38b0aa95363da1466ca81dd929989ba27c1f
https://github.com/net-snmp/net-snmp/commit/114e4c2cec2601ca56e8afb1f441520f75a9a312
https://github.com/net-snmp/net-snmp/commit/2968b455e6f182f329746e2bca1043f368618c73
https://github.com/net-snmp/net-snmp/commit/4fd9a450444a434a993bc72f7c3486ccce41f602
https://github.com/net-snmp/net-snmp/commit/77f6c60f57dba0aaea5d8ef1dd94bcd0c8e6d205
CVE-2020-15861-0005.patch is the actual fix for CVE-2020-15861 and
CVE-2020-15861-0001.patch through CVE-2020-15861-0004.patch are context
patches needed by the fix to apply cleanly.
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
7 files changed, 723 insertions, 0 deletions
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0001.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0001.patch new file mode 100644 index 0000000000..f43803a663 --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0001.patch | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | From c449946b9d06571b447fce3fc0dcad89e8df05b5 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bart Van Assche <bvanassche@acm.org> | ||
| 3 | Date: Wed, 15 May 2019 14:09:25 +0200 | ||
| 4 | Subject: [PATCH 1/5] CHANGES: libsnmp: Scan MIB directories in alphabetical | ||
| 5 | order | ||
| 6 | |||
| 7 | This guarantees that e.g. mibs/RFC1213-MIB.txt is read before mibs/SNMPv2-MIB.txt. | ||
| 8 | The order in which these MIBs is read matters because both define sysLocation but | ||
| 9 | with different attributes. | ||
| 10 | |||
| 11 | CVE: CVE-2020-15861 | ||
| 12 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/2b3e300ade4add03b889e61d610b0db77d300fc3] | ||
| 13 | |||
| 14 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 15 | --- | ||
| 16 | snmplib/parse.c | 113 +++++++++++++++++++++++++++++++++++------------- | ||
| 17 | 1 file changed, 82 insertions(+), 31 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/snmplib/parse.c b/snmplib/parse.c | ||
| 20 | index 7678b35..51d119b 100644 | ||
| 21 | --- a/snmplib/parse.c | ||
| 22 | +++ b/snmplib/parse.c | ||
| 23 | @@ -4894,6 +4894,79 @@ add_mibfile(const char* tmpstr, const char* d_name, FILE *ip ) | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | +static int elemcmp(const void *a, const void *b) | ||
| 28 | +{ | ||
| 29 | + const char *const *s1 = a, *const *s2 = b; | ||
| 30 | + | ||
| 31 | + return strcmp(*s1, *s2); | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +/* | ||
| 35 | + * Scan a directory and return all filenames found as an array of pointers to | ||
| 36 | + * directory entries (@result). | ||
| 37 | + */ | ||
| 38 | +static int scan_directory(char ***result, const char *dirname) | ||
| 39 | +{ | ||
| 40 | + DIR *dir, *dir2; | ||
| 41 | + struct dirent *file; | ||
| 42 | + char **filenames = NULL; | ||
| 43 | + int fname_len, i, filename_count = 0, array_size = 0; | ||
| 44 | + char *tmpstr; | ||
| 45 | + | ||
| 46 | + *result = NULL; | ||
| 47 | + | ||
| 48 | + dir = opendir(dirname); | ||
| 49 | + if (!dir) | ||
| 50 | + return -1; | ||
| 51 | + | ||
| 52 | + while ((file = readdir(dir))) { | ||
| 53 | + /* | ||
| 54 | + * Only parse file names that don't begin with a '.' | ||
| 55 | + * Also skip files ending in '~', or starting/ending | ||
| 56 | + * with '#' which are typically editor backup files. | ||
| 57 | + */ | ||
| 58 | + fname_len = strlen(file->d_name); | ||
| 59 | + if (fname_len > 0 && file->d_name[0] != '.' | ||
| 60 | + && file->d_name[0] != '#' | ||
| 61 | + && file->d_name[fname_len-1] != '#' | ||
| 62 | + && file->d_name[fname_len-1] != '~') { | ||
| 63 | + if (asprintf(&tmpstr, "%s/%s", dirname, file->d_name) < 0) | ||
| 64 | + continue; | ||
| 65 | + dir2 = opendir(tmpstr); | ||
| 66 | + if (dir2) { | ||
| 67 | + /* file is a directory, don't read it */ | ||
| 68 | + closedir(dir2); | ||
| 69 | + } else { | ||
| 70 | + if (filename_count >= array_size) { | ||
| 71 | + char **new_filenames; | ||
| 72 | + | ||
| 73 | + array_size = (array_size + 16) * 2; | ||
| 74 | + new_filenames = realloc(filenames, | ||
| 75 | + array_size * sizeof(filenames[0])); | ||
| 76 | + if (!new_filenames) { | ||
| 77 | + free(tmpstr); | ||
| 78 | + for (i = 0; i < filename_count; i++) | ||
| 79 | + free(filenames[i]); | ||
| 80 | + free(filenames); | ||
| 81 | + closedir(dir); | ||
| 82 | + return -1; | ||
| 83 | + } | ||
| 84 | + filenames = new_filenames; | ||
| 85 | + } | ||
| 86 | + filenames[filename_count++] = tmpstr; | ||
| 87 | + tmpstr = NULL; | ||
| 88 | + } | ||
| 89 | + free(tmpstr); | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + closedir(dir); | ||
| 93 | + | ||
| 94 | + qsort(filenames, filename_count, sizeof(filenames[0]), elemcmp); | ||
| 95 | + *result = filenames; | ||
| 96 | + | ||
| 97 | + return filename_count; | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | /* For Win32 platforms, the directory does not maintain a last modification | ||
| 101 | * date that we can compare with the modification date of the .index file. | ||
| 102 | * Therefore there is no way to know whether any .index file is valid. | ||
| 103 | @@ -4904,12 +4977,11 @@ int | ||
| 104 | add_mibdir(const char *dirname) | ||
| 105 | { | ||
| 106 | FILE *ip; | ||
| 107 | - DIR *dir, *dir2; | ||
| 108 | const char *oldFile = File; | ||
| 109 | - struct dirent *file; | ||
| 110 | + char **filenames; | ||
| 111 | char tmpstr[300]; | ||
| 112 | int count = 0; | ||
| 113 | - int fname_len = 0; | ||
| 114 | + int filename_count, i; | ||
| 115 | #if !(defined(WIN32) || defined(cygwin)) | ||
| 116 | char *token; | ||
| 117 | char space; | ||
| 118 | @@ -4957,36 +5029,15 @@ add_mibdir(const char *dirname) | ||
| 119 | DEBUGMSGTL(("parse-mibs", "No index\n")); | ||
| 120 | #endif | ||
| 121 | |||
| 122 | - if ((dir = opendir(dirname))) { | ||
| 123 | - ip = netsnmp_mibindex_new( dirname ); | ||
| 124 | - while ((file = readdir(dir))) { | ||
| 125 | - /* | ||
| 126 | - * Only parse file names that don't begin with a '.' | ||
| 127 | - * Also skip files ending in '~', or starting/ending | ||
| 128 | - * with '#' which are typically editor backup files. | ||
| 129 | - */ | ||
| 130 | - if (file->d_name != NULL) { | ||
| 131 | - fname_len = strlen( file->d_name ); | ||
| 132 | - if (fname_len > 0 && file->d_name[0] != '.' | ||
| 133 | - && file->d_name[0] != '#' | ||
| 134 | - && file->d_name[fname_len-1] != '#' | ||
| 135 | - && file->d_name[fname_len-1] != '~') { | ||
| 136 | - snprintf(tmpstr, sizeof(tmpstr), "%s/%s", dirname, file->d_name); | ||
| 137 | - tmpstr[ sizeof(tmpstr)-1 ] = 0; | ||
| 138 | - if ((dir2 = opendir(tmpstr))) { | ||
| 139 | - /* | ||
| 140 | - * file is a directory, don't read it | ||
| 141 | - */ | ||
| 142 | - closedir(dir2); | ||
| 143 | - } else { | ||
| 144 | - if ( !add_mibfile( tmpstr, file->d_name, ip )) | ||
| 145 | - count++; | ||
| 146 | - } | ||
| 147 | - } | ||
| 148 | - } | ||
| 149 | + filename_count = scan_directory(&filenames, dirname); | ||
| 150 | + | ||
| 151 | + if (filename_count >= 0) { | ||
| 152 | + ip = netsnmp_mibindex_new(dirname); | ||
| 153 | + for (i = 0; i < filename_count; i++) { | ||
| 154 | + if (add_mibfile(filenames[i], strrchr(filenames[i], '/'), ip) == 0) | ||
| 155 | + count++; | ||
| 156 | } | ||
| 157 | File = oldFile; | ||
| 158 | - closedir(dir); | ||
| 159 | if (ip) | ||
| 160 | fclose(ip); | ||
| 161 | return (count); | ||
| 162 | -- | ||
| 163 | 2.17.1 | ||
| 164 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0002.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0002.patch new file mode 100644 index 0000000000..e54a8b4acb --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0002.patch | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | From 50118392c58c8d9554580373c0dbc542336b58a9 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bart Van Assche <bvanassche@acm.org> | ||
| 3 | Date: Thu, 16 May 2019 13:49:05 +0200 | ||
| 4 | Subject: [PATCH 2/5] libsnmp: Fix two recently introduced issues in the MIB | ||
| 5 | parsing code | ||
| 6 | |||
| 7 | Ensure that the first argument passed to qsort() is not NULL. Free the memory | ||
| 8 | that holds the directory contents. | ||
| 9 | |||
| 10 | Fixes: 2b3e300ade4a ("CHANGES: libsnmp: Scan MIB directories in alphabetical order") | ||
| 11 | |||
| 12 | CVE: CVE-2020-15861 | ||
| 13 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/9cfb38b0aa95363da1466ca81dd929989ba27c1f] | ||
| 14 | |||
| 15 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 16 | --- | ||
| 17 | snmplib/parse.c | 4 +++- | ||
| 18 | 1 file changed, 3 insertions(+), 1 deletion(-) | ||
| 19 | |||
| 20 | diff --git a/snmplib/parse.c b/snmplib/parse.c | ||
| 21 | index 51d119b..200ba25 100644 | ||
| 22 | --- a/snmplib/parse.c | ||
| 23 | +++ b/snmplib/parse.c | ||
| 24 | @@ -4961,7 +4961,8 @@ static int scan_directory(char ***result, const char *dirname) | ||
| 25 | } | ||
| 26 | closedir(dir); | ||
| 27 | |||
| 28 | - qsort(filenames, filename_count, sizeof(filenames[0]), elemcmp); | ||
| 29 | + if (filenames) | ||
| 30 | + qsort(filenames, filename_count, sizeof(filenames[0]), elemcmp); | ||
| 31 | *result = filenames; | ||
| 32 | |||
| 33 | return filename_count; | ||
| 34 | @@ -5040,6 +5041,7 @@ add_mibdir(const char *dirname) | ||
| 35 | File = oldFile; | ||
| 36 | if (ip) | ||
| 37 | fclose(ip); | ||
| 38 | + free(filenames); | ||
| 39 | return (count); | ||
| 40 | } | ||
| 41 | else | ||
| 42 | -- | ||
| 43 | 2.17.1 | ||
| 44 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0003.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0003.patch new file mode 100644 index 0000000000..03acbbab92 --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0003.patch | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | From c98808036c86a4ac4877ea13dbcef096b57e49f8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bart Van Assche <bvanassche@acm.org> | ||
| 3 | Date: Wed, 22 May 2019 10:08:53 +0200 | ||
| 4 | Subject: [PATCH 3/5] libsnmp: Fix a compiler warning | ||
| 5 | |||
| 6 | Avoid that the compiler complains on Windows systems that tmpstr[] is not used. | ||
| 7 | |||
| 8 | Fixes: 2b3e300ade4a ("CHANGES: libsnmp: Scan MIB directories in alphabetical order") | ||
| 9 | |||
| 10 | CVE: CVE-2020-15861 | ||
| 11 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/114e4c2cec2601ca56e8afb1f441520f75a9a312] | ||
| 12 | |||
| 13 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 14 | --- | ||
| 15 | snmplib/parse.c | 2 +- | ||
| 16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 17 | |||
| 18 | diff --git a/snmplib/parse.c b/snmplib/parse.c | ||
| 19 | index 200ba25..0414337 100644 | ||
| 20 | --- a/snmplib/parse.c | ||
| 21 | +++ b/snmplib/parse.c | ||
| 22 | @@ -4980,7 +4980,6 @@ add_mibdir(const char *dirname) | ||
| 23 | FILE *ip; | ||
| 24 | const char *oldFile = File; | ||
| 25 | char **filenames; | ||
| 26 | - char tmpstr[300]; | ||
| 27 | int count = 0; | ||
| 28 | int filename_count, i; | ||
| 29 | #if !(defined(WIN32) || defined(cygwin)) | ||
| 30 | @@ -4988,6 +4987,7 @@ add_mibdir(const char *dirname) | ||
| 31 | char space; | ||
| 32 | char newline; | ||
| 33 | struct stat dir_stat, idx_stat; | ||
| 34 | + char tmpstr[300]; | ||
| 35 | char tmpstr1[300]; | ||
| 36 | #endif | ||
| 37 | |||
| 38 | -- | ||
| 39 | 2.17.1 | ||
| 40 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0004.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0004.patch new file mode 100644 index 0000000000..f0e709636e --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0004.patch | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | From 545742d1867d70a645a63161ede4a391456691fc Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bill Fenner <fenner@gmail.com> | ||
| 3 | Date: Mon, 3 Jun 2019 10:01:08 -0700 | ||
| 4 | Subject: [PATCH 4/5] libsnmp: free filenames from directory listing | ||
| 5 | |||
| 6 | Free each filename as we use it, as well as freeing the | ||
| 7 | list of filenames. | ||
| 8 | |||
| 9 | Fixes: 2b3e300ade4a ("CHANGES: libsnmp: Scan MIB directories in alphabetical order") | ||
| 10 | |||
| 11 | CVE: CVE-2020-15861 | ||
| 12 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/2968b455e6f182f329746e2bca1043f368618c73] | ||
| 13 | |||
| 14 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 15 | --- | ||
| 16 | snmplib/parse.c | 1 + | ||
| 17 | 1 file changed, 1 insertion(+) | ||
| 18 | |||
| 19 | diff --git a/snmplib/parse.c b/snmplib/parse.c | ||
| 20 | index 0414337..7f98542 100644 | ||
| 21 | --- a/snmplib/parse.c | ||
| 22 | +++ b/snmplib/parse.c | ||
| 23 | @@ -5037,6 +5037,7 @@ add_mibdir(const char *dirname) | ||
| 24 | for (i = 0; i < filename_count; i++) { | ||
| 25 | if (add_mibfile(filenames[i], strrchr(filenames[i], '/'), ip) == 0) | ||
| 26 | count++; | ||
| 27 | + free(filenames[i]); | ||
| 28 | } | ||
| 29 | File = oldFile; | ||
| 30 | if (ip) | ||
| 31 | -- | ||
| 32 | 2.17.1 | ||
| 33 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0005.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0005.patch new file mode 100644 index 0000000000..66a16f6dbf --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15861-0005.patch | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | From 83d6c5181828921b3731878588b3728de704d490 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bart Van Assche <bvanassche@acm.org> | ||
| 3 | Date: Wed, 22 May 2019 09:56:21 +0200 | ||
| 4 | Subject: [PATCH 5/5] CHANGES: snmpd: Stop reading and writing the | ||
| 5 | mib_indexes/* files | ||
| 6 | |||
| 7 | Caching directory contents is something the operating system should do | ||
| 8 | and is not something Net-SNMP should do. Instead of storing a copy of | ||
| 9 | the directory contents in ${tmp_dir}/mib_indexes/${n}, always scan a | ||
| 10 | MIB directory. | ||
| 11 | |||
| 12 | CVE: CVE-2020-15861 | ||
| 13 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/4fd9a450444a434a993bc72f7c3486ccce41f602] | ||
| 14 | |||
| 15 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 16 | --- | ||
| 17 | .gitignore | 1 - | ||
| 18 | include/net-snmp/library/mib.h | 3 - | ||
| 19 | include/net-snmp/library/parse.h | 2 +- | ||
| 20 | snmplib/mib.c | 148 +------------------------------ | ||
| 21 | snmplib/parse.c | 57 +----------- | ||
| 22 | 5 files changed, 4 insertions(+), 207 deletions(-) | ||
| 23 | |||
| 24 | diff --git a/.gitignore b/.gitignore | ||
| 25 | index 2d37bc6..94da568 100644 | ||
| 26 | --- a/.gitignore | ||
| 27 | +++ b/.gitignore | ||
| 28 | @@ -75,7 +75,6 @@ Makefile | ||
| 29 | man/*.[1358] | ||
| 30 | man/default_store.3.h | ||
| 31 | man/manaliases | ||
| 32 | -mibs/.index | ||
| 33 | mk/ | ||
| 34 | module_tmp_header.h | ||
| 35 | net-snmp-5* | ||
| 36 | diff --git a/include/net-snmp/library/mib.h b/include/net-snmp/library/mib.h | ||
| 37 | index ab36853..3e81634 100644 | ||
| 38 | --- a/include/net-snmp/library/mib.h | ||
| 39 | +++ b/include/net-snmp/library/mib.h | ||
| 40 | @@ -124,9 +124,6 @@ SOFTWARE. | ||
| 41 | NETSNMP_IMPORT | ||
| 42 | char *netsnmp_get_mib_directory(void); | ||
| 43 | void netsnmp_fixup_mib_directory(void); | ||
| 44 | - void netsnmp_mibindex_load( void ); | ||
| 45 | - char * netsnmp_mibindex_lookup( const char * ); | ||
| 46 | - FILE * netsnmp_mibindex_new( const char * ); | ||
| 47 | int sprint_realloc_description(u_char ** buf, size_t * buf_len, | ||
| 48 | size_t * out_len, int allow_realloc, | ||
| 49 | oid * objid, size_t objidlen, int width); | ||
| 50 | diff --git a/include/net-snmp/library/parse.h b/include/net-snmp/library/parse.h | ||
| 51 | index ce46ab9..7c33d3f 100644 | ||
| 52 | --- a/include/net-snmp/library/parse.h | ||
| 53 | +++ b/include/net-snmp/library/parse.h | ||
| 54 | @@ -201,7 +201,7 @@ SOFTWARE. | ||
| 55 | #endif | ||
| 56 | void netsnmp_init_mib_internals(void); | ||
| 57 | void unload_all_mibs(void); | ||
| 58 | - int add_mibfile(const char*, const char*, FILE *); | ||
| 59 | + int add_mibfile(const char*, const char*); | ||
| 60 | int which_module(const char *); | ||
| 61 | NETSNMP_IMPORT | ||
| 62 | char *module_name(int, char *); | ||
| 63 | diff --git a/snmplib/mib.c b/snmplib/mib.c | ||
| 64 | index 1c875c0..30d6cde 100644 | ||
| 65 | --- a/snmplib/mib.c | ||
| 66 | +++ b/snmplib/mib.c | ||
| 67 | @@ -2717,7 +2717,6 @@ netsnmp_init_mib(void) | ||
| 68 | env_var = strdup(netsnmp_get_mib_directory()); | ||
| 69 | if (!env_var) | ||
| 70 | return; | ||
| 71 | - netsnmp_mibindex_load(); | ||
| 72 | |||
| 73 | DEBUGMSGTL(("init_mib", | ||
| 74 | "Seen MIBDIRS: Looking in '%s' for mib dirs ...\n", | ||
| 75 | @@ -2737,7 +2736,7 @@ netsnmp_init_mib(void) | ||
| 76 | else | ||
| 77 | entry = strtok_r(env_var, ENV_SEPARATOR, &st); | ||
| 78 | while (entry) { | ||
| 79 | - add_mibfile(entry, NULL, NULL); | ||
| 80 | + add_mibfile(entry, NULL); | ||
| 81 | entry = strtok_r(NULL, ENV_SEPARATOR, &st); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | @@ -2888,142 +2887,6 @@ init_mib(void) | ||
| 85 | #endif | ||
| 86 | |||
| 87 | |||
| 88 | -/* | ||
| 89 | - * Handle MIB indexes centrally | ||
| 90 | - */ | ||
| 91 | -static int _mibindex = 0; /* Last index in use */ | ||
| 92 | -static int _mibindex_max = 0; /* Size of index array */ | ||
| 93 | -char **_mibindexes = NULL; | ||
| 94 | - | ||
| 95 | -int _mibindex_add( const char *dirname, int i ); | ||
| 96 | -void | ||
| 97 | -netsnmp_mibindex_load( void ) | ||
| 98 | -{ | ||
| 99 | - DIR *dir; | ||
| 100 | - struct dirent *file; | ||
| 101 | - FILE *fp; | ||
| 102 | - char tmpbuf[ 300]; | ||
| 103 | - char tmpbuf2[300]; | ||
| 104 | - int i; | ||
| 105 | - char *cp; | ||
| 106 | - | ||
| 107 | - /* | ||
| 108 | - * Open the MIB index directory, or create it (empty) | ||
| 109 | - */ | ||
| 110 | - snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes", | ||
| 111 | - get_persistent_directory()); | ||
| 112 | - tmpbuf[sizeof(tmpbuf)-1] = 0; | ||
| 113 | - dir = opendir( tmpbuf ); | ||
| 114 | - if ( dir == NULL ) { | ||
| 115 | - DEBUGMSGTL(("mibindex", "load: (new)\n")); | ||
| 116 | - mkdirhier( tmpbuf, NETSNMP_AGENT_DIRECTORY_MODE, 0); | ||
| 117 | - return; | ||
| 118 | - } | ||
| 119 | - | ||
| 120 | - /* | ||
| 121 | - * Create a list of which directory each file refers to | ||
| 122 | - */ | ||
| 123 | - while ((file = readdir( dir ))) { | ||
| 124 | - if ( !isdigit((unsigned char)(file->d_name[0]))) | ||
| 125 | - continue; | ||
| 126 | - i = atoi( file->d_name ); | ||
| 127 | - | ||
| 128 | - snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", | ||
| 129 | - get_persistent_directory(), i ); | ||
| 130 | - tmpbuf[sizeof(tmpbuf)-1] = 0; | ||
| 131 | - fp = fopen( tmpbuf, "r" ); | ||
| 132 | - if (!fp) | ||
| 133 | - continue; | ||
| 134 | - cp = fgets( tmpbuf2, sizeof(tmpbuf2), fp ); | ||
| 135 | - fclose( fp ); | ||
| 136 | - if ( !cp ) { | ||
| 137 | - DEBUGMSGTL(("mibindex", "Empty MIB index (%d)\n", i)); | ||
| 138 | - continue; | ||
| 139 | - } | ||
| 140 | - if ( strncmp( tmpbuf2, "DIR ", 4 ) != 0 ) { | ||
| 141 | - DEBUGMSGTL(("mibindex", "Malformed MIB index (%d)\n", i)); | ||
| 142 | - continue; | ||
| 143 | - } | ||
| 144 | - tmpbuf2[strlen(tmpbuf2)-1] = 0; | ||
| 145 | - DEBUGMSGTL(("mibindex", "load: (%d) %s\n", i, tmpbuf2)); | ||
| 146 | - (void)_mibindex_add( tmpbuf2+4, i ); /* Skip 'DIR ' */ | ||
| 147 | - } | ||
| 148 | - closedir( dir ); | ||
| 149 | -} | ||
| 150 | - | ||
| 151 | -char * | ||
| 152 | -netsnmp_mibindex_lookup( const char *dirname ) | ||
| 153 | -{ | ||
| 154 | - int i; | ||
| 155 | - static char tmpbuf[300]; | ||
| 156 | - | ||
| 157 | - for (i=0; i<_mibindex; i++) { | ||
| 158 | - if ( _mibindexes[i] && | ||
| 159 | - strcmp( _mibindexes[i], dirname ) == 0) { | ||
| 160 | - snprintf(tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", | ||
| 161 | - get_persistent_directory(), i); | ||
| 162 | - tmpbuf[sizeof(tmpbuf)-1] = 0; | ||
| 163 | - DEBUGMSGTL(("mibindex", "lookup: %s (%d) %s\n", dirname, i, tmpbuf )); | ||
| 164 | - return tmpbuf; | ||
| 165 | - } | ||
| 166 | - } | ||
| 167 | - DEBUGMSGTL(("mibindex", "lookup: (none)\n")); | ||
| 168 | - return NULL; | ||
| 169 | -} | ||
| 170 | - | ||
| 171 | -int | ||
| 172 | -_mibindex_add( const char *dirname, int i ) | ||
| 173 | -{ | ||
| 174 | - const int old_mibindex_max = _mibindex_max; | ||
| 175 | - | ||
| 176 | - DEBUGMSGTL(("mibindex", "add: %s (%d)\n", dirname, i )); | ||
| 177 | - if ( i == -1 ) | ||
| 178 | - i = _mibindex++; | ||
| 179 | - if ( i >= _mibindex_max ) { | ||
| 180 | - /* | ||
| 181 | - * If the index array is full (or non-existent) | ||
| 182 | - * then expand (or create) it | ||
| 183 | - */ | ||
| 184 | - _mibindex_max = i + 10; | ||
| 185 | - _mibindexes = realloc(_mibindexes, | ||
| 186 | - _mibindex_max * sizeof(_mibindexes[0])); | ||
| 187 | - netsnmp_assert(_mibindexes); | ||
| 188 | - memset(_mibindexes + old_mibindex_max, 0, | ||
| 189 | - (_mibindex_max - old_mibindex_max) * sizeof(_mibindexes[0])); | ||
| 190 | - } | ||
| 191 | - | ||
| 192 | - _mibindexes[ i ] = strdup( dirname ); | ||
| 193 | - if ( i >= _mibindex ) | ||
| 194 | - _mibindex = i+1; | ||
| 195 | - | ||
| 196 | - DEBUGMSGTL(("mibindex", "add: %d/%d/%d\n", i, _mibindex, _mibindex_max )); | ||
| 197 | - return i; | ||
| 198 | -} | ||
| 199 | - | ||
| 200 | -FILE * | ||
| 201 | -netsnmp_mibindex_new( const char *dirname ) | ||
| 202 | -{ | ||
| 203 | - FILE *fp; | ||
| 204 | - char tmpbuf[300]; | ||
| 205 | - char *cp; | ||
| 206 | - int i; | ||
| 207 | - | ||
| 208 | - cp = netsnmp_mibindex_lookup( dirname ); | ||
| 209 | - if (!cp) { | ||
| 210 | - i = _mibindex_add( dirname, -1 ); | ||
| 211 | - snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", | ||
| 212 | - get_persistent_directory(), i ); | ||
| 213 | - tmpbuf[sizeof(tmpbuf)-1] = 0; | ||
| 214 | - cp = tmpbuf; | ||
| 215 | - } | ||
| 216 | - DEBUGMSGTL(("mibindex", "new: %s (%s)\n", dirname, cp )); | ||
| 217 | - fp = fopen( cp, "w" ); | ||
| 218 | - if (fp) | ||
| 219 | - fprintf( fp, "DIR %s\n", dirname ); | ||
| 220 | - return fp; | ||
| 221 | -} | ||
| 222 | - | ||
| 223 | - | ||
| 224 | /** | ||
| 225 | * Unloads all mibs. | ||
| 226 | */ | ||
| 227 | @@ -3038,15 +2901,6 @@ shutdown_mib(void) | ||
| 228 | } | ||
| 229 | tree_head = NULL; | ||
| 230 | Mib = NULL; | ||
| 231 | - if (_mibindexes) { | ||
| 232 | - int i; | ||
| 233 | - for (i = 0; i < _mibindex; ++i) | ||
| 234 | - SNMP_FREE(_mibindexes[i]); | ||
| 235 | - free(_mibindexes); | ||
| 236 | - _mibindex = 0; | ||
| 237 | - _mibindex_max = 0; | ||
| 238 | - _mibindexes = NULL; | ||
| 239 | - } | ||
| 240 | if (Prefix != NULL && Prefix != &Standard_Prefix[0]) | ||
| 241 | SNMP_FREE(Prefix); | ||
| 242 | if (Prefix) | ||
| 243 | diff --git a/snmplib/parse.c b/snmplib/parse.c | ||
| 244 | index 7f98542..58d777e 100644 | ||
| 245 | --- a/snmplib/parse.c | ||
| 246 | +++ b/snmplib/parse.c | ||
| 247 | @@ -607,8 +607,6 @@ static int read_module_replacements(const char *); | ||
| 248 | static int read_import_replacements(const char *, | ||
| 249 | struct module_import *); | ||
| 250 | |||
| 251 | -static void new_module(const char *, const char *); | ||
| 252 | - | ||
| 253 | static struct node *merge_parse_objectid(struct node *, FILE *, char *); | ||
| 254 | static struct index_list *getIndexes(FILE * fp, struct index_list **); | ||
| 255 | static struct varbind_list *getVarbinds(FILE * fp, struct varbind_list **); | ||
| 256 | @@ -4859,7 +4857,7 @@ snmp_get_token(FILE * fp, char *token, int maxtlen) | ||
| 257 | #endif /* NETSNMP_FEATURE_REMOVE_PARSE_GET_TOKEN */ | ||
| 258 | |||
| 259 | int | ||
| 260 | -add_mibfile(const char* tmpstr, const char* d_name, FILE *ip ) | ||
| 261 | +add_mibfile(const char* tmpstr, const char* d_name) | ||
| 262 | { | ||
| 263 | FILE *fp; | ||
| 264 | char token[MAXTOKEN], token2[MAXTOKEN]; | ||
| 265 | @@ -4884,8 +4882,6 @@ add_mibfile(const char* tmpstr, const char* d_name, FILE *ip ) | ||
| 266 | */ | ||
| 267 | if (get_token(fp, token2, MAXTOKEN) == DEFINITIONS) { | ||
| 268 | new_module(token, tmpstr); | ||
| 269 | - if (ip) | ||
| 270 | - fprintf(ip, "%s %s\n", token, d_name); | ||
| 271 | fclose(fp); | ||
| 272 | return 0; | ||
| 273 | } else { | ||
| 274 | @@ -4977,71 +4973,22 @@ static int scan_directory(char ***result, const char *dirname) | ||
| 275 | int | ||
| 276 | add_mibdir(const char *dirname) | ||
| 277 | { | ||
| 278 | - FILE *ip; | ||
| 279 | const char *oldFile = File; | ||
| 280 | char **filenames; | ||
| 281 | int count = 0; | ||
| 282 | int filename_count, i; | ||
| 283 | -#if !(defined(WIN32) || defined(cygwin)) | ||
| 284 | - char *token; | ||
| 285 | - char space; | ||
| 286 | - char newline; | ||
| 287 | - struct stat dir_stat, idx_stat; | ||
| 288 | - char tmpstr[300]; | ||
| 289 | - char tmpstr1[300]; | ||
| 290 | -#endif | ||
| 291 | |||
| 292 | DEBUGMSGTL(("parse-mibs", "Scanning directory %s\n", dirname)); | ||
| 293 | -#if !(defined(WIN32) || defined(cygwin)) | ||
| 294 | - token = netsnmp_mibindex_lookup( dirname ); | ||
| 295 | - if (token && stat(token, &idx_stat) == 0 && stat(dirname, &dir_stat) == 0) { | ||
| 296 | - if (dir_stat.st_mtime < idx_stat.st_mtime) { | ||
| 297 | - DEBUGMSGTL(("parse-mibs", "The index is good\n")); | ||
| 298 | - if ((ip = fopen(token, "r")) != NULL) { | ||
| 299 | - fgets(tmpstr, sizeof(tmpstr), ip); /* Skip dir line */ | ||
| 300 | - while (fscanf(ip, "%127s%c%299[^\n]%c", token, &space, tmpstr, | ||
| 301 | - &newline) == 4) { | ||
| 302 | - | ||
| 303 | - /* | ||
| 304 | - * If an overflow of the token or tmpstr buffers has been | ||
| 305 | - * found log a message and break out of the while loop, | ||
| 306 | - * thus the rest of the file tokens will be ignored. | ||
| 307 | - */ | ||
| 308 | - if (space != ' ' || newline != '\n') { | ||
| 309 | - snmp_log(LOG_ERR, | ||
| 310 | - "add_mibdir: strings scanned in from %s/%s " \ | ||
| 311 | - "are too large. count = %d\n ", dirname, | ||
| 312 | - ".index", count); | ||
| 313 | - break; | ||
| 314 | - } | ||
| 315 | - | ||
| 316 | - snprintf(tmpstr1, sizeof(tmpstr1), "%s/%s", dirname, tmpstr); | ||
| 317 | - tmpstr1[ sizeof(tmpstr1)-1 ] = 0; | ||
| 318 | - new_module(token, tmpstr1); | ||
| 319 | - count++; | ||
| 320 | - } | ||
| 321 | - fclose(ip); | ||
| 322 | - return count; | ||
| 323 | - } else | ||
| 324 | - DEBUGMSGTL(("parse-mibs", "Can't read index\n")); | ||
| 325 | - } else | ||
| 326 | - DEBUGMSGTL(("parse-mibs", "Index outdated\n")); | ||
| 327 | - } else | ||
| 328 | - DEBUGMSGTL(("parse-mibs", "No index\n")); | ||
| 329 | -#endif | ||
| 330 | |||
| 331 | filename_count = scan_directory(&filenames, dirname); | ||
| 332 | |||
| 333 | if (filename_count >= 0) { | ||
| 334 | - ip = netsnmp_mibindex_new(dirname); | ||
| 335 | for (i = 0; i < filename_count; i++) { | ||
| 336 | - if (add_mibfile(filenames[i], strrchr(filenames[i], '/'), ip) == 0) | ||
| 337 | + if (add_mibfile(filenames[i], strrchr(filenames[i], '/')) == 0) | ||
| 338 | count++; | ||
| 339 | free(filenames[i]); | ||
| 340 | } | ||
| 341 | File = oldFile; | ||
| 342 | - if (ip) | ||
| 343 | - fclose(ip); | ||
| 344 | free(filenames); | ||
| 345 | return (count); | ||
| 346 | } | ||
| 347 | -- | ||
| 348 | 2.17.1 | ||
| 349 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15862.patch b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15862.patch new file mode 100644 index 0000000000..419a0c21bb --- /dev/null +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp/CVE-2020-15862.patch | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | From de36cf1ecbb13a9541ec5d43ce20ab5030861837 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Wes Hardaker <opensource@hardakers.net> | ||
| 3 | Date: Thu, 23 Jul 2020 16:17:27 -0700 | ||
| 4 | Subject: [PATCH 1/1] make the extend mib read-only by default | ||
| 5 | |||
| 6 | CVE: CVE-2020-15862 | ||
| 7 | Upstream-Status: Backport [https://github.com/net-snmp/net-snmp/commit/77f6c60f57dba0aaea5d8ef1dd94bcd0c8e6d205] | ||
| 8 | |||
| 9 | Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> | ||
| 10 | --- | ||
| 11 | agent/mibgroup/agent/extend.c | 18 ++++++++++++------ | ||
| 12 | 1 file changed, 12 insertions(+), 6 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/agent/mibgroup/agent/extend.c b/agent/mibgroup/agent/extend.c | ||
| 15 | index 5f8cedc..38a6c50 100644 | ||
| 16 | --- a/agent/mibgroup/agent/extend.c | ||
| 17 | +++ b/agent/mibgroup/agent/extend.c | ||
| 18 | @@ -16,6 +16,12 @@ | ||
| 19 | #define SHELLCOMMAND 3 | ||
| 20 | #endif | ||
| 21 | |||
| 22 | +/* This mib is potentially dangerous to turn on by default, since it | ||
| 23 | + * allows arbitrary commands to be set by anyone with SNMP WRITE | ||
| 24 | + * access to the MIB table. If all of your users are "root" level | ||
| 25 | + * users, then it may be safe to turn on. */ | ||
| 26 | +#define ENABLE_EXTEND_WRITE_ACCESS 0 | ||
| 27 | + | ||
| 28 | netsnmp_feature_require(extract_table_row_data) | ||
| 29 | netsnmp_feature_require(table_data_delete_table) | ||
| 30 | #ifndef NETSNMP_NO_WRITE_SUPPORT | ||
| 31 | @@ -742,7 +748,7 @@ handle_nsExtendConfigTable(netsnmp_mib_handler *handler, | ||
| 32 | * | ||
| 33 | **********/ | ||
| 34 | |||
| 35 | -#ifndef NETSNMP_NO_WRITE_SUPPORT | ||
| 36 | +#if !defined(NETSNMP_NO_WRITE_SUPPORT) && ENABLE_EXTEND_WRITE_ACCESS | ||
| 37 | case MODE_SET_RESERVE1: | ||
| 38 | /* | ||
| 39 | * Validate the new assignments | ||
| 40 | @@ -1068,7 +1074,7 @@ handle_nsExtendConfigTable(netsnmp_mib_handler *handler, | ||
| 41 | } | ||
| 42 | } | ||
| 43 | break; | ||
| 44 | -#endif /* !NETSNMP_NO_WRITE_SUPPORT */ | ||
| 45 | +#endif /* !NETSNMP_NO_WRITE_SUPPORT and ENABLE_EXTEND_WRITE_ACCESS */ | ||
| 46 | |||
| 47 | default: | ||
| 48 | netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); | ||
| 49 | @@ -1076,7 +1082,7 @@ handle_nsExtendConfigTable(netsnmp_mib_handler *handler, | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | -#ifndef NETSNMP_NO_WRITE_SUPPORT | ||
| 54 | +#if !defined(NETSNMP_NO_WRITE_SUPPORT) && ENABLE_EXTEND_WRITE_ACCESS | ||
| 55 | /* | ||
| 56 | * If we're marking a given row as active, | ||
| 57 | * then we need to check that it's ready. | ||
| 58 | @@ -1101,7 +1107,7 @@ handle_nsExtendConfigTable(netsnmp_mib_handler *handler, | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | -#endif /* !NETSNMP_NO_WRITE_SUPPORT */ | ||
| 63 | +#endif /* !NETSNMP_NO_WRITE_SUPPORT && ENABLE_EXTEND_WRITE_ACCESS */ | ||
| 64 | |||
| 65 | return SNMP_ERR_NOERROR; | ||
| 66 | } | ||
| 67 | @@ -1590,7 +1596,7 @@ fixExec2Error(int action, | ||
| 68 | idx = name[name_len-1] -1; | ||
| 69 | exten = &compatability_entries[ idx ]; | ||
| 70 | |||
| 71 | -#ifndef NETSNMP_NO_WRITE_SUPPORT | ||
| 72 | +#if !defined(NETSNMP_NO_WRITE_SUPPORT) && ENABLE_EXTEND_WRITE_ACCESS | ||
| 73 | switch (action) { | ||
| 74 | case MODE_SET_RESERVE1: | ||
| 75 | if (var_val_type != ASN_INTEGER) { | ||
| 76 | @@ -1611,7 +1617,7 @@ fixExec2Error(int action, | ||
| 77 | case MODE_SET_COMMIT: | ||
| 78 | netsnmp_cache_check_and_reload( exten->efix_entry->cache ); | ||
| 79 | } | ||
| 80 | -#endif /* !NETSNMP_NO_WRITE_SUPPORT */ | ||
| 81 | +#endif /* !NETSNMP_NO_WRITE_SUPPORT && ENABLE_EXTEND_WRITE_ACCESS */ | ||
| 82 | return SNMP_ERR_NOERROR; | ||
| 83 | } | ||
| 84 | #endif /* USING_UCD_SNMP_EXTENSIBLE_MODULE */ | ||
| 85 | -- | ||
| 86 | 2.17.1 | ||
| 87 | |||
diff --git a/meta-networking/recipes-protocols/net-snmp/net-snmp_5.8.bb b/meta-networking/recipes-protocols/net-snmp/net-snmp_5.8.bb index 67316db0d2..6b4b6ce8ed 100644 --- a/meta-networking/recipes-protocols/net-snmp/net-snmp_5.8.bb +++ b/meta-networking/recipes-protocols/net-snmp/net-snmp_5.8.bb | |||
| @@ -29,6 +29,12 @@ SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz \ | |||
| 29 | file://0001-net-snmp-fix-compile-error-disable-des.patch \ | 29 | file://0001-net-snmp-fix-compile-error-disable-des.patch \ |
| 30 | file://0001-Add-pkg-config-support-for-building-applications-and.patch \ | 30 | file://0001-Add-pkg-config-support-for-building-applications-and.patch \ |
| 31 | file://CVE-2019-20892.patch \ | 31 | file://CVE-2019-20892.patch \ |
| 32 | file://CVE-2020-15861-0001.patch \ | ||
| 33 | file://CVE-2020-15861-0002.patch \ | ||
| 34 | file://CVE-2020-15861-0003.patch \ | ||
| 35 | file://CVE-2020-15861-0004.patch \ | ||
| 36 | file://CVE-2020-15861-0005.patch \ | ||
| 37 | file://CVE-2020-15862.patch \ | ||
| 32 | " | 38 | " |
| 33 | SRC_URI[md5sum] = "63bfc65fbb86cdb616598df1aff6458a" | 39 | SRC_URI[md5sum] = "63bfc65fbb86cdb616598df1aff6458a" |
| 34 | SRC_URI[sha256sum] = "b2fc3500840ebe532734c4786b0da4ef0a5f67e51ef4c86b3345d697e4976adf" | 40 | SRC_URI[sha256sum] = "b2fc3500840ebe532734c4786b0da4ef0a5f67e51ef4c86b3345d697e4976adf" |
