mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-04 13:29:51 -05:00
connection.c: Align pointer extra storage correctly
Most extra data are just pointers, but in case of fds we store an int in the extra space. That can cause un-aligned access to pointers on 64 bit architectures. Make sure we always align pointer storage correctly.
This commit is contained in:
parent
9ebb18418a
commit
a98cfc029b
1 changed files with 18 additions and 4 deletions
|
|
@ -378,23 +378,28 @@ wl_connection_queue(struct wl_connection *connection,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ALIGN(p, s) (void *) ( ((intptr_t) (p) + ((s) - 1)) & ~((s) - 1) )
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wl_message_size_extra(const struct wl_message *message)
|
wl_message_size_extra(const struct wl_message *message)
|
||||||
{
|
{
|
||||||
int i, extra;
|
char *extra;
|
||||||
|
int i;
|
||||||
for (i = 0, extra = 0; message->signature[i]; i++) {
|
|
||||||
|
|
||||||
|
for (i = 0, extra = NULL; message->signature[i]; i++) {
|
||||||
switch (message->signature[i]) {
|
switch (message->signature[i]) {
|
||||||
case 's':
|
case 's':
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'n':
|
case 'n':
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
extra += sizeof (void *);
|
extra += sizeof (void *);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
extra += sizeof (void *) + sizeof (struct wl_array);
|
extra += sizeof (void *) + sizeof (struct wl_array);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
|
extra = ALIGN(extra, sizeof (int));
|
||||||
extra += sizeof (int);
|
extra += sizeof (int);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -402,7 +407,7 @@ wl_message_size_extra(const struct wl_message *message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return extra;
|
return (intptr_t) extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -501,6 +506,7 @@ wl_closure_vmarshal(struct wl_object *sender,
|
||||||
*p++ = va_arg(ap, int32_t);
|
*p++ = va_arg(ap, int32_t);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
closure->args[i] = extra;
|
closure->args[i] = extra;
|
||||||
sp = (const char **) extra;
|
sp = (const char **) extra;
|
||||||
|
|
@ -527,6 +533,7 @@ wl_closure_vmarshal(struct wl_object *sender,
|
||||||
p += aligned / sizeof *p;
|
p += aligned / sizeof *p;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
closure->args[i] = extra;
|
closure->args[i] = extra;
|
||||||
objectp = (struct wl_object **) extra;
|
objectp = (struct wl_object **) extra;
|
||||||
|
|
@ -557,6 +564,7 @@ wl_closure_vmarshal(struct wl_object *sender,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
closure->args[i] = extra;
|
closure->args[i] = extra;
|
||||||
arrayp = (struct wl_array **) extra;
|
arrayp = (struct wl_array **) extra;
|
||||||
|
|
@ -589,6 +597,7 @@ wl_closure_vmarshal(struct wl_object *sender,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
|
extra = ALIGN(extra, sizeof (int));
|
||||||
closure->types[i] = &ffi_type_sint;
|
closure->types[i] = &ffi_type_sint;
|
||||||
closure->args[i] = extra;
|
closure->args[i] = extra;
|
||||||
fd_ptr = (int *) extra;
|
fd_ptr = (int *) extra;
|
||||||
|
|
@ -715,6 +724,7 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
s = (char **) extra;
|
s = (char **) extra;
|
||||||
extra += sizeof *s;
|
extra += sizeof *s;
|
||||||
closure->args[i] = s;
|
closure->args[i] = s;
|
||||||
|
|
@ -736,6 +746,7 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
id = (uint32_t **) extra;
|
id = (uint32_t **) extra;
|
||||||
extra += sizeof *id;
|
extra += sizeof *id;
|
||||||
closure->args[i] = id;
|
closure->args[i] = id;
|
||||||
|
|
@ -753,6 +764,7 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
id = (uint32_t **) extra;
|
id = (uint32_t **) extra;
|
||||||
extra += sizeof *id;
|
extra += sizeof *id;
|
||||||
closure->args[i] = id;
|
closure->args[i] = id;
|
||||||
|
|
@ -789,6 +801,7 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extra = ALIGN(extra, sizeof (void *));
|
||||||
array = (struct wl_array **) extra;
|
array = (struct wl_array **) extra;
|
||||||
extra += sizeof *array;
|
extra += sizeof *array;
|
||||||
closure->args[i] = array;
|
closure->args[i] = array;
|
||||||
|
|
@ -804,6 +817,7 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
case 'h':
|
case 'h':
|
||||||
closure->types[i] = &ffi_type_sint;
|
closure->types[i] = &ffi_type_sint;
|
||||||
|
|
||||||
|
extra = ALIGN(extra, sizeof (int));
|
||||||
fd = (int *) extra;
|
fd = (int *) extra;
|
||||||
extra += sizeof *fd;
|
extra += sizeof *fd;
|
||||||
closure->args[i] = fd;
|
closure->args[i] = fd;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue