1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-07 23:27:48 +02:00

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

* g10/gpg.c (build_list): Rewrite to cope with buffer overflow in
certain locales.
--

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>

(cherry picked from commit 3402a84720)

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2012-12-15 11:28:00 +01:00
parent d6798d261c
commit 151b78cc26

View File

@ -40,6 +40,7 @@
#include "../common/iobuf.h" #include "../common/iobuf.h"
#include "util.h" #include "util.h"
#include "packet.h" #include "packet.h"
#include "membuf.h"
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
#include "keydb.h" #include "keydb.h"
@ -895,57 +896,53 @@ my_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;
const char *s; int indent;
size_t n=strlen(text)+2; int i, j, len;
char *list, *p, *line=NULL; const char *s;
char *string;
if (maybe_setuid) if (maybe_setuid)
gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* Drop setuid. */ gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* Drop setuid. */
for(i=0; i <= 110; i++ ) indent = utf8_charcount (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++ ) { for (i=0; i <= 110; i++ )
if( !chkf(i) && (s=mapf(i)) ) { {
if( !p ) { if (!chkf (i) && (s = mapf (i)))
p = stpcpy( list, text ); {
line=p; if (mb.len - len > 60)
{
put_membuf_str (&mb, ",\n");
len = mb.len;
for (j=0; j < indent; j++)
put_membuf_str (&mb, " ");
} }
else else if (mb.len)
p = stpcpy( p, ", "); put_membuf_str (&mb, ", ");
else
put_membuf_str (&mb, text);
if(strlen(line)>60) { put_membuf_str (&mb, s);
int spaces=strlen(text); if (opt.verbose && letter)
{
list=xrealloc(list,n+spaces+1); char num[20];
/* realloc could move the block, so find the end again */ snprintf (num, sizeof num, " (%c%d)", letter, i);
p=list; put_membuf_str (&mb, num);
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];
sprintf(num," (%c%d)",letter,i);
p = stpcpy(p,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);
} }