net-snmp/CVE-2020-15861.patch

355 lines
11 KiB
Diff
Raw Normal View History

2020-10-27 20:09:36 +08:00
From 1d8240c3f9ca3137e105a981823fe530544792ed Mon Sep 17 00:00:00 2001
From: Bart Van Assche <bvanassche@acm.org>
Date: Wed, 22 May 2019 09:56:21 +0200
Subject: [PATCH] CHANGES: snmpd: Stop reading and writing the mib_indexes/*
files
https://github.com/net-snmp/net-snmp/4fd9a450444a434a993bc72f7c3486ccce41f602
Caching directory contents is something the operating system should do
and is not something Net-SNMP should do. Instead of storing a copy of
the directory contents in ${tmp_dir}/mib_indexes/${n}, always scan a
MIB directory.
---
.gitignore | 1 -
include/net-snmp/library/mib.h | 3 -
include/net-snmp/library/parse.h | 2 +-
snmplib/mib.c | 148 +--------------------------------------
snmplib/parse.c | 56 +--------------
5 files changed, 4 insertions(+), 206 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2d37bc6..94da568 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,7 +75,6 @@ Makefile
man/*.[1358]
man/default_store.3.h
man/manaliases
-mibs/.index
mk/
module_tmp_header.h
net-snmp-5*
diff --git a/include/net-snmp/library/mib.h b/include/net-snmp/library/mib.h
index ab36853..3e81634 100644
--- a/include/net-snmp/library/mib.h
+++ b/include/net-snmp/library/mib.h
@@ -124,9 +124,6 @@ SOFTWARE.
NETSNMP_IMPORT
char *netsnmp_get_mib_directory(void);
void netsnmp_fixup_mib_directory(void);
- void netsnmp_mibindex_load( void );
- char * netsnmp_mibindex_lookup( const char * );
- FILE * netsnmp_mibindex_new( const char * );
int sprint_realloc_description(u_char ** buf, size_t * buf_len,
size_t * out_len, int allow_realloc,
oid * objid, size_t objidlen, int width);
diff --git a/include/net-snmp/library/parse.h b/include/net-snmp/library/parse.h
index ce46ab9..7c33d3f 100644
--- a/include/net-snmp/library/parse.h
+++ b/include/net-snmp/library/parse.h
@@ -201,7 +201,7 @@ SOFTWARE.
#endif
void netsnmp_init_mib_internals(void);
void unload_all_mibs(void);
- int add_mibfile(const char*, const char*, FILE *);
+ int add_mibfile(const char*, const char*);
int which_module(const char *);
NETSNMP_IMPORT
char *module_name(int, char *);
diff --git a/snmplib/mib.c b/snmplib/mib.c
index 1c875c0..30d6cde 100644
--- a/snmplib/mib.c
+++ b/snmplib/mib.c
@@ -2717,7 +2717,6 @@ netsnmp_init_mib(void)
env_var = strdup(netsnmp_get_mib_directory());
if (!env_var)
return;
- netsnmp_mibindex_load();
DEBUGMSGTL(("init_mib",
"Seen MIBDIRS: Looking in '%s' for mib dirs ...\n",
@@ -2737,7 +2736,7 @@ netsnmp_init_mib(void)
else
entry = strtok_r(env_var, ENV_SEPARATOR, &st);
while (entry) {
- add_mibfile(entry, NULL, NULL);
+ add_mibfile(entry, NULL);
entry = strtok_r(NULL, ENV_SEPARATOR, &st);
}
}
@@ -2888,142 +2887,6 @@ init_mib(void)
#endif
-/*
- * Handle MIB indexes centrally
- */
-static int _mibindex = 0; /* Last index in use */
-static int _mibindex_max = 0; /* Size of index array */
-char **_mibindexes = NULL;
-
-int _mibindex_add( const char *dirname, int i );
-void
-netsnmp_mibindex_load( void )
-{
- DIR *dir;
- struct dirent *file;
- FILE *fp;
- char tmpbuf[ 300];
- char tmpbuf2[300];
- int i;
- char *cp;
-
- /*
- * Open the MIB index directory, or create it (empty)
- */
- snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes",
- get_persistent_directory());
- tmpbuf[sizeof(tmpbuf)-1] = 0;
- dir = opendir( tmpbuf );
- if ( dir == NULL ) {
- DEBUGMSGTL(("mibindex", "load: (new)\n"));
- mkdirhier( tmpbuf, NETSNMP_AGENT_DIRECTORY_MODE, 0);
- return;
- }
-
- /*
- * Create a list of which directory each file refers to
- */
- while ((file = readdir( dir ))) {
- if ( !isdigit((unsigned char)(file->d_name[0])))
- continue;
- i = atoi( file->d_name );
-
- snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d",
- get_persistent_directory(), i );
- tmpbuf[sizeof(tmpbuf)-1] = 0;
- fp = fopen( tmpbuf, "r" );
- if (!fp)
- continue;
- cp = fgets( tmpbuf2, sizeof(tmpbuf2), fp );
- fclose( fp );
- if ( !cp ) {
- DEBUGMSGTL(("mibindex", "Empty MIB index (%d)\n", i));
- continue;
- }
- if ( strncmp( tmpbuf2, "DIR ", 4 ) != 0 ) {
- DEBUGMSGTL(("mibindex", "Malformed MIB index (%d)\n", i));
- continue;
- }
- tmpbuf2[strlen(tmpbuf2)-1] = 0;
- DEBUGMSGTL(("mibindex", "load: (%d) %s\n", i, tmpbuf2));
- (void)_mibindex_add( tmpbuf2+4, i ); /* Skip 'DIR ' */
- }
- closedir( dir );
-}
-
-char *
-netsnmp_mibindex_lookup( const char *dirname )
-{
- int i;
- static char tmpbuf[300];
-
- for (i=0; i<_mibindex; i++) {
- if ( _mibindexes[i] &&
- strcmp( _mibindexes[i], dirname ) == 0) {
- snprintf(tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d",
- get_persistent_directory(), i);
- tmpbuf[sizeof(tmpbuf)-1] = 0;
- DEBUGMSGTL(("mibindex", "lookup: %s (%d) %s\n", dirname, i, tmpbuf ));
- return tmpbuf;
- }
- }
- DEBUGMSGTL(("mibindex", "lookup: (none)\n"));
- return NULL;
-}
-
-int
-_mibindex_add( const char *dirname, int i )
-{
- const int old_mibindex_max = _mibindex_max;
-
- DEBUGMSGTL(("mibindex", "add: %s (%d)\n", dirname, i ));
- if ( i == -1 )
- i = _mibindex++;
- if ( i >= _mibindex_max ) {
- /*
- * If the index array is full (or non-existent)
- * then expand (or create) it
- */
- _mibindex_max = i + 10;
- _mibindexes = realloc(_mibindexes,
- _mibindex_max * sizeof(_mibindexes[0]));
- netsnmp_assert(_mibindexes);
- memset(_mibindexes + old_mibindex_max, 0,
- (_mibindex_max - old_mibindex_max) * sizeof(_mibindexes[0]));
- }
-
- _mibindexes[ i ] = strdup( dirname );
- if ( i >= _mibindex )
- _mibindex = i+1;
-
- DEBUGMSGTL(("mibindex", "add: %d/%d/%d\n", i, _mibindex, _mibindex_max ));
- return i;
-}
-
-FILE *
-netsnmp_mibindex_new( const char *dirname )
-{
- FILE *fp;
- char tmpbuf[300];
- char *cp;
- int i;
-
- cp = netsnmp_mibindex_lookup( dirname );
- if (!cp) {
- i = _mibindex_add( dirname, -1 );
- snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d",
- get_persistent_directory(), i );
- tmpbuf[sizeof(tmpbuf)-1] = 0;
- cp = tmpbuf;
- }
- DEBUGMSGTL(("mibindex", "new: %s (%s)\n", dirname, cp ));
- fp = fopen( cp, "w" );
- if (fp)
- fprintf( fp, "DIR %s\n", dirname );
- return fp;
-}
-
-
/**
* Unloads all mibs.
*/
@@ -3038,15 +2901,6 @@ shutdown_mib(void)
}
tree_head = NULL;
Mib = NULL;
- if (_mibindexes) {
- int i;
- for (i = 0; i < _mibindex; ++i)
- SNMP_FREE(_mibindexes[i]);
- free(_mibindexes);
- _mibindex = 0;
- _mibindex_max = 0;
- _mibindexes = NULL;
- }
if (Prefix != NULL && Prefix != &Standard_Prefix[0])
SNMP_FREE(Prefix);
if (Prefix)
diff --git a/snmplib/parse.c b/snmplib/parse.c
index 7678b35..0639112 100644
--- a/snmplib/parse.c
+++ b/snmplib/parse.c
@@ -607,8 +607,6 @@ static int read_module_replacements(const char *);
static int read_import_replacements(const char *,
struct module_import *);
-static void new_module(const char *, const char *);
-
static struct node *merge_parse_objectid(struct node *, FILE *, char *);
static struct index_list *getIndexes(FILE * fp, struct index_list **);
static struct varbind_list *getVarbinds(FILE * fp, struct varbind_list **);
@@ -4859,7 +4857,7 @@ snmp_get_token(FILE * fp, char *token, int maxtlen)
#endif /* NETSNMP_FEATURE_REMOVE_PARSE_GET_TOKEN */
int
-add_mibfile(const char* tmpstr, const char* d_name, FILE *ip )
+add_mibfile(const char* tmpstr, const char* d_name)
{
FILE *fp;
char token[MAXTOKEN], token2[MAXTOKEN];
@@ -4884,8 +4882,6 @@ add_mibfile(const char* tmpstr, const char* d_name, FILE *ip )
*/
if (get_token(fp, token2, MAXTOKEN) == DEFINITIONS) {
new_module(token, tmpstr);
- if (ip)
- fprintf(ip, "%s %s\n", token, d_name);
fclose(fp);
return 0;
} else {
@@ -4903,62 +4899,16 @@ add_mibfile(const char* tmpstr, const char* d_name, FILE *ip )
int
add_mibdir(const char *dirname)
{
- FILE *ip;
DIR *dir, *dir2;
const char *oldFile = File;
struct dirent *file;
char tmpstr[300];
int count = 0;
int fname_len = 0;
-#if !(defined(WIN32) || defined(cygwin))
- char *token;
- char space;
- char newline;
- struct stat dir_stat, idx_stat;
- char tmpstr1[300];
-#endif
DEBUGMSGTL(("parse-mibs", "Scanning directory %s\n", dirname));
-#if !(defined(WIN32) || defined(cygwin))
- token = netsnmp_mibindex_lookup( dirname );
- if (token && stat(token, &idx_stat) == 0 && stat(dirname, &dir_stat) == 0) {
- if (dir_stat.st_mtime < idx_stat.st_mtime) {
- DEBUGMSGTL(("parse-mibs", "The index is good\n"));
- if ((ip = fopen(token, "r")) != NULL) {
- fgets(tmpstr, sizeof(tmpstr), ip); /* Skip dir line */
- while (fscanf(ip, "%127s%c%299[^\n]%c", token, &space, tmpstr,
- &newline) == 4) {
-
- /*
- * If an overflow of the token or tmpstr buffers has been
- * found log a message and break out of the while loop,
- * thus the rest of the file tokens will be ignored.
- */
- if (space != ' ' || newline != '\n') {
- snmp_log(LOG_ERR,
- "add_mibdir: strings scanned in from %s/%s " \
- "are too large. count = %d\n ", dirname,
- ".index", count);
- break;
- }
-
- snprintf(tmpstr1, sizeof(tmpstr1), "%s/%s", dirname, tmpstr);
- tmpstr1[ sizeof(tmpstr1)-1 ] = 0;
- new_module(token, tmpstr1);
- count++;
- }
- fclose(ip);
- return count;
- } else
- DEBUGMSGTL(("parse-mibs", "Can't read index\n"));
- } else
- DEBUGMSGTL(("parse-mibs", "Index outdated\n"));
- } else
- DEBUGMSGTL(("parse-mibs", "No index\n"));
-#endif
if ((dir = opendir(dirname))) {
- ip = netsnmp_mibindex_new( dirname );
while ((file = readdir(dir))) {
/*
* Only parse file names that don't begin with a '.'
@@ -4979,7 +4929,7 @@ add_mibdir(const char *dirname)
*/
closedir(dir2);
} else {
- if ( !add_mibfile( tmpstr, file->d_name, ip ))
+ if ( !add_mibfile( tmpstr, file->d_name ))
count++;
}
}
@@ -4987,8 +4937,6 @@ add_mibdir(const char *dirname)
}
File = oldFile;
closedir(dir);
- if (ip)
- fclose(ip);
return (count);
}
else
--
1.8.3.1