@@ -298,6 +298,7 @@ enum {
HCI_FORCE_STATIC_ADDR,
HCI_LL_RPA_RESOLUTION,
HCI_CMD_PENDING,
+ HCI_ENFORCE_MITM_SMP,
__HCI_NUM_FLAGS,
};
@@ -2396,7 +2396,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
/* Require MITM if IO Capability allows or the security level
* requires it.
*/
- if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
+ if ((hci_dev_test_flag(hcon->hdev, HCI_ENFORCE_MITM_SMP) &&
+ hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT) ||
hcon->pending_sec_level > BT_SECURITY_MEDIUM)
authreq |= SMP_AUTH_MITM;
@@ -3402,6 +3403,50 @@ static const struct file_operations force_bredr_smp_fops = {
.llseek = default_llseek,
};
+static ssize_t enforce_mitm_smp_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ char buf[3];
+
+ buf[0] = hci_dev_test_flag(hdev, HCI_ENFORCE_MITM_SMP) ? 'Y' : 'N';
+ buf[1] = '\n';
+ buf[2] = '\0';
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t enforce_mitm_smp_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ char buf[32];
+ size_t buf_size = min(count, (sizeof(buf) - 1));
+ bool enable;
+
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ if (strtobool(buf, &enable))
+ return -EINVAL;
+
+ if (enable == hci_dev_test_flag(hdev, HCI_ENFORCE_MITM_SMP))
+ return -EALREADY;
+
+ hci_dev_change_flag(hdev, HCI_ENFORCE_MITM_SMP);
+
+ return count;
+}
+
+static const struct file_operations enforce_mitm_smp_fops = {
+ .open = simple_open,
+ .read = enforce_mitm_smp_read,
+ .write = enforce_mitm_smp_write,
+ .llseek = default_llseek,
+};
+
int smp_register(struct hci_dev *hdev)
{
struct l2cap_chan *chan;
@@ -3426,6 +3471,11 @@ int smp_register(struct hci_dev *hdev)
hdev->smp_data = chan;
+ /* Enforce the policy of determining MITM flag by io capabilities. */
+ hci_dev_set_flag(hdev, HCI_ENFORCE_MITM_SMP);
+ debugfs_create_file("enforce_mitm_smp", 0644, hdev->debugfs, hdev,
+ &enforce_mitm_smp_fops);
+
/* If the controller does not support BR/EDR Secure Connections
* feature, then the BR/EDR SMP channel shall not be present.
*