Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#2387 closed defect (fixed)

heap use after free resulting in double free (libvo/vo_v4l2.c)

Reported by: bug Owned by: beastd
Priority: high Component: vo
Version: HEAD Severity: major
Keywords: crash Cc: bug
Blocked By: Blocking:
Reproduced by developer: no Analyzed by developer: no

Description (last modified by bug)

Hello folks,

I stumbled across a potential double free / uaf bug. In the preinit function located in libvo/vo_v4l2.c the DEFAULT_MPEG_DECODER string gets allocated and the corresponding file gets opened to be used. In any case, this heap buffer gets freed (either if the function fails or succeeds), however the pointer doesn't get zeroed out. This is a problem, because preinit is called again if it returns a value different than 0 (if it fails). That's where the uaf comes into place. The check

if (!device)
    device = strdup (DEFAULT_MPEG_DECODER);

is passed even though the device is already free'd. Because the function free's the device buffer in any case, there is an uaf / double free as soon as the preinit function failed once before. You can find the poc in the appendix. The preinit function fails (and is called again), because there is no /dev/video16 in the docker container. To reproduce, run ./mplayer ./crash after building the container. Please don't hesitate to ask if there are any questions. Please confirm this issue.

Best Regards

Julian aka BitFriends

Attachments (3)

poc_dup.zip (528.2 KB ) - added by bug 2 years ago.
r38367.diff (9.5 KB ) - added by reimar 2 years ago.
r38368.diff (1.1 KB ) - added by reimar 2 years ago.

Download all attachments as: .zip

Change History (11)

by bug, 2 years ago

Attachment: poc_dup.zip added

comment:1 by bug, 2 years ago

Description: modified (diff)
Summary: heap use after free resulting in double freeheap use after free resulting in double free (libvo/vo_v4l2.c)

comment:2 by reimar, 2 years ago

Status: newopen

I admit I did not try to reproduce or test the fix, but this is obviously bad code.
I reviewed all uses of free(), close(), fclose() and XFree() and added resetting the variables where necessary in r38367.
Appreciate if you can confirm this fixes the issue.
I did try to review the rest of the code base a bit as well for similar issues, but it's a bit much and I did not see any red flags in my quick check.

in reply to:  2 comment:3 by bug, 2 years ago

Could you upload a patch.diff file? I can't access with svn :/

comment:4 by reimar, 2 years ago

Well, that was dumb. I just realized that I fixed other issues libvo, but not the one you reported.
So this one is fixed in r38368.
You can get an svn snapshot on the download page, e.g. http://svn.mplayerhq.hu/MPlayer/releases/mplayer-checkout-snapshot.tar.bz2
That contains the previous fixes I mentioned, but the v4l2 one might take until tomorrow.
I can attach the patches, but not sure they apply against 1.5

by reimar, 2 years ago

Attachment: r38367.diff added

by reimar, 2 years ago

Attachment: r38368.diff added

in reply to:  4 comment:5 by bug, 2 years ago

Ah okay, now I got the changed version. I just tested it and your changes seem to fix the issue! I'm going to report a CVE for the uaf. Is it okay?

comment:6 by reimar, 2 years ago

Resolution: fixed
Status: openclosed

Sure, go ahead. As far as I can tell there isn't a straight-forward way to make use of it, as there are no writes to the pointer and I think in a standard (i.e. working) user installation this code would never run.
This might be another thing to check though, do you have a log how it ends up running vo_v4l2? Is that because none of the vos like xv etc. are compiled in or X is not running?
Wonder if there should be something like certain vos like this only getting selected if explicitly requested by the user.

in reply to:  6 comment:7 by bug, 2 years ago

Yeah, the impact of this vulnerability is not too high. And yes, X was not running. Nevertheless, the double free shouldn't happen :)

comment:8 by bug, 2 years ago

thanks for your assistance tho :)

Note: See TracTickets for help on using tickets.