aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexei Shlychkov <x0177296@ti.com>2012-09-17 09:46:17 -0700
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:01:01 +0200
commite9c2665e3275d20a477fff8ed5c95b2ded63c09a (patch)
tree7948bf57aadcca516978926485184aafb0d2683d /drivers
parente5d10c5f79bacfebb9de16c1f7e5874e21669c7f (diff)
downloadkernel_samsung_tuna-e9c2665e3275d20a477fff8ed5c95b2ded63c09a.zip
kernel_samsung_tuna-e9c2665e3275d20a477fff8ed5c95b2ded63c09a.tar.gz
kernel_samsung_tuna-e9c2665e3275d20a477fff8ed5c95b2ded63c09a.tar.bz2
gcx: added geometry check.
An additional geometry check to prevent the user from supplying invalid geometry and causing L3 errors. Change-Id: I5c22dbc36ca1e4a64fa240aff0f052673b5a4116 Signed-off-by: Alexei Shlychkov <x0177296@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/gcx/gcbv/gcparser.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/misc/gcx/gcbv/gcparser.c b/drivers/misc/gcx/gcbv/gcparser.c
index 609c862..0f1a758 100644
--- a/drivers/misc/gcx/gcbv/gcparser.c
+++ b/drivers/misc/gcx/gcbv/gcparser.c
@@ -1270,6 +1270,7 @@ static inline bool valid_rect(struct bvsurfgeom *bvsurfgeom,
static bool valid_geom(struct surfaceinfo *surfaceinfo)
{
unsigned int size;
+ unsigned int height;
/* Compute the size of the surface. */
size = (surfaceinfo->geom->width *
@@ -1290,6 +1291,29 @@ static bool valid_geom(struct surfaceinfo *surfaceinfo)
return false;
}
+ /* Determine the height of the image. */
+ height = ((surfaceinfo->angle % 2) == 0)
+ ? surfaceinfo->geom->height
+ : surfaceinfo->geom->width;
+
+ /* Compute the size using the stide. */
+ size = surfaceinfo->geom->virtstride * height;
+
+ /* Make sure the size is not greater then the surface. */
+ if (size > surfaceinfo->buf.desc->length) {
+ GCERR("invalid geometry detected:\n");
+ GCERR(" specified dimensions: %dx%d, %d bitspp\n",
+ surfaceinfo->geom->width,
+ surfaceinfo->geom->height,
+ surfaceinfo->format.bitspp);
+ GCERR(" physical image height = %d\n", height);
+ GCERR(" image stride = %d\n", surfaceinfo->geom->virtstride);
+ GCERR(" computed surface size = %d\n", size);
+ GCERR(" specified surface size: %lu\n",
+ surfaceinfo->buf.desc->length);
+ return false;
+ }
+
return true;
}
@@ -1379,13 +1403,6 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
goto exit;
}
- /* Validate geometry. */
- if (!valid_geom(dstinfo)) {
- BVSETBLTERROR(BVERR_DSTGEOM,
- "destination geom exceeds surface size");
- goto exit;
- }
-
/* Destination stride must be 8 pixel aligned. */
if ((dstinfo->geom->virtstride
& (dstinfo->format.bitspp - 1)) != 0) {
@@ -1433,6 +1450,13 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
dstinfo->pixalign);
GCDBG(GCZONE_DEST, " surface offset (bytes) = %d\n",
dstinfo->bytealign);
+
+ /* Validate geometry. */
+ if (!valid_geom(dstinfo)) {
+ BVSETBLTERROR(BVERR_DSTGEOM,
+ "destination geom exceeds surface size");
+ goto exit;
+ }
}
/* Did clipping/destination rects change? */
@@ -1737,16 +1761,6 @@ enum bverror parse_source(struct bvbltparams *bvbltparams,
goto exit;
}
- /* Validate source geometry. */
- if (!valid_geom(srcinfo)) {
- BVSETBLTERROR((srcinfo->index == 0)
- ? BVERR_SRC1GEOM
- : BVERR_SRC2GEOM,
- "source%d geom exceeds surface size.",
- srcinfo->index + 1);
- goto exit;
- }
-
/* Source must be 8 pixel aligned. */
if ((srcinfo->geom->virtstride
& (srcinfo->format.bitspp - 1)) != 0) {
@@ -1820,6 +1834,16 @@ enum bverror parse_source(struct bvbltparams *bvbltparams,
srcinfo->geom->width, srcinfo->geom->height);
GCDBG(GCZONE_SRC, " mirror = %d\n", srcinfo->mirror);
+ /* Validate source geometry. */
+ if (!valid_geom(srcinfo)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1GEOM
+ : BVERR_SRC2GEOM,
+ "source%d geom exceeds surface size.",
+ srcinfo->index + 1);
+ goto exit;
+ }
+
exit:
return bverror;
}