lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Mon,  4 Mar 2019 21:28:42 +0100
From:   Arnd Bergmann <arnd@...db.de>
To:     Sakari Ailus <sakari.ailus@...ux.intel.com>,
        Mauro Carvalho Chehab <mchehab@...nel.org>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:     Arnd Bergmann <arnd@...db.de>, Yong Zhi <yong.zhi@...el.com>,
        Tian Shu Qiu <tian.shu.qiu@...el.com>,
        Bingbu Cao <bingbu.cao@...el.com>, linux-media@...r.kernel.org,
        devel@...verdev.osuosl.org, linux-kernel@...r.kernel.org
Subject: [PATCH] media: staging/intel-ipu3-v4l: reduce kernel stack usage

The v4l2_pix_format_mplane structure is too large to be put on the kernel
stack, as we can see in 32-bit builds:

drivers/staging/media/ipu3/ipu3-v4l2.c: In function 'imgu_fmt':
drivers/staging/media/ipu3/ipu3-v4l2.c:753:1: error: the frame size of 1028 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

By dynamically allocating this array, the stack usage goes down to an
acceptable 272 bytes for the same x86-32 configuration.

Fixes: a0ca1627b450 ("media: staging/intel-ipu3: Add v4l2 driver based on media framework")
Signed-off-by: Arnd Bergmann <arnd@...db.de>
---
 drivers/staging/media/ipu3/ipu3-v4l2.c | 40 ++++++++++++++++----------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
index 9c0352b193a7..c34b433539c4 100644
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
@@ -664,12 +664,11 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
 		    struct v4l2_format *f, bool try)
 {
 	struct device *dev = &imgu->pci_dev->dev;
-	struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES];
 	struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL };
 	struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL };
 	struct v4l2_mbus_framefmt pad_fmt;
 	unsigned int i, css_q;
-	int r;
+	int ret;
 	struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe];
 	struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
 	struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd;
@@ -698,9 +697,13 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
 			continue;
 
 		if (try) {
-			try_fmts[i] =
-				imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
-			fmts[i] = &try_fmts[i];
+			fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp,
+					  sizeof(struct v4l2_pix_format_mplane),
+					  GFP_KERNEL);
+			if (!fmts[i]) {
+				ret = -ENOMEM;
+				goto out;
+			}
 		} else {
 			fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp;
 		}
@@ -730,26 +733,33 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
 	 * before we return success from this function, so set it here.
 	 */
 	css_q = imgu_node_to_queue(node);
-	if (fmts[css_q])
-		*fmts[css_q] = f->fmt.pix_mp;
-	else
-		return -EINVAL;
+	if (!fmts[css_q]) {
+		ret = -EINVAL;
+		goto out;
+	}
+	*fmts[css_q] = f->fmt.pix_mp;
 
 	if (try)
-		r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
+		ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe);
 	else
-		r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
+		ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
 
-	/* r is the binary number in the firmware blob */
-	if (r < 0)
-		return r;
+	/* ret is the binary number in the firmware blob */
+	if (ret < 0)
+		goto out;
 
 	if (try)
 		f->fmt.pix_mp = *fmts[css_q];
 	else
 		f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt;
 
-	return 0;
+out:
+	if (try) {
+		for (i = 0; i < IPU3_CSS_QUEUES; i++)
+			kfree(fmts[i]);
+	}
+
+	return ret;
 }
 
 static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
-- 
2.20.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ