Skip to content

Commit

Permalink
Merge pull request from GHSA-2hjx-rm4f-r9hw
Browse files Browse the repository at this point in the history
[V0.9] CVE-2023-42822
  • Loading branch information
metalefty authored Sep 27, 2023
2 parents 4db9323 + 58c9c1f commit fd25fc5
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 25 deletions.
9 changes: 9 additions & 0 deletions xrdp/xrdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,15 @@ xrdp_font_delete(struct xrdp_font *self);
int
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
Expand Down
113 changes: 95 additions & 18 deletions xrdp/xrdp_font.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -74,7 +80,7 @@ xrdp_font_create(struct xrdp_wm *wm)
int fd;
int b;
int i;
int index;
unsigned int char_count;
int datasize;
int file_size;
struct xrdp_font_char *f;
Expand All @@ -100,29 +106,67 @@ xrdp_font_create(struct xrdp_wm *wm)
}

self = (struct xrdp_font *)g_malloc(sizeof(struct xrdp_font), 1);
if (self == NULL)
{
LOG(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(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 + 8))
{
LOG(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);
in_uint8a(s, self->name, 32);
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(LOG_LEVEL_WARNING,
"xrdp_font_create: "
"Can't parse header for character U+%X", char_count);
break;
}

if (char_count >= MAX_FONT_CHARS)
{
LOG(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);
Expand All @@ -139,23 +183,56 @@ xrdp_font_create(struct xrdp_wm *wm)
if (datasize < 0 || datasize > 512)
{
/* shouldn't happen */
LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create, datasize wrong "
"width %d, height %d, datasize %d, index %d",
f->width, f->height, datasize, index);
LOG(LOG_LEVEL_ERROR,
"xrdp_font_create: "
"datasize for U+%x wrong "
"width %d, height %d, datasize %d",
char_count, f->width, f->height, datasize);
break;
}

if (s_check_rem(s, datasize))
if (!s_check_rem(s, datasize))
{
f->data = (char *)g_malloc(datasize, 0);
in_uint8a(s, f->data, datasize);
LOG(LOG_LEVEL_ERROR,
"xrdp_font_create: "
"Not enough data for character U+%X", char_count);
break;
}
else

if ((f->data = (char *)g_malloc(datasize, 0)) == NULL)
{
LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create");
LOG(LOG_LEVEL_ERROR,
"xrdp_font_create: "
"Allocation error for character U+%X", char_count);
break;
}
in_uint8a(s, f->data, datasize);

++char_count;
}

index++;
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];
}
}
}
}
Expand All @@ -178,16 +255,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);
Expand Down
10 changes: 5 additions & 5 deletions xrdp/xrdp_painter.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,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;
}

Expand Down Expand Up @@ -493,7 +493,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);
}

Expand Down Expand Up @@ -870,7 +870,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);
Expand Down Expand Up @@ -904,7 +904,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;
Expand Down Expand Up @@ -946,7 +946,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);
Expand Down
8 changes: 6 additions & 2 deletions xrdp/xrdp_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,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
Expand All @@ -594,7 +594,11 @@ struct xrdp_bitmap
struct xrdp_font
{
struct xrdp_wm *wm;
struct xrdp_font_char font_items[NUM_FONTS];
// 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;
Expand Down

0 comments on commit fd25fc5

Please sign in to comment.