CVE-2015-7891

high
Published 2017-08-02 ยท Modified 2026-05-13
CVSS v3
7.0
CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4 NEW
โ€”
not yet in upstream
VIR risk
8.0

Description

Race condition in the ioctl implementation in the Samsung Graphics 2D driver (aka /dev/fimg2d) in Samsung devices with Android L(5.0/5.1) allows local users to trigger memory errors by leveraging definition of g2d_lock and g2d_unlock lock macros as no-ops, aka SVE-2015-4598.

Predictions

Exploit likelihood
69%
Patch ETA
โ€”

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

No mitigations published for this CVE yet.

The vendor-content worker queues fetches as references arrive (check back in a few minutes). Or โ€” if you've already worked around this in production โ€” publish your fix to the community-verified tier.

โœš Propose a mitigation on Community โ†’ Mitigations published via the community go through AI scoring + 2 human reviewers + 7-day silent objection window before landing here with source_tier=community-verified.

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-38557 dos android verified text ยท 2 KB
Google Security Research ยท 2015-10-28

Samsung fimg2d - FIMG2D_BITBLT_BLIT ioctl Concurrency Flaw

text exploit Source: Exploit-DB
Source: https://code.google.com/p/google-security-research/issues/detail?id=492

The Samsung Graphics 2D driver (/dev/fimg2d) is accessible by unprivileged users/applications. It was found that the ioctl implementation for this driver contains a locking error which can lead to memory errors (such as use-after-free) due to a race condition.

The key observation is in the locking routine definitions in fimg2d.h:

#ifdef BLIT_WORKQUE
#define g2d_lock(x)             do {} while (0)
#define g2d_unlock(x)           do {} while (0)
#define g2d_spin_lock(x, f)     spin_lock_irqsave(x, f)
#define g2d_spin_unlock(x, f)   spin_unlock_irqrestore(x, f)
#else
#define g2d_lock(x)             mutex_lock(x)
#define g2d_unlock(x)           mutex_unlock(x)
#define g2d_spin_lock(x, f)     do { f = 0; } while (0)
#define g2d_spin_unlock(x, f)   do { f = 0; } while (0)
#endif

This means that the g2d_lock/g2d_unlock routines are no-ops when BLIT_WORKQUE is defined, which appears to be the default configuration. Unfortunately the alternative spin lock routines are not used consistently with this configuration. For example, the FIMG2D_BITBLT_BLIT ioctl command (with notes annotated as "PZ"):

ctx = file->private_data; /* PZ: ctx allocated at open(), lives on the heap. */

switch (cmd) {
case FIMG2D_BITBLT_BLIT:

	mm = get_task_mm(current);
	if (!mm) {
		fimg2d_err("no mm for ctx\n");
		return -ENXIO;
	}

	g2d_lock(&ctrl->drvlock); /* PZ: This is a no-op. */

	ctx->mm = mm;

	ret = fimg2d_add_command(ctrl, ctx, (struct fimg2d_blit __user *)arg);
	if (ret) {
		...
	}

	ret = fimg2d_request_bitblt(ctrl, ctx); /* PZ: Does stuff with the ctx. */
	if (ret) {
		...
	}

	g2d_unlock(&ctrl->drvlock); /* PZ: Another no-op */

As the lock macros are no-ops, a second process can change ctx->mm when the original process is still using the same ctx->mm (as long as it has access to the same file descriptor).

Reproduction steps:
Open /dev/fimg2d
Fork to get two processes with different mmโ€™s with the access to the fd
Concurrently call the FIMG2D_BITBLT_BLIT ioctl from both processes.
One ioctl should have valid data, the other should fail

At this point ctx->mm will now have invalid or free data (free if the forked process dies). Proof-of-concept code to trigger this condition is attached (fimg2d-lock.c)

Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/38557.zip

References

CWEs

CWE-362

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.