Tuesday, December 10, 2019

[PATCH] graphics/libsixel security patches

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.

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