Add safety comments for pointers passed to extern "C" functions.

Test: m vmbase_example_kernel_bin
Change-Id: I443bee06f7ab2a2b2cff65ce22ae8b7f6ece890b

diff --git a/libs/libvmbase/src/bionic.rs b/libs/libvmbase/src/bionic.rs
index ac9f80f..2b59493 100644
--- a/libs/libvmbase/src/bionic.rs
+++ b/libs/libvmbase/src/bionic.rs
@@ -86,15 +86,20 @@
     unsafe { ERRNO }
 }
 
+/// # Safety
+///
+/// `buffer` must point to an allocation of at least `length` bytes which is valid to write to and
+/// has no concurrent access while this function is running.
 #[no_mangle]
-extern "C" fn getentropy(buffer: *mut c_void, length: usize) -> c_int {
+unsafe extern "C" fn getentropy(buffer: *mut c_void, length: usize) -> c_int {
     if length > 256 {
         // The maximum permitted value for the length argument is 256.
         set_errno(EIO);
         return -1;
     }
 
-    // SAFETY: Just like libc, we need to assume that `ptr` is valid.
+    // SAFETY: The caller promised that `buffer` is a valid pointer to at least `length` bytes with
+    // no concurrent access.
     let buffer = unsafe { slice::from_raw_parts_mut(buffer.cast::<u8>(), length) };
     fill_with_entropy(buffer).unwrap();
 
@@ -167,9 +172,13 @@
 #[no_mangle]
 static stderr: CFilePtr = CFilePtr::Stderr;
 
+/// # Safety
+///
+/// `c_str` must be a valid pointer to a NUL-terminated string which is not modified before this
+/// function returns.
 #[no_mangle]
-extern "C" fn fputs(c_str: *const c_char, stream: usize) -> c_int {
-    // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+unsafe extern "C" fn fputs(c_str: *const c_char, stream: usize) -> c_int {
+    // SAFETY: The caller promised that `c_str` is a valid NUL-terminated string.
     let c_str = unsafe { CStr::from_ptr(c_str) };
 
     if let (Ok(s), Ok(f)) = (c_str.to_str(), CFilePtr::try_from(stream)) {
@@ -181,11 +190,16 @@
     }
 }
 
+/// # Safety
+///
+/// `ptr` must be a valid pointer to an array of at least `size * nmemb` initialised bytes, which
+/// are not modified before this function returns.
 #[no_mangle]
-extern "C" fn fwrite(ptr: *const c_void, size: usize, nmemb: usize, stream: usize) -> usize {
+unsafe extern "C" fn fwrite(ptr: *const c_void, size: usize, nmemb: usize, stream: usize) -> usize {
     let length = size.saturating_mul(nmemb);
 
-    // SAFETY: Just like libc, we need to assume that `ptr` is valid.
+    // SAFETY: The caller promised that `ptr` is a valid pointer to at least `size * nmemb`
+    // initialised bytes, and `length` is no more than that.
     let bytes = unsafe { slice::from_raw_parts(ptr as *const u8, length) };
 
     if let (Ok(s), Ok(f)) = (str::from_utf8(bytes), CFilePtr::try_from(stream)) {
@@ -201,12 +215,16 @@
     cstr_error(n).as_ptr().cast_mut().cast()
 }
 
+/// # Safety
+///
+/// `s` must be a valid pointer to a NUL-terminated string which is not modified before this
+/// function returns.
 #[no_mangle]
-extern "C" fn perror(s: *const c_char) {
+unsafe extern "C" fn perror(s: *const c_char) {
     let prefix = if s.is_null() {
         None
     } else {
-        // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+        // SAFETY: The caller promised that `s` is a valid NUL-terminated string.
         let c_str = unsafe { CStr::from_ptr(s) };
         if c_str.is_empty() {
             None