Mail archive
alpine-aports

[alpine-aports] Re: [PATCH 3.0-stable] main/putty: fix CVE-2015-5309

From: Christian Kampka <christian_at_kampka.net>
Date: Wed, 02 Dec 2015 18:39:16 +0000

This patch has been superseded by v2 because of missing pkgrel bump.

Christian Kampka <christian_at_kampka.net> schrieb am Mi., 2. Dez. 2015 um
19:30 Uhr:

> fixes #4912
> ---
> main/putty/APKBUILD | 14 ++-
> main/putty/CVE-2015-5309.patch | 250
> +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 259 insertions(+), 5 deletions(-)
> create mode 100644 main/putty/CVE-2015-5309.patch
>
> diff --git a/main/putty/APKBUILD b/main/putty/APKBUILD
> index 23acdd8..ae8b173 100644
> --- a/main/putty/APKBUILD
> +++ b/main/putty/APKBUILD
> _at__at_ -11,7 +11,9 @@ depends_dev=
> makedepends="$depends_dev"
> install=""
> subpackages="$pkgname-doc"
> -source="http://the.earth.li/~sgtatham/putty/latest/putty-$pkgver.tar.gz"
> +source="http://the.earth.li/~sgtatham/putty/$pkgver/putty-$pkgver.tar.gz
> + CVE-2015-5309.patch
> + "
>
> _builddir="$srcdir"/putty-$pkgver
> prepare() {
> _at__at_ -38,7 +40,9 @@ package() {
> cd "$_builddir"
> make DESTDIR="$pkgdir" install || return 1
> }
> -
> -md5sums="75ff711e8b7cc9e0073bc511e1c1c14a putty-0.64.tar.gz"
> -sha256sums="2a46c97a184144e3ec2392aca9acc64d062317a3a38b9a5f623a147eda5f3821
> putty-0.64.tar.gz"
> -sha512sums="ba4d4086b8edcb6388924bf3d9b018841be36a9dbf298271c9d2ed063aae9854093e9ff6808bd1f65669d78369548639eb3c95fdec5e3f0daee4b1c7bb603051
> putty-0.64.tar.gz"
> +md5sums="75ff711e8b7cc9e0073bc511e1c1c14a putty-0.64.tar.gz
> +dfdc6d6f52e33811ce72f6f1614f71e8 CVE-2015-5309.patch"
> +sha256sums="2a46c97a184144e3ec2392aca9acc64d062317a3a38b9a5f623a147eda5f3821
> putty-0.64.tar.gz
> +b49a26d0ad2578acbe7e106fad010d333ca09ce5272774e4e2ce3805f37f9780
> CVE-2015-5309.patch"
> +sha512sums="ba4d4086b8edcb6388924bf3d9b018841be36a9dbf298271c9d2ed063aae9854093e9ff6808bd1f65669d78369548639eb3c95fdec5e3f0daee4b1c7bb603051
> putty-0.64.tar.gz
> +692f06ed53b8d4a6b3d041ece83d0d36601d0fcaa0b7a207b52ed57be0dea108681785466f65599ab85f4b8d164b0849c7d0b3f0f54999517390f06547163e5a
> CVE-2015-5309.patch"
> diff --git a/main/putty/CVE-2015-5309.patch
> b/main/putty/CVE-2015-5309.patch
> new file mode 100644
> index 0000000..2225b2c
> --- /dev/null
> +++ b/main/putty/CVE-2015-5309.patch
> _at__at_ -0,0 +1,250 @@
> +From 6056396f77cafc7e40da4d09f1d6212408dcb065 Mon Sep 17 00:00:00 2001
> +From: Ben Harris <bjh21_at_bjh21.me.uk>
> +Date: Wed, 7 Oct 2015 23:54:39 +0100
> +Subject: [PATCH] More robust control sequence parameter handling.
> +
> +Parameters are now accumulated in unsigned integers and carefully checked
> +for overflow (which is turned into saturation). Things that consume them
> +now have explicit range checks (again, saturating) to ensure that their
> +inputs are sane. This should make it much harder to cause overflow by
> +supplying ludicrously large numbers.
> +
> +Fixes two bugs found with the help of afl-fuzz. One of them may be
> +exploitable and is CVE-2015-5309.
> +---
> + terminal.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
> + terminal.h | 2 +-
> + 2 files changed, 44 insertions(+), 7 deletions(-)
> +
> +diff --git a/terminal.c b/terminal.c
> +index d8d0ea0..c7e2647 100644
> +--- a/terminal.c
> ++++ b/terminal.c
> +_at__at_ -5,6 +5,7 @@
> + #include <stdio.h>
> + #include <stdlib.h>
> + #include <ctype.h>
> ++#include <limits.h>
> +
> + #include <time.h>
> + #include <assert.h>
> +_at__at_ -3493,8 +3494,15 @@ static void term_out(Terminal *term)
> + if (term->esc_nargs <= ARGS_MAX) {
> + if (term->esc_args[term->esc_nargs - 1] ==
> ARG_DEFAULT)
> + term->esc_args[term->esc_nargs - 1] = 0;
> +- term->esc_args[term->esc_nargs - 1] =
> +- 10 * term->esc_args[term->esc_nargs - 1] + c -
> '0';
> ++ if (term->esc_args[term->esc_nargs - 1] <=
> ++ UINT_MAX / 10 &&
> ++ term->esc_args[term->esc_nargs - 1] * 10 <=
> ++ UINT_MAX - c - '0')
> ++ term->esc_args[term->esc_nargs - 1] =
> ++ 10 * term->esc_args[term->esc_nargs - 1] +
> ++ c - '0';
> ++ else
> ++ term->esc_args[term->esc_nargs - 1] = UINT_MAX;
> + }
> + term->termstate = SEEN_CSI;
> + } else if (c == ';') {
> +_at__at_ -3510,8 +3518,10 @@ static void term_out(Terminal *term)
> + term->esc_query = c;
> + term->termstate = SEEN_CSI;
> + } else
> ++#define CLAMP(arg, lim) ((arg) = ((arg) > (lim)) ? (lim) : (arg))
> + switch (ANSI(c, term->esc_query)) {
> + case 'A': /* CUU: move up N lines */
> ++ CLAMP(term->esc_args[0], term->rows);
> + move(term, term->curs.x,
> + term->curs.y - def(term->esc_args[0], 1), 1);
> + seen_disp_event(term);
> +_at__at_ -3520,6 +3530,7 @@ static void term_out(Terminal *term)
> + compatibility(ANSI);
> + /* FALLTHROUGH */
> + case 'B': /* CUD: Cursor down */
> ++ CLAMP(term->esc_args[0], term->rows);
> + move(term, term->curs.x,
> + term->curs.y + def(term->esc_args[0], 1), 1);
> + seen_disp_event(term);
> +_at__at_ -3535,23 +3546,27 @@ static void term_out(Terminal *term)
> + compatibility(ANSI);
> + /* FALLTHROUGH */
> + case 'C': /* CUF: Cursor right */
> ++ CLAMP(term->esc_args[0], term->cols);
> + move(term, term->curs.x + def(term->esc_args[0],
> 1),
> + term->curs.y, 1);
> + seen_disp_event(term);
> + break;
> + case 'D': /* CUB: move left N cols */
> ++ CLAMP(term->esc_args[0], term->cols);
> + move(term, term->curs.x - def(term->esc_args[0],
> 1),
> + term->curs.y, 1);
> + seen_disp_event(term);
> + break;
> + case 'E': /* CNL: move down N lines and CR */
> + compatibility(ANSI);
> ++ CLAMP(term->esc_args[0], term->rows);
> + move(term, 0,
> + term->curs.y + def(term->esc_args[0], 1), 1);
> + seen_disp_event(term);
> + break;
> + case 'F': /* CPL: move up N lines and CR */
> + compatibility(ANSI);
> ++ CLAMP(term->esc_args[0], term->rows);
> + move(term, 0,
> + term->curs.y - def(term->esc_args[0], 1), 1);
> + seen_disp_event(term);
> +_at__at_ -3559,12 +3574,14 @@ static void term_out(Terminal *term)
> + case 'G': /* CHA */
> + case '`': /* HPA: set horizontal posn */
> + compatibility(ANSI);
> ++ CLAMP(term->esc_args[0], term->cols);
> + move(term, def(term->esc_args[0], 1) - 1,
> + term->curs.y, 0);
> + seen_disp_event(term);
> + break;
> + case 'd': /* VPA: set vertical posn */
> + compatibility(ANSI);
> ++ CLAMP(term->esc_args[0], term->rows);
> + move(term, term->curs.x,
> + ((term->dec_om ? term->marg_t : 0) +
> + def(term->esc_args[0], 1) - 1),
> +_at__at_ -3575,6 +3592,8 @@ static void term_out(Terminal *term)
> + case 'f': /* HVP: set horz and vert posns at
> once */
> + if (term->esc_nargs < 2)
> + term->esc_args[1] = ARG_DEFAULT;
> ++ CLAMP(term->esc_args[0], term->rows);
> ++ CLAMP(term->esc_args[1], term->cols);
> + move(term, def(term->esc_args[1], 1) - 1,
> + ((term->dec_om ? term->marg_t : 0) +
> + def(term->esc_args[0], 1) - 1),
> +_at__at_ -3610,6 +3629,7 @@ static void term_out(Terminal *term)
> + break;
> + case 'L': /* IL: insert lines */
> + compatibility(VT102);
> ++ CLAMP(term->esc_args[0], term->rows);
> + if (term->curs.y <= term->marg_b)
> + scroll(term, term->curs.y, term->marg_b,
> + -def(term->esc_args[0], 1), FALSE);
> +_at__at_ -3617,6 +3637,7 @@ static void term_out(Terminal *term)
> + break;
> + case 'M': /* DL: delete lines */
> + compatibility(VT102);
> ++ CLAMP(term->esc_args[0], term->rows);
> + if (term->curs.y <= term->marg_b)
> + scroll(term, term->curs.y, term->marg_b,
> + def(term->esc_args[0], 1),
> +_at__at_ -3626,11 +3647,13 @@ static void term_out(Terminal *term)
> + case '_at_': /* ICH: insert chars */
> + /* XXX VTTEST says this is vt220, vt510 manual
> says vt102 */
> + compatibility(VT102);
> ++ CLAMP(term->esc_args[0], term->cols);
> + insch(term, def(term->esc_args[0], 1));
> + seen_disp_event(term);
> + break;
> + case 'P': /* DCH: delete chars */
> + compatibility(VT102);
> ++ CLAMP(term->esc_args[0], term->cols);
> + insch(term, -def(term->esc_args[0], 1));
> + seen_disp_event(term);
> + break;
> +_at__at_ -3708,6 +3731,8 @@ static void term_out(Terminal *term)
> + compatibility(VT100);
> + if (term->esc_nargs <= 2) {
> + int top, bot;
> ++ CLAMP(term->esc_args[0], term->rows);
> ++ CLAMP(term->esc_args[1], term->rows);
> + top = def(term->esc_args[0], 1) - 1;
> + bot = (term->esc_nargs <= 1
> + || term->esc_args[1] == 0 ?
> +_at__at_ -4062,6 +4087,7 @@ static void term_out(Terminal *term)
> + }
> + break;
> + case 'S': /* SU: Scroll up */
> ++ CLAMP(term->esc_args[0], term->rows);
> + compatibility(SCOANSI);
> + scroll(term, term->marg_t, term->marg_b,
> + def(term->esc_args[0], 1), TRUE);
> +_at__at_ -4069,6 +4095,7 @@ static void term_out(Terminal *term)
> + seen_disp_event(term);
> + break;
> + case 'T': /* SD: Scroll down */
> ++ CLAMP(term->esc_args[0], term->rows);
> + compatibility(SCOANSI);
> + scroll(term, term->marg_t, term->marg_b,
> + -def(term->esc_args[0], 1), TRUE);
> +_at__at_ -4111,6 +4138,7 @@ static void term_out(Terminal *term)
> + /* XXX VTTEST says this is vt220, vt510 manual
> + * says vt100 */
> + compatibility(ANSIMIN);
> ++ CLAMP(term->esc_args[0], term->cols);
> + {
> + int n = def(term->esc_args[0], 1);
> + pos cursplus;
> +_at__at_ -4144,6 +4172,7 @@ static void term_out(Terminal *term)
> + break;
> + case 'Z': /* CBT */
> + compatibility(OTHER);
> ++ CLAMP(term->esc_args[0], term->cols);
> + {
> + int i = def(term->esc_args[0], 1);
> + pos old_curs = term->curs;
> +_at__at_ -4204,7 +4233,7 @@ static void term_out(Terminal *term)
> + break;
> + case ANSI('F', '='): /* set normal foreground */
> + compatibility(SCOANSI);
> +- if (term->esc_args[0] >= 0 && term->esc_args[0] <
> 16) {
> ++ if (term->esc_args[0] < 16) {
> + long colour =
> + (sco2ansicolour[term->esc_args[0] & 0x7] |
> + (term->esc_args[0] & 0x8)) <<
> +_at__at_ -4218,7 +4247,7 @@ static void term_out(Terminal *term)
> + break;
> + case ANSI('G', '='): /* set normal background */
> + compatibility(SCOANSI);
> +- if (term->esc_args[0] >= 0 && term->esc_args[0] <
> 16) {
> ++ if (term->esc_args[0] < 16) {
> + long colour =
> + (sco2ansicolour[term->esc_args[0] & 0x7] |
> + (term->esc_args[0] & 0x8)) <<
> +_at__at_ -4342,7 +4371,11 @@ static void term_out(Terminal *term)
> + case '7':
> + case '8':
> + case '9':
> +- term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
> ++ if (term->esc_args[0] <= UINT_MAX / 10 &&
> ++ term->esc_args[0] * 10 <= UINT_MAX - c - '0')
> ++ term->esc_args[0] = 10 * term->esc_args[0] + c -
> '0';
> ++ else
> ++ term->esc_args[0] = UINT_MAX;
> + break;
> + case 'L':
> + /*
> +_at__at_ -4424,7 +4457,11 @@ static void term_out(Terminal *term)
> + case '7':
> + case '8':
> + case '9':
> +- term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
> ++ if (term->esc_args[0] <= UINT_MAX / 10 &&
> ++ term->esc_args[0] * 10 <= UINT_MAX - c - '0')
> ++ term->esc_args[0] = 10 * term->esc_args[0] + c -
> '0';
> ++ else
> ++ term->esc_args[0] = UINT_MAX;
> + break;
> + default:
> + term->termstate = OSC_STRING;
> +diff --git a/terminal.h b/terminal.h
> +index 135ef45..01d5f57 100644
> +--- a/terminal.h
> ++++ b/terminal.h
> +_at__at_ -172,7 +172,7 @@ struct terminal_tag {
> + #define ARGS_MAX 32 /* max # of esc sequence arguments
> */
> + #define ARG_DEFAULT 0 /* if an arg isn't specified */
> + #define def(a,d) ( (a) == ARG_DEFAULT ? (d) : (a) )
> +- int esc_args[ARGS_MAX];
> ++ unsigned esc_args[ARGS_MAX];
> + int esc_nargs;
> + int esc_query;
> + #define ANSI(x,y) ((x)+((y)<<8))
> +--
> +1.7.10.4
> +
> --
> 2.6.2
>
>



---
Unsubscribe:  alpine-aports+unsubscribe_at_lists.alpinelinux.org
Help:         alpine-aports+help_at_lists.alpinelinux.org
---
Received on Wed Dec 02 2015 - 18:39:16 GMT