summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Harris <pharris@opentext.com>2010-03-11 10:45:44 -0500
committerPeter Harris <pharris@opentext.com>2010-03-11 11:53:46 -0500
commit697ebecdd334587515f78a5361cb7a84c296d12a (patch)
treea6b09965860ecc49ffbdc2eefe7bb70c1bae5354
parent915abc98450865fc390e53b9ff8ceeb64921614e (diff)
Validate size of wm_hints and wm_size_hints
Without these checks, we can overflow the buffer or divide by zero. Signed-off-by: David Coppa <dcoppa@gmail.com> Signed-off-by: Peter Harris <pharris@opentext.com>
-rw-r--r--icccm/icccm.c23
-rw-r--r--icccm/xcb_icccm.h3
2 files changed, 16 insertions, 10 deletions
diff --git a/icccm/icccm.c b/icccm/icccm.c
index 0206e4b..f6397fe 100644
--- a/icccm/icccm.c
+++ b/icccm/icccm.c
@@ -424,8 +424,7 @@ xcb_get_property_cookie_t
xcb_get_wm_size_hints(xcb_connection_t *c, xcb_window_t window,
xcb_atom_t property)
{
- /* NumPropSizeElements = 18 (ICCCM version 1). */
- return xcb_get_property(c, 0, window, property, XCB_ATOM_WM_SIZE_HINTS, 0L, 18);
+ return xcb_get_property(c, 0, window, property, XCB_ATOM_WM_SIZE_HINTS, 0L, XCB_NUM_WM_SIZE_HINTS_ELEMENTS);
}
xcb_get_property_cookie_t
@@ -433,28 +432,29 @@ xcb_get_wm_size_hints_unchecked(xcb_connection_t *c, xcb_window_t window,
xcb_atom_t property)
{
return xcb_get_property_unchecked(c, 0, window, property, XCB_ATOM_WM_SIZE_HINTS,
- 0L, 18);
+ 0L, XCB_NUM_WM_SIZE_HINTS_ELEMENTS);
}
uint8_t
xcb_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, xcb_get_property_reply_t *reply)
{
uint32_t flags;
+ int length;
if(!reply)
return 0;
- int length = xcb_get_property_value_length(reply) / (reply->format / 8);
-
if (!(reply->type == XCB_ATOM_WM_SIZE_HINTS &&
- (reply->format == 8 || reply->format == 16 ||
- reply->format == 32) &&
- /* OldNumPropSizeElements = 15 (pre-ICCCM) */
- length >= 15))
+ reply->format == 32))
return 0;
+ length = xcb_get_property_value_length(reply) / (reply->format / 8);
+
+ if(length > XCB_NUM_WM_SIZE_HINTS_ELEMENTS)
+ length = XCB_NUM_WM_SIZE_HINTS_ELEMENTS;
+
memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value (reply),
- length * reply->format >> 3);
+ length * (reply->format / 8));
flags = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE |
XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE |
@@ -644,6 +644,9 @@ xcb_get_wm_hints_from_reply(xcb_wm_hints_t *hints,
if(num_elem < XCB_NUM_WM_HINTS_ELEMENTS - 1)
return 0;
+ if(length > sizeof(xcb_size_hints_t))
+ length = sizeof(xcb_size_hints_t);
+
memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value(reply), length);
if(num_elem < XCB_NUM_WM_HINTS_ELEMENTS)
diff --git a/icccm/xcb_icccm.h b/icccm/xcb_icccm.h
index 2d80ffb..f205c4c 100644
--- a/icccm/xcb_icccm.h
+++ b/icccm/xcb_icccm.h
@@ -452,6 +452,9 @@ typedef struct {
uint32_t win_gravity;
} xcb_size_hints_t;
+/** Number of elements in this structure */
+#define XCB_NUM_WM_SIZE_HINTS_ELEMENTS 18
+
/**
* @brief Set size hints to a given position.
* @param hints SIZE_HINTS structure.