tflite: Fix native handle deallocation size mismatch

The default new/delete memory management will act based on the given
type.
However, since native_handle_t contains zero-length (dynamic size)
array, which new/delete cannot handle properly.

Thus, instead of relying on the default deleter in the unique_ptr, which
use delete, this CL create a custom deleter that use malloc/free to
match the C behavior, which makes memory size management easier.

BUG=b:442765928
TEST=bazelisk test --config=host_clang '//android:hardware_buffer_test'

Change-Id: I84364f4149a2da99742a40f201af3a17d9541d44
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/tflite/+/6908322
Auto-Submit: Tommy Chiang <ototot@google.com>
Tested-by: Tommy Chiang <ototot@google.com>
Reviewed-by: Shik Chen <shik@chromium.org>
Commit-Queue: Shik Chen <shik@chromium.org>
diff --git a/android/hardware_buffer.cc b/android/hardware_buffer.cc
index ff614eb..db4fe86 100644
--- a/android/hardware_buffer.cc
+++ b/android/hardware_buffer.cc
@@ -357,7 +357,7 @@
     // The file descriptor (fd) in native_handle_t is the same one owned by
     // ScopedFd. Therefore, we don't need to close it separately when releasing
     // native_handle_t, nor do we need to duplicate it (dup) when cloning.
-    std::unique_ptr<native_handle_t> handle;
+    OwnedNativeHandle handle;
 
     // The usage mask applied when the buffer is locked. The value would be 0
     // when the buffer is not locked.
diff --git a/android/native_handle_util.cc b/android/native_handle_util.cc
index b94b86d..9c96ca5 100644
--- a/android/native_handle_util.cc
+++ b/android/native_handle_util.cc
@@ -6,31 +6,34 @@
 
 #include "android/native_handle_util.h"
 
-#include <memory>
+#include <cstdlib>
 
 namespace tflite::cros {
 
-std::unique_ptr<native_handle_t> CreateNativeHandle(int fd) {
+void NativeHandleDeleter::operator()(native_handle_t* handle) {
+  std::free(handle);
+}
+
+OwnedNativeHandle CreateNativeHandle(int fd) {
   size_t size = sizeof(native_handle_t) + sizeof(int);
-  auto* handle = static_cast<native_handle_t*>(operator new(size));
+  auto* handle = static_cast<native_handle_t*>(std::malloc(size));
   *handle = {
       .version = sizeof(native_handle_t),
       .numFds = 1,
       .numInts = 0,
   };
   handle->data[0] = fd;
-  return std::unique_ptr<native_handle_t>(handle);
+  return OwnedNativeHandle(handle);
 }
 
-std::unique_ptr<native_handle_t> CloneNativeHandle(
-    const native_handle_t* handle) {
+OwnedNativeHandle CloneNativeHandle(const native_handle_t* handle) {
   if (handle == nullptr) {
     return nullptr;
   }
 
   size_t size = sizeof(native_handle_t) +
                 sizeof(int) * (handle->numFds + handle->numInts);
-  auto* cloned = static_cast<native_handle_t*>(operator new(size));
+  auto* cloned = static_cast<native_handle_t*>(std::malloc(size));
 
   *cloned = {
       .version = sizeof(native_handle_t),
@@ -41,7 +44,7 @@
     cloned->data[i] = handle->data[i];
   }
 
-  return std::unique_ptr<native_handle_t>(cloned);
+  return OwnedNativeHandle(cloned);
 }
 
 }  // namespace tflite::cros
diff --git a/android/native_handle_util.h b/android/native_handle_util.h
index 9ba0713..c090b51 100644
--- a/android/native_handle_util.h
+++ b/android/native_handle_util.h
@@ -13,12 +13,19 @@
 
 namespace tflite::cros {
 
+// A helper to release memory allocated for native_handle_t.
+struct NativeHandleDeleter {
+  void operator()(native_handle_t* handle);
+};
+
+// A helper class to hold the native handle.
+using OwnedNativeHandle = std::unique_ptr<native_handle_t, NativeHandleDeleter>;
+
 // Creates a new native handle from the given fd.
-std::unique_ptr<native_handle_t> CreateNativeHandle(int fd);
+OwnedNativeHandle CreateNativeHandle(int fd);
 
 // Clones a native handle. The file descriptor(s) are copied without dup().
-std::unique_ptr<native_handle_t> CloneNativeHandle(
-    const native_handle_t* handle);
+OwnedNativeHandle CloneNativeHandle(const native_handle_t* handle);
 
 // TODO(shik): Add another copy helper that will dup() the file descriptors.