[msitools: 4/6] libmsi: allocate decoded stream name to avoid buffer overflow
- From: Marc-André Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [msitools: 4/6] libmsi: allocate decoded stream name to avoid buffer overflow
- Date: Tue, 16 Mar 2021 11:16:09 +0000 (UTC)
commit ab4b63dc815812df8eee0cbab9d8a4c70315469c
Author: Marc-André Lureau <marcandre lureau redhat com>
Date: Tue Mar 16 13:28:53 2021 +0400
libmsi: allocate decoded stream name to avoid buffer overflow
Fixes #36 "Buffer overflow in create_stream"
libmsi/libmsi-database.c | 13 +++++++------
libmsi/msipriv.h | 2 +-
libmsi/streams.c | 4 ++--
libmsi/table.c | 26 +++++++++++++++++---------
4 files changed, 27 insertions(+), 18 deletions(-)
---
diff --git a/libmsi/libmsi-database.c b/libmsi/libmsi-database.c
index e02d65c..e0c68cc 100644
--- a/libmsi/libmsi-database.c
+++ b/libmsi/libmsi-database.c
@@ -491,10 +491,10 @@ unsigned clone_infile_stream( LibmsiDatabase *db, const char *name, GsfInput **s
unsigned msi_get_raw_stream( LibmsiDatabase *db, const char *stname, GsfInput **stm )
{
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- char decoded[MAX_STREAM_NAME_LEN];
+ g_autofree char *decoded = NULL;
LibmsiTransform *transform;
- decode_streamname( stname, decoded );
+ decoded = decode_streamname(stname);
TRACE("%s -> %s\n", debugstr_a(stname), debugstr_a(decoded));
if (clone_infile_stream( db, stname, stm ) == LIBMSI_RESULT_SUCCESS)
@@ -2110,7 +2110,6 @@ libmsi_database_is_readonly (LibmsiDatabase *db)
static void cache_infile_structure( LibmsiDatabase *db )
{
int i, n;
- char decname[0x40];
unsigned r;
n = gsf_infile_num_children(db->infile);
@@ -2132,7 +2131,9 @@ static void cache_infile_structure( LibmsiDatabase *db )
/* UTF-8 encoding of 0x4840. */
if (name8[0] == 0xe4 && name8[1] == 0xa1 && name8[2] == 0x80)
{
- decode_streamname(name + 3, decname);
+ g_autofree char *decname = NULL;
+
+ decname = decode_streamname(name + 3);
if ( !strcmp( decname, szStringPool ) ||
!strcmp( decname, szStringData ) )
continue;
@@ -2340,9 +2341,9 @@ static unsigned commit_stream( const char *name, GsfInput *stm, void *opaque)
LibmsiDatabase *db = opaque;
GsfOutput *outstm;
unsigned ret = LIBMSI_RESULT_FUNCTION_FAILED;
- char decname[0x40];
+ g_autofree char *decname = NULL;
- decode_streamname(name, decname);
+ decname = decode_streamname(name);
TRACE("%s(%s) %p %p\n", debugstr_a(name), debugstr_a(decname), stm, opaque);
outstm = gsf_outfile_new_child( db->outfile, name, false );
diff --git a/libmsi/msipriv.h b/libmsi/msipriv.h
index f7a80a6..35dbb91 100644
--- a/libmsi/msipriv.h
+++ b/libmsi/msipriv.h
@@ -389,7 +389,7 @@ extern bool _libmsi_record_compare_fields(const LibmsiRecord *a, const LibmsiRec
/* stream internals */
extern void enum_stream_names( GsfInfile *stg );
extern char *encode_streamname(bool bTable, const char *in);
-extern void decode_streamname(const char *in, char *out);
+extern char *decode_streamname(const char *in);
/* database internals */
extern LibmsiResult _libmsi_database_start_transaction(LibmsiDatabase *db);
diff --git a/libmsi/streams.c b/libmsi/streams.c
index 379dcee..025e53c 100644
--- a/libmsi/streams.c
+++ b/libmsi/streams.c
@@ -62,7 +62,7 @@ static bool streams_set_table_size(LibmsiStreamsView *sv, unsigned size)
static STREAM *create_stream(LibmsiStreamsView *sv, const char *name, bool encoded, GsfInput *stm)
{
STREAM *stream;
- char decoded[MAX_STREAM_NAME_LEN];
+ g_autofree char *decoded = NULL;
stream = msi_alloc(sizeof(STREAM));
if (!stream)
@@ -70,7 +70,7 @@ static STREAM *create_stream(LibmsiStreamsView *sv, const char *name, bool encod
if (encoded)
{
- decode_streamname(name, decoded);
+ decoded = decode_streamname(name);
TRACE("stream -> %s %s\n", debugstr_a(name), debugstr_a(decoded));
name = decoded;
}
diff --git a/libmsi/table.c b/libmsi/table.c
index 5c207e3..5e0a6f8 100644
--- a/libmsi/table.c
+++ b/libmsi/table.c
@@ -188,12 +188,16 @@ static int mime2utf(int x)
return '_';
}
-void decode_streamname(const char *in, char *out)
+char *decode_streamname(const char *in)
{
unsigned count = 0;
const uint8_t *p = (const uint8_t *)in;
- uint8_t *q = (uint8_t *)out;
+ char *out;
+ uint8_t *q;
+ g_return_val_if_fail(in != NULL, NULL);
+ out = g_malloc0(strlen(in) + 1);
+ q = (uint8_t *)out;
while ( *p )
{
uint8_t ch = *p;
@@ -226,18 +230,23 @@ void decode_streamname(const char *in, char *out)
count++;
}
*q = 0;
+ return out;
}
void enum_stream_names( GsfInfile *stg )
{
unsigned n, i;
- char name[0x40];
n = gsf_infile_num_children(stg);
for (i = 0; i < n; i++)
{
+ g_autofree char *name = NULL;
const char *stname = gsf_infile_name_by_index(stg, i);
- decode_streamname( stname, name );
+
+ if (!stname)
+ continue;
+
+ name = decode_streamname(stname);
TRACE("stream %2d -> %s %s\n", n,
debugstr_a(stname), debugstr_a(name) );
}
@@ -562,15 +571,14 @@ static unsigned table_get_column_info( LibmsiDatabase *db, const char *name, Lib
unsigned _libmsi_open_table( LibmsiDatabase *db, const char *name, bool encoded )
{
- char decname[0x40];
+ g_autofree char *decname = NULL;
LibmsiTable *table;
guint8 *name8 = (guint8*)name;
if (encoded)
{
assert(name8[0] == 0xe4 && name8[1] == 0xa1 && name8[2] == 0x80);
- decode_streamname( name + 1, decname );
- name = decname;
+ decname = decode_streamname(name + 1);
}
table = msi_alloc_zero( sizeof(LibmsiTable) + strlen( name ) * sizeof(char) );
@@ -2568,13 +2576,13 @@ unsigned msi_table_apply_transform( LibmsiDatabase *db, GsfInfile *stg )
{
LibmsiTableView *tv = NULL;
const uint8_t *encname;
- char name[0x40];
+ g_autofree char *name = NULL;
encname = (const uint8_t *) gsf_infile_name_by_index(stg, i);
if ( encname[0] != 0xe4 || encname[1] != 0xa1 || encname[2] != 0x80)
continue;
- decode_streamname( (char*)encname, name );
+ name = decode_streamname((char*)encname);
if ( !strcmp( name+3, szStringPool ) ||
!strcmp( name+3, szStringData ) )
continue;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]