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:
parent
eb541e35b8
commit
e33e74e3a4
1
THANKS
1
THANKS
@ -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
|
||||||
|
80
g10/gpg.c
80
g10/gpg.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user