Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0575f156 authored by Robb Glasser's avatar Robb Glasser Committed by Dennis Cagle
Browse files

Prevent potential double frees in sg driver



sg_ioctl could be spammed by requests, leading to a double free in
__free_pages. This protects the entry points of sg_ioctl where the
memory could be corrupted by a double call to __free_pages if multiple
requests are happening concurrently.

Bug:35644812

Change-Id: Ie13f65beb6974430f90292e2742841b26aecb8b1
Signed-off-by: default avatarRobb Glasser <rglasser@google.com>
[dcagle@codeaurora.org: Resolve trivial merge conflicts]
Git-repo: https://android.googlesource.com/kernel/msm


Git-commit: 22d8e80738b5ce8784d59b48b0b051a520da4bec
Signed-off-by: default avatarDennis Cagle <dcagle@codeaurora.org>
parent 5bc5bb65
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -859,8 +859,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
			return -ENXIO;
		if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
			return -EFAULT;
		mutex_lock(&sfp->parentdp->open_rel_lock);
		result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
				 1, read_only, 1, &srp);
		mutex_unlock(&sfp->parentdp->open_rel_lock);
		if (result < 0)
			return result;
		result = wait_event_interruptible(sfp->read_wait,
@@ -901,8 +903,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
			sfp->low_dma = 1;
			if ((0 == sfp->low_dma) && !sfp->res_in_use) {
				val = (int) sfp->reserve.bufflen;
				mutex_lock(&sfp->parentdp->open_rel_lock);
				sg_remove_scat(sfp, &sfp->reserve);
				sg_build_reserve(sfp, val);
				mutex_unlock(&sfp->parentdp->open_rel_lock);
			}
		} else {
			if (atomic_read(&sdp->detaching))
@@ -981,9 +985,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
				mutex_unlock(&sfp->f_mutex);
				return -EBUSY;
			}

			mutex_lock(&sfp->parentdp->open_rel_lock);
			sg_remove_scat(sfp, &sfp->reserve);
			sg_build_reserve(sfp, val);
			mutex_unlock(&sfp->parentdp->open_rel_lock);
		}
		mutex_unlock(&sfp->f_mutex);
		return 0;