Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
xrdp
xrdp-CVE-2023-42822.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xrdp-CVE-2023-42822.patch of Package xrdp
From aed27b162d704324a0ea00f864df6bd44cc2af34 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Mon, 25 Sep 2023 11:25:04 +0100 Subject: [PATCH] CVE-2023-42822 - font_items in struct xrdp_font renamed to chars to catch all accesses to it. This name is consistent with the type of the array elements (struct xrdp_font_char). - Additional fields added to struct xrdp_font to allow for range checking and for a default character to be provided - Additional checks and logic added to xrdp_font_create() - New macro XRDP_FONT_GET_CHAR() added to perform checked access to chars field in struct xrdp_font --- xrdp/xrdp.h | 13 ++++++- xrdp/xrdp_font.c | 92 +++++++++++++++++++++++++++++++++++++++------ xrdp/xrdp_painter.c | 10 ++--- xrdp/xrdp_types.h | 16 +++++--- 4 files changed, 106 insertions(+), 25 deletions(-) diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 697081db..a8c917f5 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -316,8 +316,17 @@ xrdp_font_create(struct xrdp_wm* wm); void xrdp_font_delete(struct xrdp_font* self); int -xrdp_font_item_compare(struct xrdp_font_char* font1, - struct xrdp_font_char* font2); +xrdp_font_item_compare(struct xrdp_font_char *font1, + struct xrdp_font_char *font2); +/** + * Gets a checked xrdp_font_char from a font + * @param f Font + * @param c32 Unicode codepoint + */ +#define XRDP_FONT_GET_CHAR(f, c32) \ + (((unsigned int)(c32) >= ' ') && ((unsigned int)(c32) < (f)->char_count) \ + ? ((f)->chars + (unsigned int)(c32)) \ + : (f)->default_char) /* funcs.c */ int diff --git a/xrdp/xrdp_font.c b/xrdp/xrdp_font.c index ae2e116f..4690cdcf 100644 --- a/xrdp/xrdp_font.c +++ b/xrdp/xrdp_font.c @@ -65,6 +65,12 @@ static char w_char[] = }; #endif +// Unicode definitions +#define UNICODE_WHITE_SQUARE 0x25a1 + +// First character allocated in the 'struct xrdp_font.chars' array +#define FIRST_CHAR ' ' + /*****************************************************************************/ struct xrdp_font * xrdp_font_create(struct xrdp_wm *wm) @@ -74,8 +80,8 @@ xrdp_font_create(struct xrdp_wm *wm) int fd; int b; int i; - int index; - int datasize; + unsigned int char_count; + unsigned int datasize; // Size of glyph data on disk int file_size; struct xrdp_font_char *f; char file_path[256]; @@ -100,17 +106,39 @@ xrdp_font_create(struct xrdp_wm *wm) } self = (struct xrdp_font *)g_malloc(sizeof(struct xrdp_font), 1); + if (self == NULL) + { + log_message(LOG_LEVEL_ERROR, "xrdp_font_create: " + "Can't allocate memory for font"); + return self; + } self->wm = wm; make_stream(s); init_stream(s, file_size + 1024); fd = g_file_open(file_path); - if (fd != -1) + if (fd < 0) + { + log_message(LOG_LEVEL_ERROR, + "xrdp_font_create: Can't open %s - %s", file_path, + g_get_strerror()); + g_free(self); + self = NULL; + } + else { b = g_file_read(fd, s->data, file_size + 1024); g_file_close(fd); - if (b > 0) + // Got at least a header? + if (b < (4 + 32 + 2 + 2 + 2 + 2 + 4)) + { + log_message(LOG_LEVEL_ERROR, + "xrdp_font_create: Font %s is truncated", file_path); + g_free(self); + self = NULL; + } + else { s->end = s->data + b; in_uint8s(s, 4); @@ -118,11 +146,27 @@ xrdp_font_create(struct xrdp_wm *wm) in_uint16_le(s, self->size); in_uint16_le(s, self->style); in_uint8s(s, 8); - index = 32; + char_count = FIRST_CHAR; - while (s_check_rem(s, 16)) + while (!s_check_end(s)) { - f = self->font_items + index; + if (!s_check_rem(s, 16)) + { + log_message(LOG_LEVEL_WARNING, + "xrdp_font_create: " + "Can't parse header for character U+%X", char_count); + break; + } + + if (char_count >= MAX_FONT_CHARS) + { + log_message(LOG_LEVEL_WARNING, + "xrdp_font_create: " + "Ignoring characters >= U+%x", MAX_FONT_CHARS); + break; + } + + f = self->chars + char_count; in_sint16_le(s, i); f->width = i; in_sint16_le(s, i); @@ -141,7 +185,7 @@ xrdp_font_create(struct xrdp_wm *wm) /* shouldn't happen */ log_message(LOG_LEVEL_ERROR,"error in xrdp_font_create, datasize wrong"); log_message(LOG_LEVEL_DEBUG,"width %d height %d datasize %d index %d", - f->width, f->height, datasize, index); + f->width, f->height, datasize, char_count); break; } @@ -155,7 +199,31 @@ xrdp_font_create(struct xrdp_wm *wm) log_message(LOG_LEVEL_ERROR,"error in xrdp_font_create"); } - index++; + ++char_count; + } + + self->char_count = char_count; + if (char_count <= FIRST_CHAR) + { + /* We read no characters from the font */ + xrdp_font_delete(self); + self = NULL; + } + else + { + // Find a default glyph + if (char_count > UNICODE_WHITE_SQUARE) + { + self->default_char = &self->chars[UNICODE_WHITE_SQUARE]; + } + else if (char_count > '?') + { + self->default_char = &self->chars['?']; + } + else + { + self->default_char = &self->chars[FIRST_CHAR]; + } } } } @@ -178,16 +246,16 @@ xrdp_font_create(struct xrdp_wm *wm) void xrdp_font_delete(struct xrdp_font *self) { - int i; + unsigned int i; if (self == 0) { return; } - for (i = 0; i < NUM_FONTS; i++) + for (i = FIRST_CHAR; i < self->char_count; i++) { - g_free(self->font_items[i].data); + g_free(self->chars[i].data); } g_free(self); diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index 97ae5cc3..fe952b53 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -464,7 +464,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, const char *text) for (index = 0; index < len; index++) { - font_item = self->font->font_items + wstr[index]; + font_item = XRDP_FONT_GET_CHAR(self->font, wstr[index]); rv = rv + font_item->incby; } @@ -502,7 +502,7 @@ xrdp_painter_text_height(struct xrdp_painter *self, const char *text) for (index = 0; index < len; index++) { - font_item = self->font->font_items + wstr[index]; + font_item = XRDP_FONT_GET_CHAR(self->font, wstr[index]); rv = MAX(rv, font_item->height); } @@ -879,7 +879,7 @@ xrdp_painter_draw_text(struct xrdp_painter *self, total_height = 0; for (index = 0; index < len; index++) { - font_item = font->font_items + wstr[index]; + font_item = XRDP_FONT_GET_CHAR(font, wstr[index]); k = font_item->incby; total_width += k; total_height = MAX(total_height, font_item->height); @@ -913,7 +913,7 @@ xrdp_painter_draw_text(struct xrdp_painter *self, draw_rect.bottom - draw_rect.top); for (index = 0; index < len; index++) { - font_item = font->font_items + wstr[index]; + font_item = XRDP_FONT_GET_CHAR(font, wstr[index]); g_memset(&pat, 0, sizeof(pat)); pat.format = PT_FORMAT_c1; pat.width = font_item->width; @@ -955,7 +955,7 @@ xrdp_painter_draw_text(struct xrdp_painter *self, for (index = 0; index < len; index++) { - font_item = font->font_items + wstr[index]; + font_item = XRDP_FONT_GET_CHAR(font, wstr[index]); i = xrdp_cache_add_char(self->wm->cache, font_item); f = HIWORD(i); c = LOWORD(i); diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index b0c8b559..aebf891b 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -493,7 +493,7 @@ struct xrdp_bitmap int crc16; }; -#define NUM_FONTS 0x4e00 +#define MAX_FONT_CHARS 0x4e00 #define DEFAULT_FONT_NAME "sans-10.fv1" #define DEFAULT_ELEMENT_TOP 35 @@ -512,11 +512,15 @@ struct xrdp_bitmap /* font */ struct xrdp_font { - struct xrdp_wm* wm; - struct xrdp_font_char font_items[NUM_FONTS]; - char name[32]; - int size; - int style; + struct xrdp_wm *wm; + // Font characters, accessed by Unicode codepoint. The first 32 + // entries are unused. + struct xrdp_font_char chars[MAX_FONT_CHARS]; + unsigned int char_count; // # elements in above array + struct xrdp_font_char *default_char; // Pointer into above array + char name[32]; + int size; + int style; }; /* module */ -- 2.43.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor