Mikulas Patocka
2012-Apr-09 22:04 UTC
[Secure-testing-team] Bug#668227: links2: security bugs in links
Package: links2 Version: 2.3~pre1-1 Severity: grave Tags: security Justification: user security hole I discovered some out of memory accesses in links2 graphics mode that could be potentially used to run exploits. I fixed them in links-2.6. For Debian Squeeze, I am sending this patch that backports the fixes to links-2.3pre1. Apply the patch and distribute patched packages links and links2 through security.debian.org. -- System Information: Debian Release: 6.0.4 APT prefers stable APT policy: (500, ''stable'') Architecture: amd64 (x86_64) Kernel: Linux 3.3.0 (SMP w/8 CPU cores; PREEMPT) Locale: LANG=cs_CZ, LC_CTYPE=cs_CZ (charmap=ISO-8859-2) Shell: /bin/sh linked to /bin/dash Versions of packages links2 depends on: ii libc6 2.11.3-2 Embedded GNU C Library: Shared lib ii libdirectfb-1.2-9 1.2.10.0-4 direct frame buffer graphics - sha ii libgpm2 1.20.4-3.3 General Purpose Mouse - shared lib ii libjpeg62 6b1-1 The Independent JPEG Group''s JPEG ii libpng12-0 1.2.44-1+squeeze4 PNG library - runtime ii libssl0.9.8 0.9.8o-4squeeze7 SSL shared libraries ii libsvga1 1:1.4.3-29 console SVGA display libraries ii libtiff4 3.9.6 Empty libtiff4 package ii libx11-6 2:1.3.3-4 X11 client-side library ii zlib1g 1:1.2.3.4.dfsg-3 compression library - runtime links2 recommends no packages. links2 suggests no packages. -- no debconf information -------------- next part -------------- This patch fixes: Buffer overflow when pasting too long text from clipboard to dialog boxes (not remotely exploitable) A write out of allocated memory in the graphics rendeder (potentionally exploitable) An infinite loop when parsing invalid usemap specification in text and graphics mode (can cause browser lockup, but not otherwise exploitable) Accesses out of memory in the xbm decoder (potentionally exploitable) --- bfu.c | 3 ++- dip.c | 3 ++- html.c | 6 +++++- xbm.c | 20 ++++++++++---------- 4 files changed, 19 insertions(+), 13 deletions(-) Index: links-2.3pre1/bfu.c ==================================================================--- links-2.3pre1.orig/bfu.c 2012-04-09 23:39:47.000000000 +0200 +++ links-2.3pre1/bfu.c 2012-04-09 23:39:56.000000000 +0200 @@ -1382,7 +1382,8 @@ void dialog_func(struct window *win, str clipbd_paste: clipboard = get_clipboard_text(term); if (clipboard) { - if (strlen(di->cdata) < di->item->dlen - strlen(clipboard)) { + if (strlen(di->cdata) + strlen(clipboard) < (size_t)di->item->dlen || + strlen(di->cdata) + strlen(clipboard) < strlen(di->cdata)) { memmove(di->cdata + di->cpos + strlen(clipboard), di->cdata + di->cpos, strlen(di->cdata) - di->cpos + 1); memcpy(&di->cdata[di->cpos], clipboard, strlen(clipboard)); di->cpos += strlen(clipboard); Index: links-2.3pre1/dip.c ==================================================================--- links-2.3pre1.orig/dip.c 2012-04-09 23:39:47.000000000 +0200 +++ links-2.3pre1/dip.c 2012-04-09 23:39:56.000000000 +0200 @@ -1901,6 +1901,7 @@ int g_wrap_text(struct wrap_struct *w) while (*w->text) { int u; int s; + unsigned char *l_text = w->text; if (*w->text == '' '') w->last_wrap = w->text, w->last_wrap_obj = w->obj; GET_UTF_8(w->text, u); @@ -1913,7 +1914,7 @@ int g_wrap_text(struct wrap_struct *w) if (u != 0xad || *w->text == '' '') continue; s = g_char_width(w->style, ''-''); if (w->pos + s <= w->width || (!w->last_wrap && !w->last_wrap_obj)) { - w->last_wrap = w->text; + w->last_wrap = l_text; w->last_wrap_obj = w->obj; continue; } Index: links-2.3pre1/html.c ==================================================================--- links-2.3pre1.orig/html.c 2012-04-09 23:39:47.000000000 +0200 +++ links-2.3pre1/html.c 2012-04-09 23:39:56.000000000 +0200 @@ -2920,6 +2920,7 @@ int get_image_map(unsigned char *head, u lblen = 0; se3: ss = s; + se4: while (ss < eof && *ss != ''<'') ss++; if (ss >= eof) { mem_free(label); @@ -2933,7 +2934,10 @@ int get_image_map(unsigned char *head, u s = skip_comment(s, eof); goto se3; } - if (parse_element(s, eof, NULL, NULL, NULL, &ss)) goto se3; + if (parse_element(s, eof, NULL, NULL, NULL, &ss)) { + ss = s + 1; + goto se4; + } if (!((namelen == 1 && !casecmp(name, "A", 1)) || (namelen == 2 && !casecmp(name, "/A", 2)) || (namelen == 3 && !casecmp(name, "MAP", 3)) || Index: links-2.3pre1/xbm.c ==================================================================--- links-2.3pre1.orig/xbm.c 2012-04-09 23:39:47.000000000 +0200 +++ links-2.3pre1/xbm.c 2012-04-09 23:39:56.000000000 +0200 @@ -44,7 +44,7 @@ struct xbm_decoder{ extern int get_foreground(int rgb); unsigned char *my_memmem(unsigned char *, int, unsigned char *, int); -void xbm_decode(struct cached_image *, unsigned char *, int); +int xbm_decode(struct cached_image *, unsigned char *, int); unsigned char *my_memmem(unsigned char *h, int hl, unsigned char *n, int nl) @@ -138,7 +138,7 @@ static inline void put_eight(struct cach /* opravdovy dekoder xbm, data jsou bez komentaru */ /* length is always !=NULL */ -void xbm_decode(struct cached_image *cimg, unsigned char *data, int length) +int xbm_decode(struct cached_image *cimg, unsigned char *data, int length) { struct xbm_decoder *deco=(struct xbm_decoder *)cimg->decoder; /* okurky v decu ;-) */ @@ -146,13 +146,13 @@ void xbm_decode(struct cached_image *cim int must_return=0; restart_again: - if (must_return&&!length)return; + if (must_return&&!length)return 0; must_return=0; a=min(length,XBM_BUFFER_LEN-deco->buffer_pos); memcpy(deco->buffer+deco->buffer_pos,data,a); length-=a; deco->buffer_pos+=a; - if (!deco->buffer_pos)return; /* z toho nic plodnyho nevznikne */ + if (!deco->buffer_pos)return 0; /* z toho nic plodnyho nevznikne */ data+=a; if (!deco->in_data_block&&deco->partnum) { @@ -220,7 +220,7 @@ restart_again: cimg->green_gamma=display_green_gamma; cimg->blue_gamma=display_blue_gamma; cimg->strip_optimized=0; - if (header_dimensions_known(cimg)) {img_end(cimg);return;} + if (header_dimensions_known(cimg)) {img_end(cimg);return 1;} deco->in_data_block=1; p++; @@ -239,7 +239,7 @@ restart_again: deco->buffer_pos=a; if (deco->partnum)must_return=1; else put_eight(cimg,(b==16&&d>2)||(b==10&&deco->actual_eight>255)?16:8); - if (deco->image_pos>=deco->pixels) {img_end(cimg);return;} + if (deco->image_pos>=deco->pixels) {img_end(cimg);return 1;} goto restart_again; } @@ -261,9 +261,9 @@ cycle_again: unsigned char *p; p=memchr(data,''/'',length); if (!p){xbm_decode(cimg, data, length);return;} - xbm_decode(cimg, data, p-data); - data=p+1; /* preskocim lomitko */ + if (xbm_decode(cimg, data, p-data)) return; length-=p-data+1; + data=p+1; /* preskocim lomitko */ deco->state=1; goto cycle_again; } @@ -271,7 +271,7 @@ cycle_again: case 1: /* za 1. lomitkem */ { if (*data==''*''){deco->state=2;data++;length--;goto cycle_again;} /* zacal komentar */ - xbm_decode(cimg, "/", 1); + if (xbm_decode(cimg, "/", 1)) return; deco->state=0; /* to nebyl komentar */ goto cycle_again; } @@ -281,8 +281,8 @@ cycle_again: unsigned char *p; p=memchr(data,''*'',length); if (!p)return; /* furt komentar */ - data=p+1; /* preskocim hvezdicku */ length-=p-data+1; + data=p+1; /* preskocim hvezdicku */ deco->state=3; goto cycle_again; }