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" |