1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Fix potential heap corruption in "gpg -v --version"

* g10/gpg.c (build_list): Rewrite to cope with buffer overflow in
certain locales.
* util/membuf.c (put_membuf_str): New.
(get_membuf): Make LEN optional.
--

This fixes an obvious bug in locales where the translated string is
longer than the original.  The bug could be exhibited by using
LANG=ru_RU.utf8 gpg -v --version.

En passant we also removed the trailing white space on continued
lines.

Reported-by: Dmitry V. Levin" <ldv at altlinux.org>
This commit is contained in:
Werner Koch 2012-12-15 11:28:00 +01:00
parent eb541e35b8
commit e33e74e3a4
4 changed files with 56 additions and 50 deletions

1
THANKS
View File

@ -49,6 +49,7 @@ David R. Bergstein dbergstein@home.com
David Shaw dshaw@jabberwocky.com David Shaw dshaw@jabberwocky.com
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
Dimitri dmitri@advantrix.com Dimitri dmitri@advantrix.com
Dmitry V. Levin ldv at altlinux dot org
Dirk Lattermann dlatt@t-online.de Dirk Lattermann dlatt@t-online.de
Dirk Meyer dirk.meyer@dinoex.sub.org Dirk Meyer dirk.meyer@dinoex.sub.org
Disastry Disastry@saiknes.lv Disastry Disastry@saiknes.lv

View File

@ -835,57 +835,53 @@ strusage( int level )
static char * static char *
build_list( const char *text, char letter, build_list (const char *text, char letter,
const char * (*mapf)(int), int (*chkf)(int) ) const char * (*mapf)(int), int (*chkf)(int))
{ {
int i; membuf_t mb;
int indent;
int i, j, len;
const char *s; const char *s;
size_t n=strlen(text)+2; char *string;
char *list, *p, *line=NULL;
if( maybe_setuid ) if (maybe_setuid)
secmem_init( 0 ); /* drop setuid */ secmem_init (0); /* Drop setuid */
for(i=0; i <= 110; i++ ) indent = strlen (text);
if( !chkf(i) && (s=mapf(i)) ) len = 0;
n += strlen(s) + 7 + 2; init_membuf (&mb, 512);
list = xmalloc( 21 + n ); *list = 0;
for(p=NULL, i=0; i <= 110; i++ ) {
if( !chkf(i) && (s=mapf(i)) ) {
if( !p ) {
p = stpcpy( list, text );
line=p;
}
else
p = stpcpy( p, ", ");
if(strlen(line)>60) { for (i=0; i <= 110; i++ )
int spaces=strlen(text);
list=xrealloc(list,n+spaces+1);
/* realloc could move the block, so find the end again */
p=list;
while(*p)
p++;
p=stpcpy(p, "\n");
line=p;
for(;spaces;spaces--)
p=stpcpy(p, " ");
}
p = stpcpy(p, s );
if(opt.verbose && letter)
{ {
char num[8]; if (!chkf (i) && (s = mapf (i)))
sprintf(num," (%c%d)",letter,i); {
p = stpcpy(p,num); if (mb.len - len > 60)
{
put_membuf_str (&mb, ",\n");
len = mb.len;
for (j=0; j < indent; j++)
put_membuf_str (&mb, " ");
}
else if (mb.len)
put_membuf_str (&mb, ", ");
else
put_membuf_str (&mb, text);
put_membuf_str (&mb, s);
if (opt.verbose && letter)
{
char num[20];
snprintf (num, sizeof num, " (%c%d)", letter, i);
put_membuf_str (&mb, num);
} }
} }
} }
if( p ) if (mb.len)
p = stpcpy(p, "\n" ); put_membuf_str (&mb, "\n");
return list; put_membuf (&mb, "", 1);
string = get_membuf (&mb, NULL);
return xrealloc (string, strlen (string)+1);
} }

View File

@ -219,6 +219,7 @@ typedef struct private_membuf_s membuf_t;
void init_membuf (membuf_t *mb, int initiallen); void init_membuf (membuf_t *mb, int initiallen);
void put_membuf (membuf_t *mb, const void *buf, size_t len); void put_membuf (membuf_t *mb, const void *buf, size_t len);
void put_membuf_str (membuf_t *mb, const char *buf);
void *get_membuf (membuf_t *mb, size_t *len); void *get_membuf (membuf_t *mb, size_t *len);

View File

@ -62,6 +62,13 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
} }
void
put_membuf_str (membuf_t *mb, const char *buf)
{
put_membuf (mb, buf, strlen (buf));
}
void * void *
get_membuf (membuf_t *mb, size_t *len) get_membuf (membuf_t *mb, size_t *len)
{ {
@ -75,6 +82,7 @@ get_membuf (membuf_t *mb, size_t *len)
} }
p = mb->buf; p = mb->buf;
if (len)
*len = mb->len; *len = mb->len;
mb->buf = NULL; mb->buf = NULL;
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */ mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */