cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mgmt_config.c (9489B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2
      3/*
      4 * Copyright (C) 2020 Google Corporation
      5 */
      6
      7#include <net/bluetooth/bluetooth.h>
      8#include <net/bluetooth/hci_core.h>
      9#include <net/bluetooth/mgmt.h>
     10
     11#include "mgmt_util.h"
     12#include "mgmt_config.h"
     13
     14#define HDEV_PARAM_U16(_param_name_) \
     15	struct {\
     16		struct mgmt_tlv entry; \
     17		__le16 value; \
     18	} __packed _param_name_
     19
     20#define HDEV_PARAM_U8(_param_name_) \
     21	struct {\
     22		struct mgmt_tlv entry; \
     23		__u8 value; \
     24	} __packed _param_name_
     25
     26#define TLV_SET_U16(_param_code_, _param_name_) \
     27	{ \
     28		{ cpu_to_le16(_param_code_), sizeof(__u16) }, \
     29		cpu_to_le16(hdev->_param_name_) \
     30	}
     31
     32#define TLV_SET_U8(_param_code_, _param_name_) \
     33	{ \
     34		{ cpu_to_le16(_param_code_), sizeof(__u8) }, \
     35		hdev->_param_name_ \
     36	}
     37
     38#define TLV_SET_U16_JIFFIES_TO_MSECS(_param_code_, _param_name_) \
     39	{ \
     40		{ cpu_to_le16(_param_code_), sizeof(__u16) }, \
     41		cpu_to_le16(jiffies_to_msecs(hdev->_param_name_)) \
     42	}
     43
     44int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
     45			   u16 data_len)
     46{
     47	int ret;
     48	struct mgmt_rp_read_def_system_config {
     49		/* Please see mgmt-api.txt for documentation of these values */
     50		HDEV_PARAM_U16(def_page_scan_type);
     51		HDEV_PARAM_U16(def_page_scan_int);
     52		HDEV_PARAM_U16(def_page_scan_window);
     53		HDEV_PARAM_U16(def_inq_scan_type);
     54		HDEV_PARAM_U16(def_inq_scan_int);
     55		HDEV_PARAM_U16(def_inq_scan_window);
     56		HDEV_PARAM_U16(def_br_lsto);
     57		HDEV_PARAM_U16(def_page_timeout);
     58		HDEV_PARAM_U16(sniff_min_interval);
     59		HDEV_PARAM_U16(sniff_max_interval);
     60		HDEV_PARAM_U16(le_adv_min_interval);
     61		HDEV_PARAM_U16(le_adv_max_interval);
     62		HDEV_PARAM_U16(def_multi_adv_rotation_duration);
     63		HDEV_PARAM_U16(le_scan_interval);
     64		HDEV_PARAM_U16(le_scan_window);
     65		HDEV_PARAM_U16(le_scan_int_suspend);
     66		HDEV_PARAM_U16(le_scan_window_suspend);
     67		HDEV_PARAM_U16(le_scan_int_discovery);
     68		HDEV_PARAM_U16(le_scan_window_discovery);
     69		HDEV_PARAM_U16(le_scan_int_adv_monitor);
     70		HDEV_PARAM_U16(le_scan_window_adv_monitor);
     71		HDEV_PARAM_U16(le_scan_int_connect);
     72		HDEV_PARAM_U16(le_scan_window_connect);
     73		HDEV_PARAM_U16(le_conn_min_interval);
     74		HDEV_PARAM_U16(le_conn_max_interval);
     75		HDEV_PARAM_U16(le_conn_latency);
     76		HDEV_PARAM_U16(le_supv_timeout);
     77		HDEV_PARAM_U16(def_le_autoconnect_timeout);
     78		HDEV_PARAM_U16(advmon_allowlist_duration);
     79		HDEV_PARAM_U16(advmon_no_filter_duration);
     80		HDEV_PARAM_U8(enable_advmon_interleave_scan);
     81	} __packed rp = {
     82		TLV_SET_U16(0x0000, def_page_scan_type),
     83		TLV_SET_U16(0x0001, def_page_scan_int),
     84		TLV_SET_U16(0x0002, def_page_scan_window),
     85		TLV_SET_U16(0x0003, def_inq_scan_type),
     86		TLV_SET_U16(0x0004, def_inq_scan_int),
     87		TLV_SET_U16(0x0005, def_inq_scan_window),
     88		TLV_SET_U16(0x0006, def_br_lsto),
     89		TLV_SET_U16(0x0007, def_page_timeout),
     90		TLV_SET_U16(0x0008, sniff_min_interval),
     91		TLV_SET_U16(0x0009, sniff_max_interval),
     92		TLV_SET_U16(0x000a, le_adv_min_interval),
     93		TLV_SET_U16(0x000b, le_adv_max_interval),
     94		TLV_SET_U16(0x000c, def_multi_adv_rotation_duration),
     95		TLV_SET_U16(0x000d, le_scan_interval),
     96		TLV_SET_U16(0x000e, le_scan_window),
     97		TLV_SET_U16(0x000f, le_scan_int_suspend),
     98		TLV_SET_U16(0x0010, le_scan_window_suspend),
     99		TLV_SET_U16(0x0011, le_scan_int_discovery),
    100		TLV_SET_U16(0x0012, le_scan_window_discovery),
    101		TLV_SET_U16(0x0013, le_scan_int_adv_monitor),
    102		TLV_SET_U16(0x0014, le_scan_window_adv_monitor),
    103		TLV_SET_U16(0x0015, le_scan_int_connect),
    104		TLV_SET_U16(0x0016, le_scan_window_connect),
    105		TLV_SET_U16(0x0017, le_conn_min_interval),
    106		TLV_SET_U16(0x0018, le_conn_max_interval),
    107		TLV_SET_U16(0x0019, le_conn_latency),
    108		TLV_SET_U16(0x001a, le_supv_timeout),
    109		TLV_SET_U16_JIFFIES_TO_MSECS(0x001b,
    110					     def_le_autoconnect_timeout),
    111		TLV_SET_U16(0x001d, advmon_allowlist_duration),
    112		TLV_SET_U16(0x001e, advmon_no_filter_duration),
    113		TLV_SET_U8(0x001f, enable_advmon_interleave_scan),
    114	};
    115
    116	bt_dev_dbg(hdev, "sock %p", sk);
    117
    118	ret = mgmt_cmd_complete(sk, hdev->id,
    119				MGMT_OP_READ_DEF_SYSTEM_CONFIG,
    120				0, &rp, sizeof(rp));
    121	return ret;
    122}
    123
    124#define TO_TLV(x)		((struct mgmt_tlv *)(x))
    125#define TLV_GET_LE16(tlv)	le16_to_cpu(*((__le16 *)(TO_TLV(tlv)->value)))
    126#define TLV_GET_U8(tlv)		(*((__u8 *)(TO_TLV(tlv)->value)))
    127
    128int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
    129			  u16 data_len)
    130{
    131	u16 buffer_left = data_len;
    132	u8 *buffer = data;
    133
    134	if (buffer_left < sizeof(struct mgmt_tlv)) {
    135		return mgmt_cmd_status(sk, hdev->id,
    136				       MGMT_OP_SET_DEF_SYSTEM_CONFIG,
    137				       MGMT_STATUS_INVALID_PARAMS);
    138	}
    139
    140	/* First pass to validate the tlv */
    141	while (buffer_left >= sizeof(struct mgmt_tlv)) {
    142		const u8 len = TO_TLV(buffer)->length;
    143		size_t exp_type_len;
    144		const u16 exp_len = sizeof(struct mgmt_tlv) +
    145				    len;
    146		const u16 type = le16_to_cpu(TO_TLV(buffer)->type);
    147
    148		if (buffer_left < exp_len) {
    149			bt_dev_warn(hdev, "invalid len left %u, exp >= %u",
    150				    buffer_left, exp_len);
    151
    152			return mgmt_cmd_status(sk, hdev->id,
    153					MGMT_OP_SET_DEF_SYSTEM_CONFIG,
    154					MGMT_STATUS_INVALID_PARAMS);
    155		}
    156
    157		/* Please see mgmt-api.txt for documentation of these values */
    158		switch (type) {
    159		case 0x0000:
    160		case 0x0001:
    161		case 0x0002:
    162		case 0x0003:
    163		case 0x0004:
    164		case 0x0005:
    165		case 0x0006:
    166		case 0x0007:
    167		case 0x0008:
    168		case 0x0009:
    169		case 0x000a:
    170		case 0x000b:
    171		case 0x000c:
    172		case 0x000d:
    173		case 0x000e:
    174		case 0x000f:
    175		case 0x0010:
    176		case 0x0011:
    177		case 0x0012:
    178		case 0x0013:
    179		case 0x0014:
    180		case 0x0015:
    181		case 0x0016:
    182		case 0x0017:
    183		case 0x0018:
    184		case 0x0019:
    185		case 0x001a:
    186		case 0x001b:
    187		case 0x001d:
    188		case 0x001e:
    189			exp_type_len = sizeof(u16);
    190			break;
    191		case 0x001f:
    192			exp_type_len = sizeof(u8);
    193			break;
    194		default:
    195			exp_type_len = 0;
    196			bt_dev_warn(hdev, "unsupported parameter %u", type);
    197			break;
    198		}
    199
    200		if (exp_type_len && len != exp_type_len) {
    201			bt_dev_warn(hdev, "invalid length %d, exp %zu for type %u",
    202				    len, exp_type_len, type);
    203
    204			return mgmt_cmd_status(sk, hdev->id,
    205				MGMT_OP_SET_DEF_SYSTEM_CONFIG,
    206				MGMT_STATUS_INVALID_PARAMS);
    207		}
    208
    209		buffer_left -= exp_len;
    210		buffer += exp_len;
    211	}
    212
    213	buffer_left = data_len;
    214	buffer = data;
    215	while (buffer_left >= sizeof(struct mgmt_tlv)) {
    216		const u8 len = TO_TLV(buffer)->length;
    217		const u16 exp_len = sizeof(struct mgmt_tlv) +
    218				    len;
    219		const u16 type = le16_to_cpu(TO_TLV(buffer)->type);
    220
    221		switch (type) {
    222		case 0x0000:
    223			hdev->def_page_scan_type = TLV_GET_LE16(buffer);
    224			break;
    225		case 0x0001:
    226			hdev->def_page_scan_int = TLV_GET_LE16(buffer);
    227			break;
    228		case 0x0002:
    229			hdev->def_page_scan_window = TLV_GET_LE16(buffer);
    230			break;
    231		case 0x0003:
    232			hdev->def_inq_scan_type = TLV_GET_LE16(buffer);
    233			break;
    234		case 0x0004:
    235			hdev->def_inq_scan_int = TLV_GET_LE16(buffer);
    236			break;
    237		case 0x0005:
    238			hdev->def_inq_scan_window = TLV_GET_LE16(buffer);
    239			break;
    240		case 0x0006:
    241			hdev->def_br_lsto = TLV_GET_LE16(buffer);
    242			break;
    243		case 0x0007:
    244			hdev->def_page_timeout = TLV_GET_LE16(buffer);
    245			break;
    246		case 0x0008:
    247			hdev->sniff_min_interval = TLV_GET_LE16(buffer);
    248			break;
    249		case 0x0009:
    250			hdev->sniff_max_interval = TLV_GET_LE16(buffer);
    251			break;
    252		case 0x000a:
    253			hdev->le_adv_min_interval = TLV_GET_LE16(buffer);
    254			break;
    255		case 0x000b:
    256			hdev->le_adv_max_interval = TLV_GET_LE16(buffer);
    257			break;
    258		case 0x000c:
    259			hdev->def_multi_adv_rotation_duration =
    260							   TLV_GET_LE16(buffer);
    261			break;
    262		case 0x000d:
    263			hdev->le_scan_interval = TLV_GET_LE16(buffer);
    264			break;
    265		case 0x000e:
    266			hdev->le_scan_window = TLV_GET_LE16(buffer);
    267			break;
    268		case 0x000f:
    269			hdev->le_scan_int_suspend = TLV_GET_LE16(buffer);
    270			break;
    271		case 0x0010:
    272			hdev->le_scan_window_suspend = TLV_GET_LE16(buffer);
    273			break;
    274		case 0x0011:
    275			hdev->le_scan_int_discovery = TLV_GET_LE16(buffer);
    276			break;
    277		case 0x00012:
    278			hdev->le_scan_window_discovery = TLV_GET_LE16(buffer);
    279			break;
    280		case 0x00013:
    281			hdev->le_scan_int_adv_monitor = TLV_GET_LE16(buffer);
    282			break;
    283		case 0x00014:
    284			hdev->le_scan_window_adv_monitor = TLV_GET_LE16(buffer);
    285			break;
    286		case 0x00015:
    287			hdev->le_scan_int_connect = TLV_GET_LE16(buffer);
    288			break;
    289		case 0x00016:
    290			hdev->le_scan_window_connect = TLV_GET_LE16(buffer);
    291			break;
    292		case 0x00017:
    293			hdev->le_conn_min_interval = TLV_GET_LE16(buffer);
    294			break;
    295		case 0x00018:
    296			hdev->le_conn_max_interval = TLV_GET_LE16(buffer);
    297			break;
    298		case 0x00019:
    299			hdev->le_conn_latency = TLV_GET_LE16(buffer);
    300			break;
    301		case 0x0001a:
    302			hdev->le_supv_timeout = TLV_GET_LE16(buffer);
    303			break;
    304		case 0x0001b:
    305			hdev->def_le_autoconnect_timeout =
    306					msecs_to_jiffies(TLV_GET_LE16(buffer));
    307			break;
    308		case 0x0001d:
    309			hdev->advmon_allowlist_duration = TLV_GET_LE16(buffer);
    310			break;
    311		case 0x0001e:
    312			hdev->advmon_no_filter_duration = TLV_GET_LE16(buffer);
    313			break;
    314		case 0x0001f:
    315			hdev->enable_advmon_interleave_scan = TLV_GET_U8(buffer);
    316			break;
    317		default:
    318			bt_dev_warn(hdev, "unsupported parameter %u", type);
    319			break;
    320		}
    321
    322		buffer_left -= exp_len;
    323		buffer += exp_len;
    324	}
    325
    326	return mgmt_cmd_complete(sk, hdev->id,
    327				 MGMT_OP_SET_DEF_SYSTEM_CONFIG, 0, NULL, 0);
    328}
    329
    330int read_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
    331			    u16 data_len)
    332{
    333	bt_dev_dbg(hdev, "sock %p", sk);
    334
    335	return mgmt_cmd_complete(sk, hdev->id,
    336				 MGMT_OP_READ_DEF_RUNTIME_CONFIG, 0, NULL, 0);
    337}
    338
    339int set_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
    340			   u16 data_len)
    341{
    342	bt_dev_dbg(hdev, "sock %p", sk);
    343
    344	return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEF_SYSTEM_CONFIG,
    345			       MGMT_STATUS_INVALID_PARAMS);
    346}