[bt][hci-uart] Fix possible use-after-free.

serial_write now takes ownership of the buffer it's passed (for asynch
serial).  Previously the snoop log was written to after serial_write,
which may not be valid any longer, as the asynchronous serial callback
frees the same buffer when it is finished writing.

log to the snoop channel before actually writing to serial to eliminate
this possibility.

Add locking to the write in hci_handle_acl_reasd_events as it was
missing before and this function is called while unlocked.

Bug: 42413
Change-Id: Ifba2da8f669dea6f0c4b3ef4664f43106fd9dde3
diff --git a/zircon/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c b/zircon/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
index 3a42e7e..c141ab1 100644
--- a/zircon/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
+++ b/zircon/system/dev/bluetooth/bt-transport-uart/bt-transport-uart.c
@@ -191,12 +191,13 @@
 
     buf[0] = HCI_COMMAND;
     length++;
-    serial_write(hci, buf, length);
 
     mtx_lock(&hci->mutex);
     snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_CMD, false), buf + 1,
                                length - 1);
     mtx_unlock(&hci->mutex);
+
+    serial_write(hci, buf, length);
   }
 
   return;
@@ -221,9 +222,13 @@
 
     buf[0] = HCI_ACL_DATA;
     length++;
-    serial_write(hci, buf, length);
+
+    mtx_lock(&hci->mutex);
     snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_ACL, false), buf + 1,
                                length - 1);
+    mtx_unlock(&hci->mutex);
+
+    serial_write(hci, buf, length);
   }
 
   return;