include/shared/lk: Column Sizing with callback am: 6f6c0c3649

Original change: https://android-review.googlesource.com/c/trusty/lk/trusty/+/3172799

Change-Id: I502da97580ecf2388466fe508a9492f6a8e1e9be
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/lib/sm/sm.c b/lib/sm/sm.c
index 81db962..1432d86 100644
--- a/lib/sm/sm.c
+++ b/lib/sm/sm.c
@@ -94,7 +94,9 @@
                api_version, sm_api_version_min, sm_api_version);
         api_version = sm_api_version;
     } else {
+        /* Update and lock the version to prevent downgrade */
         sm_api_version = api_version;
+        sm_api_version_min = api_version;
     }
     spin_unlock(&sm_api_version_lock);
 
diff --git a/lib/sm/smcall.c b/lib/sm/smcall.c
index 5837145..54ad14d 100644
--- a/lib/sm/smcall.c
+++ b/lib/sm/smcall.c
@@ -134,7 +134,7 @@
     if (index == -1)
         return version_len;
 
-    if ((size_t)index >= version_len)
+    if (index < 0 || (size_t)index >= version_len)
         return SM_ERR_INVALID_PARAMETERS;
 
     return lk_version[index];
diff --git a/lib/trusty/syscall.c b/lib/trusty/syscall.c
index 745a051..746abea 100644
--- a/lib/trusty/syscall.c
+++ b/lib/trusty/syscall.c
@@ -93,16 +93,21 @@
     return sys_fds[fd];
 }
 
-static bool valid_address(vaddr_t addr, u_int size) {
-    size = round_up(size + (addr & (PAGE_SIZE - 1)), PAGE_SIZE);
+static bool valid_address(vaddr_t addr, const u_int size) {
+    u_int rsize = round_up(size + (addr & (PAGE_SIZE - 1)), PAGE_SIZE);
     addr = round_down(addr, PAGE_SIZE);
 
-    while (size) {
+    /* Ensure size did not overflow */
+    if (rsize < size) {
+        return false;
+    }
+
+    while (rsize) {
         if (!is_user_address(addr) || !vaddr_to_paddr((void*)addr)) {
             return false;
         }
         addr += PAGE_SIZE;
-        size -= PAGE_SIZE;
+        rsize -= PAGE_SIZE;
     }
 
     return true;
diff --git a/lib/trusty/vqueue.c b/lib/trusty/vqueue.c
index 437fd14..5a59ac5 100644
--- a/lib/trusty/vqueue.c
+++ b/lib/trusty/vqueue.c
@@ -26,6 +26,7 @@
 #include <assert.h>
 #include <err.h>
 #include <lib/sm.h>
+#include <lk/pow2.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -42,6 +43,9 @@
 
 #define VQ_LOCK_FLAGS SPIN_LOCK_FLAG_INTERRUPTS
 
+/* Arbitrary limit to ensure vring size doesn't overflow */
+#define VQ_MAX_RING_NUM 256
+
 int vqueue_init(struct vqueue* vq,
                 uint32_t id,
                 ext_mem_client_id_t client_id,
@@ -56,6 +60,16 @@
 
     DEBUG_ASSERT(vq);
 
+    if (num > VQ_MAX_RING_NUM) {
+        LTRACEF("vring too large: %u\n", num);
+        return ERR_INVALID_ARGS;
+    }
+
+    if (align == 0 || !ispow2(align)) {
+        LTRACEF("bad vring alignment: %lu\n", align);
+        return ERR_INVALID_ARGS;
+    }
+
     vq->vring_sz = vring_size(num, align);
     ret = ext_mem_map_obj_id(vmm_get_kernel_aspace(), "vqueue", client_id,
                              shared_mem_id, 0, 0,