Unverified Commit fa3f9ee5 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6525 v2 CVE-2024-24860 bugfix

Merge Pull Request from: @ci-robot 
 
PR sync from: Liu Jian <liujian56@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/CJBQ35V3SAQ6KPR3T4PXRBDYCL42SPXG/ 
CVE-2024-24860

v1->v2: change bugzilla tag

Gui-Dong Han (1):
  Bluetooth: Fix atomicity violation in {min,max}_key_size_set

Marcel Holtmann (1):
  Bluetooth: Move {min,max}_key_size debugfs into hci_debugfs_create_le


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/I917MX 
 
Link:https://gitee.com/openeuler/kernel/pulls/6525

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Reviewed-by: default avatarLiu YongQiang <liuyongqiang13@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents 95b433f1 71923a9c
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#include "smp.h"
#include "hci_debugfs.h"

#define DEFINE_QUIRK_ATTRIBUTE(__name, __quirk)				      \
@@ -941,6 +942,66 @@ static int adv_max_interval_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
			adv_max_interval_set, "%llu\n");

static int min_key_size_set(void *data, u64 val)
{
	struct hci_dev *hdev = data;

	hci_dev_lock(hdev);
	if (val > hdev->le_max_key_size || val < SMP_MIN_ENC_KEY_SIZE) {
		hci_dev_unlock(hdev);
		return -EINVAL;
	}

	hdev->le_min_key_size = val;
	hci_dev_unlock(hdev);

	return 0;
}

static int min_key_size_get(void *data, u64 *val)
{
	struct hci_dev *hdev = data;

	hci_dev_lock(hdev);
	*val = hdev->le_min_key_size;
	hci_dev_unlock(hdev);

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(min_key_size_fops, min_key_size_get,
			min_key_size_set, "%llu\n");

static int max_key_size_set(void *data, u64 val)
{
	struct hci_dev *hdev = data;

	hci_dev_lock(hdev);
	if (val > SMP_MAX_ENC_KEY_SIZE || val < hdev->le_min_key_size) {
		hci_dev_unlock(hdev);
		return -EINVAL;
	}

	hdev->le_max_key_size = val;
	hci_dev_unlock(hdev);

	return 0;
}

static int max_key_size_get(void *data, u64 *val)
{
	struct hci_dev *hdev = data;

	hci_dev_lock(hdev);
	*val = hdev->le_max_key_size;
	hci_dev_unlock(hdev);

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(max_key_size_fops, max_key_size_get,
			max_key_size_set, "%llu\n");

DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
		       HCI_QUIRK_STRICT_DUPLICATE_FILTER);
DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
@@ -994,6 +1055,10 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
			    &adv_max_interval_fops);
	debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
			   &hdev->discov_interleaved_timeout);
	debugfs_create_file("min_key_size", 0644, hdev->debugfs, hdev,
			    &min_key_size_fops);
	debugfs_create_file("max_key_size", 0644, hdev->debugfs, hdev,
			    &max_key_size_fops);

	debugfs_create_file("quirk_strict_duplicate_filter", 0644,
			    hdev->debugfs, hdev,
+0 −93
Original line number Diff line number Diff line
@@ -3401,94 +3401,6 @@ static const struct file_operations force_bredr_smp_fops = {
	.llseek		= default_llseek,
};

static ssize_t le_min_key_size_read(struct file *file,
				     char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct hci_dev *hdev = file->private_data;
	char buf[4];

	snprintf(buf, sizeof(buf), "%2u\n", hdev->le_min_key_size);

	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
}

static ssize_t le_min_key_size_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));
	u8 key_size;

	if (copy_from_user(buf, user_buf, buf_size))
		return -EFAULT;

	buf[buf_size] = '\0';

	sscanf(buf, "%hhu", &key_size);

	if (key_size > hdev->le_max_key_size ||
	    key_size < SMP_MIN_ENC_KEY_SIZE)
		return -EINVAL;

	hdev->le_min_key_size = key_size;

	return count;
}

static const struct file_operations le_min_key_size_fops = {
	.open		= simple_open,
	.read		= le_min_key_size_read,
	.write		= le_min_key_size_write,
	.llseek		= default_llseek,
};

static ssize_t le_max_key_size_read(struct file *file,
				     char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct hci_dev *hdev = file->private_data;
	char buf[4];

	snprintf(buf, sizeof(buf), "%2u\n", hdev->le_max_key_size);

	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
}

static ssize_t le_max_key_size_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));
	u8 key_size;

	if (copy_from_user(buf, user_buf, buf_size))
		return -EFAULT;

	buf[buf_size] = '\0';

	sscanf(buf, "%hhu", &key_size);

	if (key_size > SMP_MAX_ENC_KEY_SIZE ||
	    key_size < hdev->le_min_key_size)
		return -EINVAL;

	hdev->le_max_key_size = key_size;

	return count;
}

static const struct file_operations le_max_key_size_fops = {
	.open		= simple_open,
	.read		= le_max_key_size_read,
	.write		= le_max_key_size_write,
	.llseek		= default_llseek,
};

int smp_register(struct hci_dev *hdev)
{
	struct l2cap_chan *chan;
@@ -3513,11 +3425,6 @@ int smp_register(struct hci_dev *hdev)

	hdev->smp_data = chan;

	debugfs_create_file("le_min_key_size", 0644, hdev->debugfs, hdev,
			    &le_min_key_size_fops);
	debugfs_create_file("le_max_key_size", 0644, hdev->debugfs, hdev,
			    &le_max_key_size_fops);

	/* If the controller does not support BR/EDR Secure Connections
	 * feature, then the BR/EDR SMP channel shall not be present.
	 *