[PATCH 2/3] connection: Prevent integer overflow in DIV_ROUNDUP.
Derek Foreman
derek.foreman.samsung at gmail.com
Fri Aug 17 15:52:44 UTC 2018
On 2018-08-17 05:39 AM, Pekka Paalanen wrote:
> On Tue, 14 Aug 2018 13:07:52 +0200
> Michal Srb <msrb at suse.com> wrote:
>
>> The DIV_ROUNDUP macro would overflow when trying to round values higher
>> than MAX_UINT32 - (a - 1). The result is 0 after the division. This is
>> potential security issue when demarshalling an array because the length
>> check is performed with the overflowed value, but then the original huge
>> value is stored for later use.
>>
>> The issue was present only on 32bit platforms. The use of size_t in the
>> DIV_ROUNDUP macro already promoted everything to 64 bit size on 64 bit
>> systems.
>> ---
>> src/connection.c | 23 ++++++++++++++---------
>> 1 file changed, 14 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/connection.c b/src/connection.c
>> index 294c521..31396bc 100644
>> --- a/src/connection.c
>> +++ b/src/connection.c
>> @@ -44,7 +44,12 @@
>> #include "wayland-private.h"
>> #include "wayland-os.h"
>>
>> -#define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
>> +static inline uint32_t div_roundup(uint32_t n, size_t a) {
>> + // The cast to uint64_t is necessary to prevent overflow when rounding
>> + // values close to UINT32_MAX. After the division it is again safe to
>> + // cast back to uint32_t.
>> + return (uint32_t) (((uint64_t) n + (a - 1)) / a);
>> +}
>
> The above has a few style issues:
> - div_roundup should start on a new line as it is a function now
> - use /* */ comment style
> - use tabs for indent
> - missing Signed-off-by
>
> But aside from those, this patch is:
>
> Reviewed-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
It's also
Reviewed-by: Derek Foreman <derek.foreman.samsung at gmail.com>
I'd like to land this today, so I'll deal with the trivial style
complaints when landing.
Thanks,
Derek
>>
>> struct wl_buffer {
>> char data[4096];
>> @@ -734,7 +739,7 @@ wl_connection_demarshal(struct wl_connection *connection,
>> break;
>> }
>>
>> - next = p + DIV_ROUNDUP(length, sizeof *p);
>> + next = p + div_roundup(length, sizeof *p);
>> if (next > end) {
>> wl_log("message too short, "
>> "object (%d), message %s(%s)\n",
>> @@ -793,7 +798,7 @@ wl_connection_demarshal(struct wl_connection *connection,
>> case 'a':
>> length = *p++;
>>
>> - next = p + DIV_ROUNDUP(length, sizeof *p);
>> + next = p + div_roundup(length, sizeof *p);
>> if (next > end) {
>> wl_log("message too short, "
>> "object (%d), message %s(%s)\n",
>> @@ -1068,7 +1073,7 @@ buffer_size_for_closure(struct wl_closure *closure)
>> }
>>
>> size = strlen(closure->args[i].s) + 1;
>> - buffer_size += 1 + DIV_ROUNDUP(size, sizeof(uint32_t));
>> + buffer_size += 1 + div_roundup(size, sizeof(uint32_t));
>> break;
>> case 'a':
>> if (closure->args[i].a == NULL) {
>> @@ -1077,7 +1082,7 @@ buffer_size_for_closure(struct wl_closure *closure)
>> }
>>
>> size = closure->args[i].a->size;
>> - buffer_size += (1 + DIV_ROUNDUP(size, sizeof(uint32_t)));
>> + buffer_size += (1 + div_roundup(size, sizeof(uint32_t)));
>> break;
>> default:
>> break;
>> @@ -1139,11 +1144,11 @@ serialize_closure(struct wl_closure *closure, uint32_t *buffer,
>> size = strlen(closure->args[i].s) + 1;
>> *p++ = size;
>>
>> - if (p + DIV_ROUNDUP(size, sizeof *p) > end)
>> + if (p + div_roundup(size, sizeof *p) > end)
>> goto overflow;
>>
>> memcpy(p, closure->args[i].s, size);
>> - p += DIV_ROUNDUP(size, sizeof *p);
>> + p += div_roundup(size, sizeof *p);
>> break;
>> case 'a':
>> if (closure->args[i].a == NULL) {
>> @@ -1154,11 +1159,11 @@ serialize_closure(struct wl_closure *closure, uint32_t *buffer,
>> size = closure->args[i].a->size;
>> *p++ = size;
>>
>> - if (p + DIV_ROUNDUP(size, sizeof *p) > end)
>> + if (p + div_roundup(size, sizeof *p) > end)
>> goto overflow;
>>
>> memcpy(p, closure->args[i].a->data, size);
>> - p += DIV_ROUNDUP(size, sizeof *p);
>> + p += div_roundup(size, sizeof *p);
>> break;
>> default:
>> break;
>
>
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180817/38f91086/attachment.sig>
More information about the wayland-devel
mailing list