Merge lp:~vanvugt/compiz-core/fix-940066 into lp:compiz-core

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 3024
Proposed branch: lp:~vanvugt/compiz-core/fix-940066
Merge into: lp:compiz-core
Diff against target: 89 lines (+53/-5)
1 file modified
libdecoration/decoration.c (+53/-5)
To merge this branch: bzr merge lp:~vanvugt/compiz-core/fix-940066
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Sam Spilsbury Approve
Review via email: mp+94723@code.launchpad.net

This proposal supersedes a proposal from 2012-02-24.

Description of the change

Avoid uninitialized memory reads, which could lead to unpredictable results.
The uninitialized memory was in the padding bytes of imperfectly aligned
structures. (LP: #940066)

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Gah, truly bitten by this I see :/

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

It seems odd to use "return memcmp (a, b, sizeof (double) * 6);" without at least a compile-time assert that sizeof (decor_matrix_t) == sizeof (double) * 6).

#define STATIC_ASSERT(condition, label) _Static_assert(condition, #label)
STATIC_ASSERT(sizeof (decor_matrix_t) == sizeof (double) * 6, decor_matrix_t is 6 doubles);

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

That assertion would be incorrect, which is why I avoided sizeof (decor_matrix_t).

Structure alignment rules guarantee that decor_matrix_t contains 6 doubles tightly packed at offset 0. However I do not think they guarantee how much padding there is after that. Thus, you cannot assume sizeof (decor_matrix_t) == 6 * sizeof (double).

Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

While I agree there is no C standard requirement that there is no tail
padding, the universal implementation of tail padding is for the size
of a struct to reach the smallest possible multiple of the alignment
required by the contained types.  (This is required by every ABI that
I've seen.)
If you feel a need to be paranoid I don't believe one can show that
all bits in a double are significant.

----- Original Message -----
From: <email address hidden>
To:"Daniel van Vugt"
Cc:
Sent:Sat, 25 Feb 2012 03:19:16 -0000
Subject:Re: [Merge] lp:~vanvugt/compiz-core/fix-940066 into
lp:compiz-core

 That assertion would be incorrect, which is why I avoided sizeof
(decor_matrix_t).

 Structure alignment rules guarantee that decor_matrix_t contains 6
doubles tightly packed at offset 0. However I do not think they
guarantee how much padding there is after that. Thus, you cannot
assume sizeof (decor_matrix_t) == 6 * sizeof (double).
 --
https://code.launchpad.net/~vanvugt/compiz-core/fix-940066/+merge/94502
[1]
 Your team Compiz Maintainers is subscribed to branch lp:compiz-core.

Links:
------
[1]
https://code.launchpad.net/~vanvugt/compiz-core/fix-940066/+merge/94502

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think all the bits in a double are significant to an equality operation:
http://en.wikipedia.org/wiki/Double_precision_floating-point_format

But I'm happy to remove the memcmp for argument's sake.

Revision history for this message
Sam Spilsbury (smspillaz) :
review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libdecoration/decoration.c'
2--- libdecoration/decoration.c 2012-02-09 07:48:57 +0000
3+++ libdecoration/decoration.c 2012-02-27 06:48:18 +0000
4@@ -369,6 +369,49 @@
5 return n;
6 }
7
8+static int
9+decor_point_cmp (const decor_point_t *a, const decor_point_t *b)
10+{
11+ /* Use binary | to avoid branch prediction slow-downs */
12+ return (a->x - b->x) | (a->y - b->y) | (a->gravity - b->gravity);
13+}
14+
15+static int
16+decor_matrix_cmp (const decor_matrix_t *a, const decor_matrix_t *b)
17+{
18+ return (a->xx != b->xx) ||
19+ (a->yx != b->yx) ||
20+ (a->xy != b->xy) ||
21+ (a->yy != b->yy) ||
22+ (a->x0 != b->x0) ||
23+ (a->y0 != b->y0);
24+}
25+
26+static int
27+decor_quad_cmp (const decor_quad_t *a, const decor_quad_t *b)
28+{
29+ return decor_point_cmp (&a->p1, &b->p1) ||
30+ decor_point_cmp (&a->p2, &b->p2) ||
31+ decor_matrix_cmp (&a->m, &b->m) ||
32+ (
33+ (a->max_width - b->max_width) |
34+ (a->max_height - b->max_height) |
35+ (a->align - b->align) |
36+ (a->clamp - b->clamp) |
37+ (a->stretch - b->stretch)
38+ );
39+}
40+
41+static int
42+decor_extents_cmp (const decor_extents_t *a, const decor_extents_t *b)
43+{
44+ /* Use binary | to avoid branch prediction slow-downs */
45+ return (a->left - b->left) |
46+ (a->right - b->right) |
47+ (a->top - b->top) |
48+ (a->bottom - b->bottom);
49+}
50+
51 /* Returns n for a match, returns -1 for no match */
52
53 int
54@@ -395,6 +438,7 @@
55 Pixmap cPixmap;
56 decor_extents_t cFrame, cBorder, cMax_frame, cMax_border;
57 int cMin_width, cMin_height;
58+ int q;
59 unsigned int cFrame_type, cFrame_state, cFrame_actions, cNQuad;
60 decor_quad_t cQuad[N_QUADS_MAX];
61 cNQuad = decor_pixmap_property_to_quads (data, i, size, &cPixmap, &cFrame, &cBorder, &cMax_frame,
62@@ -404,10 +448,10 @@
63 if (cPixmap != *pixmap)
64 continue;
65
66- if (memcmp (&cFrame, frame, sizeof (decor_extents_t)) ||
67- memcmp (&cBorder, border, sizeof (decor_extents_t)) ||
68- memcmp (&cMax_frame, max_frame, sizeof (decor_extents_t)) ||
69- memcmp (&cMax_border, max_border, sizeof (decor_extents_t)))
70+ if (decor_extents_cmp (&cFrame, frame) ||
71+ decor_extents_cmp (&cBorder, border) ||
72+ decor_extents_cmp (&cMax_frame, max_frame) ||
73+ decor_extents_cmp (&cMax_border, max_border))
74 continue;
75
76 if (cFrame_type != frame_type ||
77@@ -420,7 +464,11 @@
78 if (cNQuad != n_quad)
79 continue;
80
81- if (memcmp (cQuad, quad, sizeof (decor_quad_t) * n_quad))
82+ q = 0;
83+ while (q < n_quad && !decor_quad_cmp (&cQuad[q], &quad[q]))
84+ q++;
85+
86+ if (q < n_quad)
87 continue;
88
89 return n;

Subscribers

People subscribed via source and target branches