Fix possible null pointer dereference in identify_data BIF.

There was no check/handling for if magic_buffer() returns null.
Also centralized libmagic calls for consistent error handling/output.
This commit is contained in:
Jon Siwek 2013-02-27 16:04:36 -06:00
parent dd9f361bc7
commit 2481f9f837
5 changed files with 47 additions and 46 deletions

View file

@ -2,6 +2,7 @@
#include "FileAnalyzer.h" #include "FileAnalyzer.h"
#include "Reporter.h" #include "Reporter.h"
#include "util.h"
magic_t File_Analyzer::magic = 0; magic_t File_Analyzer::magic = 0;
magic_t File_Analyzer::magic_mime = 0; magic_t File_Analyzer::magic_mime = 0;
@ -11,11 +12,8 @@ File_Analyzer::File_Analyzer(Connection* conn)
{ {
buffer_len = 0; buffer_len = 0;
if ( ! magic ) bro_init_magic(&magic, MAGIC_NONE);
{ bro_init_magic(&magic_mime, MAGIC_MIME);
InitMagic(&magic, MAGIC_NONE);
InitMagic(&magic_mime, MAGIC_MIME);
}
} }
void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig) void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
@ -49,10 +47,10 @@ void File_Analyzer::Identify()
const char* mime = 0; const char* mime = 0;
if ( magic ) if ( magic )
descr = magic_buffer(magic, buffer, buffer_len); descr = bro_magic_buffer(magic, buffer, buffer_len);
if ( magic_mime ) if ( magic_mime )
mime = magic_buffer(magic_mime, buffer, buffer_len); mime = bro_magic_buffer(magic_mime, buffer, buffer_len);
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
@ -61,18 +59,3 @@ void File_Analyzer::Identify()
vl->append(new StringVal(mime ? mime : "<unknown>")); vl->append(new StringVal(mime ? mime : "<unknown>"));
ConnectionEvent(file_transferred, vl); ConnectionEvent(file_transferred, vl);
} }
void File_Analyzer::InitMagic(magic_t* magic, int flags)
{
*magic = magic_open(flags);
if ( ! *magic )
reporter->Error("can't init libmagic: %s", magic_error(*magic));
else if ( magic_load(*magic, 0) < 0 )
{
reporter->Error("can't load magic file: %s", magic_error(*magic));
magic_close(*magic);
*magic = 0;
}
}

View file

@ -29,8 +29,6 @@ protected:
char buffer[BUFFER_SIZE]; char buffer[BUFFER_SIZE];
int buffer_len; int buffer_len;
static void InitMagic(magic_t* magic, int flags);
static magic_t magic; static magic_t magic;
static magic_t magic_mime; static magic_t magic_mime;
}; };

View file

@ -16,6 +16,7 @@
#include "digest.h" #include "digest.h"
#include "Reporter.h" #include "Reporter.h"
#include "IPAddr.h" #include "IPAddr.h"
#include "util.h"
using namespace std; using namespace std;
@ -844,38 +845,21 @@ extern "C" {
## return_mime: If true, the function returns a short MIME type string (e.g., ## return_mime: If true, the function returns a short MIME type string (e.g.,
## ``text/plain`` instead of a more elaborate textual description). ## ``text/plain`` instead of a more elaborate textual description).
## ##
## Returns: The MIME type of *data*. ## Returns: The MIME type of *data*, or "<unknown>" if there was an error.
function identify_data%(data: string, return_mime: bool%): string function identify_data%(data: string, return_mime: bool%): string
%{ %{
const char* descr = "";
static magic_t magic_mime = 0; static magic_t magic_mime = 0;
static magic_t magic_descr = 0; static magic_t magic_descr = 0;
magic_t* magic = return_mime ? &magic_mime : &magic_descr; magic_t* magic = return_mime ? &magic_mime : &magic_descr;
bro_init_magic(magic, return_mime ? MAGIC_MIME : MAGIC_NONE);
if( ! *magic ) if( ! *magic )
{ return new StringVal("<unknown>");
*magic = magic_open(return_mime ? MAGIC_MIME : MAGIC_NONE);
if ( ! *magic ) const char* desc = bro_magic_buffer(*magic, data->Bytes(), data->Len());
{
reporter->Error("can't init libmagic: %s", magic_error(*magic));
return new StringVal("");
}
if ( magic_load(*magic, 0) < 0 ) return new StringVal(desc ? desc : "<unknown>");
{
reporter->Error("can't load magic file: %s", magic_error(*magic));
magic_close(*magic);
*magic = 0;
return new StringVal("");
}
}
descr = magic_buffer(*magic, data->Bytes(), data->Len());
return new StringVal(descr);
%} %}
## Performs an entropy test on the given data. ## Performs an entropy test on the given data.

View file

@ -1527,3 +1527,35 @@ void operator delete[](void* v)
} }
#endif #endif
void bro_init_magic(magic_t* cookie_ptr, int flags)
{
if ( ! cookie_ptr || *cookie_ptr ) return;
*cookie_ptr = magic_open(flags);
if ( ! *cookie_ptr )
{
const char* err = magic_error(*cookie_ptr);
reporter->Error("can't init libmagic: %s", err ? err : "unknown");
}
else if ( magic_load(*cookie_ptr, 0) < 0 )
{
const char* err = magic_error(*cookie_ptr);
reporter->Error("can't load magic file: %s", err ? err : "unknown");
magic_close(*cookie_ptr);
*cookie_ptr = 0;
}
}
const char* bro_magic_buffer(magic_t cookie, const void* buffer, size_t length)
{
const char* rval = magic_buffer(cookie, buffer, length);
if ( ! rval )
{
const char* err = magic_error(cookie);
reporter->Error("magic_buffer error: %s", err ? err : "unknown");
}
return rval;
}

View file

@ -15,6 +15,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <magic.h>
#include "config.h" #include "config.h"
#if __STDC__ #if __STDC__
@ -364,4 +365,7 @@ struct CompareString
} }
}; };
void bro_init_magic(magic_t* cookie_ptr, int flags);
const char* bro_magic_buffer(magic_t cookie, const void* buffer, size_t length);
#endif #endif