Wednesday, December 11, 2019

Re: [PATCH] graphics/libsixel security patches

On 2019/12/10 21:58, trondd wrote:
> A handful of CVEs were assigned for bugs in libsixel. Heap buffer
> overflows and integer overflows.
>
> CVE-2019-19638
> CVE-2019-19635
> CVE-2019-19636
> CVE-2019-19637
>
> A pull request pointing out the issues and patching them was submitted
> about 10 days ago. The CVEs were assigned 3 days ago.
>
> https://github.com/saitoha/libsixel/pull/106
>
> There hasn't been a response yet so instead of waiting for a new release
> I'm being proactive to get the patches applied to the port of the current
> version.

Please would you add a quick comment to the patches? A reference to
the PR and short description would be fine.

> Tim.
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/graphics/libsixel/Makefile,v
> retrieving revision 1.5
> diff -u -p -r1.5 Makefile
> --- Makefile 12 Jul 2019 20:47:02 -0000 1.5
> +++ Makefile 11 Dec 2019 02:51:09 -0000
> @@ -9,6 +9,8 @@ SHARED_LIBS += sixel 1.0 # 1.6
>
> CATEGORIES = graphics
>
> +REVISION = 0
> +
> HOMEPAGE = https://github.com/saitoha/libsixel
>
> MAINTAINER = Frederic Cambus <fcambus@openbsd.org>
> Index: patches/patch-include_sixel_h_in
> ===================================================================
> RCS file: patches/patch-include_sixel_h_in
> diff -N patches/patch-include_sixel_h_in
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-include_sixel_h_in 11 Dec 2019 02:51:09 -0000
> @@ -0,0 +1,13 @@
> +$OpenBSD$
> +
> +Index: include/sixel.h.in
> +--- include/sixel.h.in.orig
> ++++ include/sixel.h.in
> +@@ -60,6 +60,7 @@ typedef int SIXELSTATUS;
> + #define SIXEL_BAD_ALLOCATION (SIXEL_RUNTIME_ERROR | 0x0001) /* malloc() failed */
> + #define SIXEL_BAD_ARGUMENT (SIXEL_RUNTIME_ERROR | 0x0002) /* bad argument detected */
> + #define SIXEL_BAD_INPUT (SIXEL_RUNTIME_ERROR | 0x0003) /* bad input detected */
> ++#define SIXEL_BAD_INTEGER_OVERFLOW (SIXEL_RUNTIME_ERROR | 0x0004) /* integer overflow */
> +
> + #define SIXEL_NOT_IMPLEMENTED (SIXEL_FEATURE_ERROR | 0x0001) /* feature not implemented */
> +
> Index: patches/patch-src_frompnm_c
> ===================================================================
> RCS file: patches/patch-src_frompnm_c
> diff -N patches/patch-src_frompnm_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_frompnm_c 11 Dec 2019 02:51:09 -0000
> @@ -0,0 +1,23 @@
> +$OpenBSD$
> +
> +Index: src/frompnm.c
> +--- src/frompnm.c.orig
> ++++ src/frompnm.c
> +@@ -166,7 +166,7 @@ load_pnm(unsigned char /* in */ *p,
> + height = 0;
> + for (; *s >= '0' && *s <= '9'; ++s) {
> + height = height * 10 + (*s - '0');
> +- if (width > PNM_MAX_WIDTH) {
> ++ if (height > PNM_MAX_HEIGHT) {
> + status = SIXEL_RUNTIME_ERROR;
> + sprintf(
> + message,
> +@@ -193,7 +193,7 @@ load_pnm(unsigned char /* in */ *p,
> + for (; *s >= '0' && *s <= '9'; ++s) {
> + deps = deps * 10 + (*s - '0');
> + }
> +- if (width > PNM_MAX_WIDTH) {
> ++ if (deps > PNM_MAX_DEPTH) {
> + status = SIXEL_RUNTIME_ERROR;
> + sprintf(
> + message,
> Index: patches/patch-src_fromsixel_c
> ===================================================================
> RCS file: patches/patch-src_fromsixel_c
> diff -N patches/patch-src_fromsixel_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_fromsixel_c 11 Dec 2019 02:51:09 -0000
> @@ -0,0 +1,79 @@
> +$OpenBSD$
> +
> +Index: src/fromsixel.c
> +--- src/fromsixel.c.orig
> ++++ src/fromsixel.c
> +@@ -52,6 +52,7 @@
> + #include <stdio.h>
> + #include <ctype.h> /* isdigit */
> + #include <string.h> /* memcpy */
> ++#include <limits.h>
> +
> + #if defined(HAVE_INTTYPES_H)
> + # include <inttypes.h>
> +@@ -367,7 +368,17 @@ parser_context_init(parser_context_t *context)
> + return status;
> + }
> +
> ++SIXELSTATUS safe_addition_for_params(parser_context_t *context, unsigned char *p){
> ++ int x;
> +
> ++ x = *p - '0'; /* 0 <= x <= 9 */
> ++ if ((context->param > INT_MAX / 10) || (x > INT_MAX - context->param * 10)) {
> ++ return SIXEL_BAD_INTEGER_OVERFLOW;
> ++ }
> ++ context->param = context->param * 10 + x;
> ++ return SIXEL_OK;
> ++}
> ++
> + /* convert sixel data into indexed pixel bytes and palette data */
> + SIXELAPI SIXELSTATUS
> + sixel_decode_raw_impl(
> +@@ -446,7 +457,10 @@ sixel_decode_raw_impl(
> + if (context->param < 0) {
> + context->param = 0;
> + }
> +- context->param = context->param * 10 + *p - '0';
> ++ status = safe_addition_for_params(context, p);
> ++ if (SIXEL_FAILED(status)) {
> ++ goto end;
> ++ }
> + p++;
> + break;
> + case ';':
> +@@ -647,7 +661,10 @@ sixel_decode_raw_impl(
> + case '7':
> + case '8':
> + case '9':
> +- context->param = context->param * 10 + *p - '0';
> ++ status = safe_addition_for_params(context, p);
> ++ if (SIXEL_FAILED(status)) {
> ++ goto end;
> ++ }
> + p++;
> + break;
> + case ';':
> +@@ -721,7 +738,10 @@ sixel_decode_raw_impl(
> + case '7':
> + case '8':
> + case '9':
> +- context->param = context->param * 10 + *p - '0';
> ++ status = safe_addition_for_params(context, p);
> ++ if (SIXEL_FAILED(status)) {
> ++ goto end;
> ++ }
> + p++;
> + break;
> + default:
> +@@ -753,7 +773,10 @@ sixel_decode_raw_impl(
> + case '7':
> + case '8':
> + case '9':
> +- context->param = context->param * 10 + *p - '0';
> ++ status = safe_addition_for_params(context, p);
> ++ if (SIXEL_FAILED(status)) {
> ++ goto end;
> ++ }
> + p++;
> + break;
> + case ';':
> Index: patches/patch-src_status_c
> ===================================================================
> RCS file: patches/patch-src_status_c
> diff -N patches/patch-src_status_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_status_c 11 Dec 2019 02:51:09 -0000
> @@ -0,0 +1,23 @@
> +$OpenBSD$
> +
> +Index: src/status.c
> +--- src/status.c.orig
> ++++ src/status.c
> +@@ -46,6 +46,7 @@
> + #define SIXEL_MESSAGE_BAD_ALLOCATION ("runtime error: bad allocation error")
> + #define SIXEL_MESSAGE_BAD_ARGUMENT ("runtime error: bad argument detected")
> + #define SIXEL_MESSAGE_BAD_INPUT ("runtime error: bad input detected")
> ++#define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW ("runtime error: integer overflow")
> + #define SIXEL_MESSAGE_RUNTIME_ERROR ("runtime error")
> + #define SIXEL_MESSAGE_LOGIC_ERROR ("logic error")
> + #define SIXEL_MESSAGE_NOT_IMPLEMENTED ("feature error: not implemented")
> +@@ -117,6 +118,9 @@ sixel_helper_format_error(
> + break;
> + case SIXEL_BAD_INPUT:
> + error_string = SIXEL_MESSAGE_BAD_INPUT;
> ++ break;
> ++ case SIXEL_BAD_INTEGER_OVERFLOW:
> ++ error_string = SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW;
> + break;
> + default:
> + error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
> Index: patches/patch-src_tosixel_c
> ===================================================================
> RCS file: patches/patch-src_tosixel_c
> diff -N patches/patch-src_tosixel_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_tosixel_c 11 Dec 2019 02:51:09 -0000
> @@ -0,0 +1,53 @@
> +$OpenBSD$
> +
> +Index: src/tosixel.c
> +--- src/tosixel.c.orig
> ++++ src/tosixel.c
> +@@ -21,6 +21,7 @@
> + #include <stdio.h>
> + #include <stdlib.h>
> + #include <string.h>
> ++#include <limits.h>
> +
> + #if defined(HAVE_INTTYPES_H)
> + # include <inttypes.h>
> +@@ -502,6 +503,7 @@ sixel_encode_body(
> + int mx;
> + int len;
> + int pix;
> ++ int check_integer_overflow;
> + unsigned char *map = NULL;
> + sixel_node_t *np, *tp, top;
> + int fillable;
> +@@ -557,8 +559,30 @@ sixel_encode_body(
> + fillable = 1;
> + }
> + for (x = 0; x < width; x++) {
> +- pix = pixels[y * width + x]; /* color index */
> ++ if (y > INT_MAX / width) {
> ++ /* integer overflow */
> ++ status = SIXEL_BAD_INTEGER_OVERFLOW;
> ++ goto end;
> ++ }
> ++ check_integer_overflow = y * width;
> ++ if (check_integer_overflow > INT_MAX - x) {
> ++ /* integer overflow */
> ++ status = SIXEL_BAD_INTEGER_OVERFLOW;
> ++ goto end;
> ++ }
> ++ pix = pixels[check_integer_overflow + x]; /* color index */
> + if (pix >= 0 && pix < ncolors && pix != keycolor) {
> ++ if (pix > INT_MAX / width) {
> ++ /* integer overflow */
> ++ status = SIXEL_BAD_INTEGER_OVERFLOW;
> ++ goto end;
> ++ }
> ++ check_integer_overflow = pix * width;
> ++ if (check_integer_overflow > INT_MAX - x) {
> ++ /* integer overflow */
> ++ status = SIXEL_BAD_INTEGER_OVERFLOW;
> ++ goto end;
> ++ }
> + map[pix * width + x] |= (1 << i);
> + }
> + else if (!palstate) {
>

No comments:

Post a Comment