Loading system/gd/rust/linux/service/src/main.rs +4 −1 Original line number Diff line number Diff line Loading @@ -176,7 +176,10 @@ fn main() -> Result<(), Box<dyn Error>> { bluetooth_media.clone(), tx.clone(), )))); let bt_sock_mgr = Arc::new(Mutex::new(Box::new(BluetoothSocketManager::new(tx.clone())))); let bt_sock_mgr = Arc::new(Mutex::new(Box::new(BluetoothSocketManager::new( tx.clone(), bluetooth_admin.clone(), )))); let qa = Arc::new(Mutex::new(Box::new(BluetoothQA::new(tx.clone())))); let dis = Arc::new(Mutex::new(Box::new(DeviceInformation::new(bluetooth_gatt.clone(), tx.clone())))); Loading system/gd/rust/linux/stack/src/bluetooth_admin.rs +7 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ pub struct BluetoothAdmin { allowed_services: HashSet<Uuid128Bit>, callbacks: Callbacks<dyn IBluetoothAdminPolicyCallback + Send>, device_policy_affect_cache: HashMap<BluetoothDevice, Option<PolicyEffect>>, tx: Sender<Message>, } impl BluetoothAdmin { Loading @@ -75,6 +76,7 @@ impl BluetoothAdmin { allowed_services: HashSet::new(), //empty means allowed all services callbacks: Callbacks::new(tx.clone(), Message::AdminCallbackDisconnected), device_policy_affect_cache: HashMap::new(), tx: tx.clone(), }; if admin.load_config().is_err() { Loading Loading @@ -227,6 +229,11 @@ impl IBluetoothAdmin for BluetoothAdmin { cb.on_service_allowlist_changed(allowed_services.clone()); }); let txl = self.tx.clone(); tokio::spawn(async move { let _ = txl.send(Message::AdminPolicyChanged).await; }); for (device, effect) in self.device_policy_affect_cache.clone().iter() { let uuids = adapter.lock().unwrap().get_remote_uuids(device.clone()); let new_effect = self.new_device_policy_effect(Some(uuids)); Loading system/gd/rust/linux/stack/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ pub enum Message { // Admin policy related AdminCallbackDisconnected(u32), HidHostEnable, AdminPolicyChanged, // Dis callbacks Dis(ServiceCallbacks), Loading Loading @@ -342,6 +343,9 @@ impl Stack { Message::HidHostEnable => { bluetooth.lock().unwrap().enable_hidhost(); } Message::AdminPolicyChanged => { bluetooth_socketmgr.lock().unwrap().handle_admin_policy_changed(); } Message::Dis(callback) => { bluetooth_dis.lock().unwrap().handle_callbacks(&callback); } Loading system/gd/rust/linux/stack/src/socket_manager.rs +60 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ use tokio::task::JoinHandle; use tokio::time; use crate::bluetooth::BluetoothDevice; use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin}; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::Message; Loading Loading @@ -396,11 +397,19 @@ struct InternalListeningSocket { /// Channel to future that listens for `accept` and `close` signals. tx: Sender<SocketRunnerActions>, /// Used by admin uuid: Option<Uuid>, } impl InternalListeningSocket { fn new(_callback_id: CallbackId, socket_id: SocketId, tx: Sender<SocketRunnerActions>) -> Self { InternalListeningSocket { _callback_id, socket_id, tx } fn new( _callback_id: CallbackId, socket_id: SocketId, tx: Sender<SocketRunnerActions>, uuid: Option<Uuid>, ) -> Self { InternalListeningSocket { _callback_id, socket_id, tx, uuid } } } Loading Loading @@ -492,11 +501,14 @@ pub struct BluetoothSocketManager { /// Channel TX for the mainloop for topstack. tx: Sender<Message>, /// Admin admin: Arc<Mutex<Box<BluetoothAdmin>>>, } impl BluetoothSocketManager { /// Constructs the IBluetooth implementation. pub fn new(tx: Sender<Message>) -> Self { pub fn new(tx: Sender<Message>, admin: Arc<Mutex<Box<BluetoothAdmin>>>) -> Self { let callbacks = Callbacks::new(tx.clone(), Message::SocketManagerCallbackDisconnected); let socket_counter: u64 = 1000; let futures = HashMap::new(); Loading @@ -518,6 +530,7 @@ impl BluetoothSocketManager { sock: None, socket_counter, tx, admin, } } Loading Loading @@ -549,6 +562,13 @@ impl BluetoothSocketManager { mut socket_info: BluetoothServerSocket, cbid: CallbackId, ) -> SocketResult { if let Some(uuid) = socket_info.uuid { if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) { log::debug!("service {} is blocked by admin policy", uuid); return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID); } } // Create listener socket pair let (mut status, result) = self.sock.as_ref().expect("Socket Manager not initialized").listen( Loading Loading @@ -578,7 +598,7 @@ impl BluetoothSocketManager { let (runner_tx, runner_rx) = channel::<SocketRunnerActions>(10); // Keep track of active listener sockets. let listener = InternalListeningSocket::new(cbid, id, runner_tx); let listener = InternalListeningSocket::new(cbid, id, runner_tx, socket_info.uuid); self.listening.entry(cbid).or_default().push(listener); // Push a listening task to local runtime to wait for device to Loading Loading @@ -632,6 +652,13 @@ impl BluetoothSocketManager { mut socket_info: BluetoothSocket, cbid: CallbackId, ) -> SocketResult { if let Some(uuid) = socket_info.uuid { if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) { log::debug!("service {} is blocked by admin policy", uuid); return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID); } } let addr = match RawAddress::from_string(socket_info.remote_device.address.clone()) { Some(v) => v, None => { Loading Loading @@ -1135,6 +1162,35 @@ impl BluetoothSocketManager { } } /// Close Rfcomm sockets whose UUID is not allowed by policy pub fn handle_admin_policy_changed(&mut self) { let forbidden_sockets = self .listening .values() .into_iter() .flatten() .filter(|sock| { sock.uuid // Don't need to close L2cap socket (indicated by no uuid). .map_or(false, |uuid| { !self.admin.lock().unwrap().is_service_allowed(uuid.into()) }) }) .map(|sock| (sock.socket_id, sock.tx.clone(), sock.uuid.unwrap())) .collect::<Vec<(u64, Sender<SocketRunnerActions>, Uuid)>>(); self.runtime.spawn(async move { for (id, tx, uuid) in forbidden_sockets { log::debug!( "socket id {} is not allowed by admin policy due to uuid {}, closing", id, uuid ); let _ = tx.send(SocketRunnerActions::Close(id)).await; } }); } pub fn remove_callback(&mut self, callback: CallbackId) { // Remove any associated futures and sockets waiting to accept. self.futures.remove(&callback); Loading system/gd/rust/topshim/src/btif.rs +6 −0 Original line number Diff line number Diff line Loading @@ -396,6 +396,12 @@ impl From<[u8; 16]> for Uuid { } } impl From<Uuid> for [u8; 16] { fn from(uuid: Uuid) -> Self { uuid.uu } } impl Hash for Uuid { fn hash<H: Hasher>(&self, state: &mut H) { self.uu.hash(state); Loading Loading
system/gd/rust/linux/service/src/main.rs +4 −1 Original line number Diff line number Diff line Loading @@ -176,7 +176,10 @@ fn main() -> Result<(), Box<dyn Error>> { bluetooth_media.clone(), tx.clone(), )))); let bt_sock_mgr = Arc::new(Mutex::new(Box::new(BluetoothSocketManager::new(tx.clone())))); let bt_sock_mgr = Arc::new(Mutex::new(Box::new(BluetoothSocketManager::new( tx.clone(), bluetooth_admin.clone(), )))); let qa = Arc::new(Mutex::new(Box::new(BluetoothQA::new(tx.clone())))); let dis = Arc::new(Mutex::new(Box::new(DeviceInformation::new(bluetooth_gatt.clone(), tx.clone())))); Loading
system/gd/rust/linux/stack/src/bluetooth_admin.rs +7 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ pub struct BluetoothAdmin { allowed_services: HashSet<Uuid128Bit>, callbacks: Callbacks<dyn IBluetoothAdminPolicyCallback + Send>, device_policy_affect_cache: HashMap<BluetoothDevice, Option<PolicyEffect>>, tx: Sender<Message>, } impl BluetoothAdmin { Loading @@ -75,6 +76,7 @@ impl BluetoothAdmin { allowed_services: HashSet::new(), //empty means allowed all services callbacks: Callbacks::new(tx.clone(), Message::AdminCallbackDisconnected), device_policy_affect_cache: HashMap::new(), tx: tx.clone(), }; if admin.load_config().is_err() { Loading Loading @@ -227,6 +229,11 @@ impl IBluetoothAdmin for BluetoothAdmin { cb.on_service_allowlist_changed(allowed_services.clone()); }); let txl = self.tx.clone(); tokio::spawn(async move { let _ = txl.send(Message::AdminPolicyChanged).await; }); for (device, effect) in self.device_policy_affect_cache.clone().iter() { let uuids = adapter.lock().unwrap().get_remote_uuids(device.clone()); let new_effect = self.new_device_policy_effect(Some(uuids)); Loading
system/gd/rust/linux/stack/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ pub enum Message { // Admin policy related AdminCallbackDisconnected(u32), HidHostEnable, AdminPolicyChanged, // Dis callbacks Dis(ServiceCallbacks), Loading Loading @@ -342,6 +343,9 @@ impl Stack { Message::HidHostEnable => { bluetooth.lock().unwrap().enable_hidhost(); } Message::AdminPolicyChanged => { bluetooth_socketmgr.lock().unwrap().handle_admin_policy_changed(); } Message::Dis(callback) => { bluetooth_dis.lock().unwrap().handle_callbacks(&callback); } Loading
system/gd/rust/linux/stack/src/socket_manager.rs +60 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ use tokio::task::JoinHandle; use tokio::time; use crate::bluetooth::BluetoothDevice; use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin}; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::Message; Loading Loading @@ -396,11 +397,19 @@ struct InternalListeningSocket { /// Channel to future that listens for `accept` and `close` signals. tx: Sender<SocketRunnerActions>, /// Used by admin uuid: Option<Uuid>, } impl InternalListeningSocket { fn new(_callback_id: CallbackId, socket_id: SocketId, tx: Sender<SocketRunnerActions>) -> Self { InternalListeningSocket { _callback_id, socket_id, tx } fn new( _callback_id: CallbackId, socket_id: SocketId, tx: Sender<SocketRunnerActions>, uuid: Option<Uuid>, ) -> Self { InternalListeningSocket { _callback_id, socket_id, tx, uuid } } } Loading Loading @@ -492,11 +501,14 @@ pub struct BluetoothSocketManager { /// Channel TX for the mainloop for topstack. tx: Sender<Message>, /// Admin admin: Arc<Mutex<Box<BluetoothAdmin>>>, } impl BluetoothSocketManager { /// Constructs the IBluetooth implementation. pub fn new(tx: Sender<Message>) -> Self { pub fn new(tx: Sender<Message>, admin: Arc<Mutex<Box<BluetoothAdmin>>>) -> Self { let callbacks = Callbacks::new(tx.clone(), Message::SocketManagerCallbackDisconnected); let socket_counter: u64 = 1000; let futures = HashMap::new(); Loading @@ -518,6 +530,7 @@ impl BluetoothSocketManager { sock: None, socket_counter, tx, admin, } } Loading Loading @@ -549,6 +562,13 @@ impl BluetoothSocketManager { mut socket_info: BluetoothServerSocket, cbid: CallbackId, ) -> SocketResult { if let Some(uuid) = socket_info.uuid { if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) { log::debug!("service {} is blocked by admin policy", uuid); return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID); } } // Create listener socket pair let (mut status, result) = self.sock.as_ref().expect("Socket Manager not initialized").listen( Loading Loading @@ -578,7 +598,7 @@ impl BluetoothSocketManager { let (runner_tx, runner_rx) = channel::<SocketRunnerActions>(10); // Keep track of active listener sockets. let listener = InternalListeningSocket::new(cbid, id, runner_tx); let listener = InternalListeningSocket::new(cbid, id, runner_tx, socket_info.uuid); self.listening.entry(cbid).or_default().push(listener); // Push a listening task to local runtime to wait for device to Loading Loading @@ -632,6 +652,13 @@ impl BluetoothSocketManager { mut socket_info: BluetoothSocket, cbid: CallbackId, ) -> SocketResult { if let Some(uuid) = socket_info.uuid { if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) { log::debug!("service {} is blocked by admin policy", uuid); return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID); } } let addr = match RawAddress::from_string(socket_info.remote_device.address.clone()) { Some(v) => v, None => { Loading Loading @@ -1135,6 +1162,35 @@ impl BluetoothSocketManager { } } /// Close Rfcomm sockets whose UUID is not allowed by policy pub fn handle_admin_policy_changed(&mut self) { let forbidden_sockets = self .listening .values() .into_iter() .flatten() .filter(|sock| { sock.uuid // Don't need to close L2cap socket (indicated by no uuid). .map_or(false, |uuid| { !self.admin.lock().unwrap().is_service_allowed(uuid.into()) }) }) .map(|sock| (sock.socket_id, sock.tx.clone(), sock.uuid.unwrap())) .collect::<Vec<(u64, Sender<SocketRunnerActions>, Uuid)>>(); self.runtime.spawn(async move { for (id, tx, uuid) in forbidden_sockets { log::debug!( "socket id {} is not allowed by admin policy due to uuid {}, closing", id, uuid ); let _ = tx.send(SocketRunnerActions::Close(id)).await; } }); } pub fn remove_callback(&mut self, callback: CallbackId) { // Remove any associated futures and sockets waiting to accept. self.futures.remove(&callback); Loading
system/gd/rust/topshim/src/btif.rs +6 −0 Original line number Diff line number Diff line Loading @@ -396,6 +396,12 @@ impl From<[u8; 16]> for Uuid { } } impl From<Uuid> for [u8; 16] { fn from(uuid: Uuid) -> Self { uuid.uu } } impl Hash for Uuid { fn hash<H: Hasher>(&self, state: &mut H) { self.uu.hash(state); Loading