diff options
author | Peter Harris <pharris@opentext.com> | 2010-03-11 10:45:44 -0500 |
---|---|---|
committer | Peter Harris <pharris@opentext.com> | 2010-03-11 11:53:46 -0500 |
commit | 697ebecdd334587515f78a5361cb7a84c296d12a (patch) | |
tree | a6b09965860ecc49ffbdc2eefe7bb70c1bae5354 | |
parent | 915abc98450865fc390e53b9ff8ceeb64921614e (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.c | 23 | ||||
-rw-r--r-- | icccm/xcb_icccm.h | 3 |
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. |