Move from memset to memset_s.

This adds the extra bounds checks and panics if there is a violation.

Change-Id: I9db3ca44be4f9c39964d912b57fe7b68e2792bc1
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 8ec1f92..8e1b7e2 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -70,6 +70,10 @@
 
 # Standard library functions.
 source_set("std") {
+  sources = [
+    "std.c",
+  ]
+
   deps = [
     "//src/arch/${plat_arch}:std",
   ]
diff --git a/src/api.c b/src/api.c
index cd46073..ec98c22 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1185,7 +1185,7 @@
 		return false;
 	}
 
-	memset(ptr, 0, size);
+	memset_s(ptr, size, 0, size);
 	arch_mm_write_back_dcache(ptr, size);
 	mm_unmap(begin, end, ppool);
 
diff --git a/src/arch/aarch64/cpu.c b/src/arch/aarch64/cpu.c
index b1280a6..a1a2c87 100644
--- a/src/arch/aarch64/cpu.c
+++ b/src/arch/aarch64/cpu.c
@@ -42,7 +42,7 @@
 	uintreg_t cptr;
 	uintreg_t cnthctl;
 
-	memset(r, 0, sizeof(*r));
+	memset_s(r, sizeof(*r), 0, sizeof(*r));
 
 	r->pc = pc;
 	r->r[0] = arg;
diff --git a/src/cpu.c b/src/cpu.c
index b2213d1..ca26122 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -159,7 +159,7 @@
 
 void vcpu_init(struct vcpu *vcpu, struct vm *vm)
 {
-	memset(vcpu, 0, sizeof(*vcpu));
+	memset_s(vcpu, sizeof(*vcpu), 0, sizeof(*vcpu));
 	sl_init(&vcpu->lock);
 	vcpu->regs_available = true;
 	vcpu->vm = vm;
diff --git a/src/fdt.c b/src/fdt.c
index b781a72..f02864a 100644
--- a/src/fdt.c
+++ b/src/fdt.c
@@ -136,7 +136,7 @@
 	uint32_t begin = be32toh(hdr->off_dt_struct);
 	uint32_t size = be32toh(hdr->size_dt_struct);
 
-	memset(node, 0, sizeof(*node));
+	memset_s(node, sizeof(*node), 0, sizeof(*node));
 
 	/* Check the magic number before anything else. */
 	if (hdr->magic != be32toh(FDT_MAGIC)) {
diff --git a/src/std.c b/src/std.c
new file mode 100644
index 0000000..00d4704
--- /dev/null
+++ b/src/std.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hf/std.h"
+
+#include "hf/panic.h"
+
+/* Declare unsafe functions locally so they are not available globally. */
+void *memset(void *s, int c, size_t n);
+
+void memset_s(void *dest, rsize_t destsz, int ch, rsize_t count)
+{
+	if (dest == NULL) {
+		goto fail;
+	}
+
+	if (destsz > RSIZE_MAX || count > RSIZE_MAX) {
+		goto fail;
+	}
+
+	if (count > destsz) {
+		goto fail;
+	}
+
+	memset(dest, ch, count);
+	return;
+
+fail:
+	panic("memset_s failure");
+}
diff --git a/src/vm.c b/src/vm.c
index a58886e..d1fb5bb 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -36,7 +36,7 @@
 
 	vm = &vms[vm_count];
 
-	memset(vm, 0, sizeof(*vm));
+	memset_s(vm, sizeof(*vm), 0, sizeof(*vm));
 
 	list_init(&vm->mailbox.waiter_list);
 	list_init(&vm->mailbox.ready_list);