diff options
author | Alexei Shlychkov <x0177296@ti.com> | 2012-09-17 09:46:17 -0700 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 13:01:01 +0200 |
commit | e9c2665e3275d20a477fff8ed5c95b2ded63c09a (patch) | |
tree | 7948bf57aadcca516978926485184aafb0d2683d /drivers/misc | |
parent | e5d10c5f79bacfebb9de16c1f7e5874e21669c7f (diff) | |
download | kernel_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/misc')
-rw-r--r-- | drivers/misc/gcx/gcbv/gcparser.c | 58 |
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; } |