mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-04 13:29:51 -05:00
Fix buffer overflow when serializing a closure object
Here is the JIRA page of this issue https://bugs.tizen.org/jira/browse/TIVI-1889 Change-Id: I773a6d2d8f6fd02ff10c92450db1fa8a69544219 Signed-off-by: Chi Ding <chi.ding@mobica.com> Closes: https://bugs.freedesktop.org/show_bug.cgi?id=65186
This commit is contained in:
parent
cd0dccd01e
commit
c102c20f01
1 changed files with 83 additions and 8 deletions
|
|
@ -962,6 +962,57 @@ copy_fds_to_connection(struct wl_closure *closure,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
buffer_size_for_closure(struct wl_closure *closure)
|
||||||
|
{
|
||||||
|
const struct wl_message *message = closure->message;
|
||||||
|
int i, count;
|
||||||
|
struct argument_details arg;
|
||||||
|
const char *signature;
|
||||||
|
uint32_t size, buffer_size = 0;
|
||||||
|
|
||||||
|
signature = message->signature;
|
||||||
|
count = arg_count_for_signature(signature);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
signature = get_next_argument(signature, &arg);
|
||||||
|
|
||||||
|
switch (arg.type) {
|
||||||
|
case 'h':
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
case 'i':
|
||||||
|
case 'f':
|
||||||
|
case 'o':
|
||||||
|
case 'n':
|
||||||
|
buffer_size++;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
if (closure->args[i].s == NULL) {
|
||||||
|
buffer_size++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = strlen(closure->args[i].s) + 1;
|
||||||
|
buffer_size += 1 + DIV_ROUNDUP(size, sizeof(uint32_t));
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
if (closure->args[i].a == NULL) {
|
||||||
|
buffer_size++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = closure->args[i].a->size;
|
||||||
|
buffer_size += (1 + DIV_ROUNDUP(size, sizeof(uint32_t)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer_size + 2;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
serialize_closure(struct wl_closure *closure, uint32_t *buffer,
|
serialize_closure(struct wl_closure *closure, uint32_t *buffer,
|
||||||
size_t buffer_count)
|
size_t buffer_count)
|
||||||
|
|
@ -1055,33 +1106,57 @@ overflow:
|
||||||
int
|
int
|
||||||
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
|
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
|
||||||
{
|
{
|
||||||
uint32_t buffer[256];
|
|
||||||
int size;
|
int size;
|
||||||
|
uint32_t buffer_size;
|
||||||
|
uint32_t *buffer;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (copy_fds_to_connection(closure, connection))
|
if (copy_fds_to_connection(closure, connection))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size = serialize_closure(closure, buffer, 256);
|
buffer_size = buffer_size_for_closure(closure);
|
||||||
if (size < 0)
|
buffer = malloc(buffer_size * sizeof buffer[0]);
|
||||||
|
if (buffer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return wl_connection_write(connection, buffer, size);
|
size = serialize_closure(closure, buffer, buffer_size);
|
||||||
|
if (size < 0) {
|
||||||
|
free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = wl_connection_write(connection, buffer, size);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
|
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
|
||||||
{
|
{
|
||||||
uint32_t buffer[256];
|
|
||||||
int size;
|
int size;
|
||||||
|
uint32_t buffer_size;
|
||||||
|
uint32_t *buffer;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (copy_fds_to_connection(closure, connection))
|
if (copy_fds_to_connection(closure, connection))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size = serialize_closure(closure, buffer, 256);
|
buffer_size = buffer_size_for_closure(closure);
|
||||||
if (size < 0)
|
buffer = malloc(buffer_size * sizeof buffer[0]);
|
||||||
|
if (buffer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return wl_connection_queue(connection, buffer, size);
|
size = serialize_closure(closure, buffer, buffer_size);
|
||||||
|
if (size < 0) {
|
||||||
|
free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = wl_connection_queue(connection, buffer, size);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue