[PATCH:libX11] If XGetImage fails to create image, don't dereference it to bounds check
Emil Velikov
emil.l.velikov at gmail.com
Wed Mar 7 21:42:53 UTC 2018
On 7 March 2018 at 20:10, Alan Coopersmith <alan.coopersmith at oracle.com> wrote:
> On 03/ 7/18 05:36 AM, Emil Velikov wrote:
>> Hi Alan,
>>
>> On 6 March 2018 at 21:47, Alan Coopersmith <alan.coopersmith at oracle.com> wrote:
>>> Reported by gcc 7.3:
>>>
>>> GetImage.c:110:25: warning: potential null pointer dereference [-Wnull-dereference]
>>> if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
>>> ~~~~~^~~~~~~~
>>>
>>> Introduced by 8ea762f94f4c942d898fdeb590a1630c83235c17 in Xlib 1.6.4
>>>
>>> Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
>>> ---
>>> src/GetImage.c | 16 +++++++++-------
>>> 1 file changed, 9 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/src/GetImage.c b/src/GetImage.c
>>> index ff32d589..44a576a1 100644
>>> --- a/src/GetImage.c
>>> +++ b/src/GetImage.c
>>> @@ -105,14 +105,16 @@ XImage *XGetImage (
>>> planes = 1;
>>> }
>>>
>>> - if (!image)
>>> + if (!image) {
>>> Xfree(data);
>>> - if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
>>> - INT_MAX / image->height <= image->bytes_per_line ||
>>> - INT_MAX / planes <= image->height * image->bytes_per_line ||
>>> - nbytes < planes * image->height * image->bytes_per_line) {
>>> - XDestroyImage(image);
>>> - image = NULL;
>>> + } else {
>>> + if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
>>> + INT_MAX / image->height <= image->bytes_per_line ||
>>> + INT_MAX / planes <= image->height * image->bytes_per_line ||
>>> + nbytes < planes * image->height * image->bytes_per_line) {
>>> + XDestroyImage(image);
>>> + image = NULL;
>>> + }
>>
>> Instead of reshuffling, one could easily add the missing unlock/sync
>> in the error path.
>> Or even a goto unlock?
>
> Sorry - not sure I'm following - are you suggesting something like this?
>
> --- a/src/GetImage.c
> +++ b/src/GetImage.c
> @@ -104,17 +104,20 @@ XImage *XGetImage (
> _XGetScanlinePad(dpy, (int) rep.depth), 0);
> planes = 1;
> }
>
> - if (!image)
> + if (!image) {
> Xfree(data);
> + goto unlock;
> + }
> if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
> INT_MAX / image->height <= image->bytes_per_line ||
> INT_MAX / planes <= image->height * image->bytes_per_line ||
> nbytes < planes * image->height * image->bytes_per_line) {
> XDestroyImage(image);
> image = NULL;
> }
> + unlock:
> UnlockDisplay(dpy);
> SyncHandle();
> return (image);
> }
>
Yes, precisely.
>
> That should be effectively equivalent, just less change in indentation for
> the lines in between.
>
You're correct - it's functionally identical although it seems cleaner.
Regardless of which version you opt for
Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
-Emil
More information about the xorg-devel
mailing list