video: tegra: host: fix integer overflow
Deepak Nibade [Mon, 27 Jun 2016 08:43:26 +0000 (13:43 +0530)]
Below addition on 32 bit architecture machines could
cause integer overflow since we will assign overflowed
value to "num_unpins"
s64 num_unpins = num_cmdbufs + num_relocs

Fix this and other calculations by explicitly typecasting
variables to u64 first

Bug 1781393

Change-Id: Ib7d9c0be4ac61dc404512b4bb0331aa20a6978bc
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1171748
(cherry picked from commit 8f00b96c137b9c4cb43a8dbe2e153fae49524113)
Reviewed-on: http://git-master/r/1172519
(cherry picked from commit 61229625b1e19d5a93a9458f04e0cce356dbdee3)
Reviewed-on: http://git-master/r/1190218
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Jeetesh Burman <jburman@nvidia.com>
Tested-by: Jeetesh Burman <jburman@nvidia.com>
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>

drivers/video/tegra/host/nvhost_job.c

index 2100749..cd83b96 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Job
  *
- * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 static size_t job_size(u32 num_cmdbufs, u32 num_relocs, u32 num_waitchks,
                        u32 num_syncpts)
 {
-       s64 num_unpins = num_cmdbufs + num_relocs;
-       s64 total;
+       u64 num_unpins = (u64)num_cmdbufs + (u64)num_relocs;
+       u64 total;
 
        total = sizeof(struct nvhost_job)
-                       + num_relocs * sizeof(struct nvhost_reloc)
-                       + num_relocs * sizeof(struct nvhost_reloc_shift)
+                       + (u64)num_relocs * sizeof(struct nvhost_reloc)
+                       + (u64)num_relocs * sizeof(struct nvhost_reloc_shift)
                        + num_unpins * sizeof(struct nvhost_job_unpin)
-                       + num_waitchks * sizeof(struct nvhost_waitchk)
-                       + num_cmdbufs * sizeof(struct nvhost_job_gather)
+                       + (u64)num_waitchks * sizeof(struct nvhost_waitchk)
+                       + (u64)num_cmdbufs * sizeof(struct nvhost_job_gather)
                        + num_unpins * sizeof(dma_addr_t)
                        + num_unpins * sizeof(struct nvhost_pinid)
-                       + num_syncpts * sizeof(struct nvhost_job_syncpt);
+                       + (u64)num_syncpts * sizeof(struct nvhost_job_syncpt);
 
-       if(total > ULONG_MAX)
+       if (total > UINT_MAX)
                return 0;
+
        return (size_t)total;
 }