summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2012-01-17 21:26:14 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2012-01-18 08:26:18 +1000
commit07ced7b48219e3bc0c98806f3d7106f86d1b2ca0 (patch)
tree5dfd2b167a4f2be374c2fcfc954909efea093e95
parent15feb92b30e13e7439a3434bea9f454645b97444 (diff)
Force class alignment to a multiple of sizeof(XID).
Calculate length field to a multiples of sizeof(XID). XIDs are typedefs to ulong and thus may be 8 bytes on some platforms. This can trigger a SIGBUS if a class ends up not being 8-aligned (e.g. after XAxisInfo). Reported-by: Nicolai Stange <nicolai.stange@zmaw.de> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr>
-rw-r--r--src/XListDev.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/XListDev.c b/src/XListDev.c
index 6a16da4..6b91238 100644
--- a/src/XListDev.c
+++ b/src/XListDev.c
@@ -61,6 +61,17 @@ SOFTWARE.
#include <X11/extensions/extutil.h>
#include "XIint.h"
+/* Calculate length field to a multiples of sizeof(XID). XIDs are typedefs
+ * to ulong and thus may be 8 bytes on some platforms. This can trigger a
+ * SIGBUS if a class ends up not being 8-aligned (e.g. after XAxisInfo).
+ */
+static int pad_to_xid(int base_size)
+{
+ int padsize = sizeof(XID);
+
+ return ((base_size + padsize - 1)/padsize) * padsize;
+}
+
static int
SizeClassInfo(xAnyClassPtr *any, int num_classes)
{
@@ -69,18 +80,18 @@ SizeClassInfo(xAnyClassPtr *any, int num_classes)
for (j = 0; j < num_classes; j++) {
switch ((*any)->class) {
case KeyClass:
- size += sizeof(XKeyInfo);
+ size += pad_to_xid(sizeof(XKeyInfo));
break;
case ButtonClass:
- size += sizeof(XButtonInfo);
+ size += pad_to_xid(sizeof(XButtonInfo));
break;
case ValuatorClass:
{
xValuatorInfoPtr v;
v = (xValuatorInfoPtr) *any;
- size += sizeof(XValuatorInfo) +
- (v->num_axes * sizeof(XAxisInfo));
+ size += pad_to_xid(sizeof(XValuatorInfo) +
+ (v->num_axes * sizeof(XAxisInfo)));
break;
}
default:
@@ -105,7 +116,7 @@ ParseClassInfo(xAnyClassPtr *any, XAnyClassPtr *Any, int num_classes)
xKeyInfoPtr k = (xKeyInfoPtr) *any;
K->class = KeyClass;
- K->length = sizeof(XKeyInfo);
+ K->length = pad_to_xid(sizeof(XKeyInfo));
K->min_keycode = k->min_keycode;
K->max_keycode = k->max_keycode;
K->num_keys = k->num_keys;
@@ -117,7 +128,7 @@ ParseClassInfo(xAnyClassPtr *any, XAnyClassPtr *Any, int num_classes)
xButtonInfoPtr b = (xButtonInfoPtr) *any;
B->class = ButtonClass;
- B->length = sizeof(XButtonInfo);
+ B->length = pad_to_xid(sizeof(XButtonInfo));
B->num_buttons = b->num_buttons;
break;
}
@@ -129,8 +140,8 @@ ParseClassInfo(xAnyClassPtr *any, XAnyClassPtr *Any, int num_classes)
xAxisInfoPtr a;
V->class = ValuatorClass;
- V->length = sizeof(XValuatorInfo) +
- (v->num_axes * sizeof(XAxisInfo));
+ V->length = pad_to_xid(sizeof(XValuatorInfo) +
+ (v->num_axes * sizeof(XAxisInfo)));
V->num_axes = v->num_axes;
V->motion_buffer = v->motion_buffer_size;
V->mode = v->mode;