Compare commits

...

24 Commits

Author SHA1 Message Date
Kumar Gala
fff583d699 ci: github: Update for deprecation of add-path
Github has deprecated add-path, so update the workflows that use it to
the new method of setting the PATH.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2021-03-27 08:58:22 -04:00
Eugeniy Paltsev
edf6be2986 linker-defs: Fix sorting order of objects by priority
Commit 0a7b65e tweaked the CREATE_OBJ_LEVEL macro in such a way
that it would break the expected sorting order.

For example if you had 2, 19, 20, 30 as the level, we'd end up sort
these to be 19, 2, 20, 30.

Fix this by adding aditional "_" symbol after the init level counter.
That allows to keep correct sort order (for both GNU and MWDT
toolchains) and distinguish init level counter from section suffix
(for MWDT toolchain).

Fixes zephyrproject-rtos#33464

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
2021-03-25 22:29:09 -04:00
Tomasz Bursztyka
af4148c8c8 net/ieee802154: Drop fragmented packet if first frag is not present
Bogus fragmented packet could be sent without a FRAG1 fragment and hit
reassembly. Let's make sure this does not happen.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Tomasz Bursztyka
b35d6d4f4d net/ieee802154: Do not unreference one time too many a fragmented packet
In case the current packet is the same as the cached one, let's not
unreference it while clearing the cache.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Tomasz Bursztyka
d14ba3c1b0 net/ieee802154: Make sure L2 drop any ACK frames
Though ACK frames are not meant to reach L2 (drivers must ensure this
never happens), let's "re-enforce" the L2 by dropping them.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Tomasz Bursztyka
fab3f949b5 net/ieee802154: Avoid NULL pointer de-reference in packet reassembly
In case the very first fragment holds all the data already.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Tomasz Bursztyka
f911248d92 net/ieee802154: Each fragment should be at least of its header's length
Not validating this length could lead to integer underflow and memory
corruption.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Tomasz Bursztyka
029b8a597c net/ieee802154: Invalidate frame in case of no address in relevant modes
All addressing mode but IEEE802154_ADDR_MODE_NONE should have a valid
address. If not, the frame is invalid.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-03-23 13:52:27 -04:00
Flavio Ceolin
2e30f2abea mempool: Fix possible overflow
Fix possible overflow when allocating memory resulting in less memory
allocated what can cause further invalid memory access.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2021-03-23 13:52:05 -04:00
Luiz Augusto von Dentz
cf3b638fcb Bluetooth: L2CAP: Fix not including all DCIDs
The order of Destination CIDs shall correspond the order of Source CIDs
including its amount so errors that don't result in all connection being
refused shall not break the order of CIDs.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2021-03-23 13:51:28 -04:00
Luiz Augusto von Dentz
de142e438d Bluetooth: L2CAP: Fix invalid BT_L2CAP_ECRED_CONN_RSP
For errors that means all connections have been refused there is no need
to add dcids since none will be valid.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2021-03-23 13:51:28 -04:00
Luiz Augusto von Dentz
0a14470645 Bluetooth: L2CAP: Fix not checking for L2CAP_ECRED_CHAN_MAX
When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request
more channels than allowed so this checks if amount of channel surpasses
the maximum channels (5) and return an error.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2021-03-23 13:51:28 -04:00
Joakim Andersson
da887af568 Bluetooth: host: Overwrite existing bond when IRK has been updated
Overwrite the existing bond when the IRK of the existing bond could not
resolve the RPA of the peer. This would happen if the peer has deleted
the bond and replaced the IRK that was used.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-03-23 13:50:48 -04:00
Joakim Andersson
705ff30071 Bluetooth: host: Refactor update_keys_check to operate on keys as input
Refactor update_keys_check helper function to operate on input keys
input. This allows the function to be re-used on a keys structure that
is not the current connection keys.

This also avoids the helper function changing the connection state.
The conn->le.keys pointer should at this point always have been
assigned, as central when sending the pairing request, and as peripheral
when receiving the pairing request at the very latest.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-03-23 13:50:48 -04:00
Johan Hedberg
3a06d3d523 Bluetooth: L2CAP: Fix missing buffer length check for sdu_len
We should verify that the buffer has sufficient data before attempting
to parse the SDU length field. If we get a too short packet just
disconnect the channel.

Fixes #32497

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2021-03-23 13:49:09 -04:00
Christoph Reiter
3c1fb27e9c drivers: sensor: dps310 fix out of bounds write
Fixes a copy-paste error which results in an out of bounds write on the
stack.

Signed-off-by: Christoph Reiter <christoph.reiter@infineon.com>
2021-02-14 22:10:04 -05:00
Joakim Andersson
9c30e79469 Bluetooth: L2CAP: Enable L2CAP dynamic channels without Enhanced CBFC
Allow application to enable L2CAP dynamic channels without support
for Enhanced Credit Based Flow Control (CBFC).

Since these are separate features in the qualification it should
be possible to qualify L2CAP connection oriented channels without
also having to qualify L2CAP enhanced credit based flow control.

The L2CAP/LE/REJ/BI-02-C conformance test will fail when enhanced CBFC
has not been selected in the ICS.

The lower tester expects that since the Enhanced CBFC is not supported,
the command L2CAP_CREDIT_BASED_CONNECTION_REQ should be met with an
L2CAP_COMMAND_REJECT_RSP and not an L2CAP_CREDIT_BASED_CONNECTION_RSP.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-01-10 15:41:29 -05:00
Thomas Ebert Hansen
463bf8eadc Bluetooth: controller: Fix CUI/CPR lock during TO
Release the CUI/CPR lock if the connection owning the lock is
terminated.

This can happen if a device performing a CUI/CPR procedure gets a LSTO
before the procedeure completes or the procedure itself TO.

Signed-off-by: Thomas Ebert Hansen <thoh@oticon.com>
2021-01-10 15:41:11 -05:00
Vinayak Kariappa Chettimada
951786950c Bluetooth: controller: Release blocking LF clock request
Release the LF clock requested in blocking mode used to wait
to settle, which has already been asynchronously requested.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-01-10 15:40:58 -05:00
Vinayak Kariappa Chettimada
75ebb69b1e Bluetooth: controller: nRF5x: Fix lll LF clock wait
Fix lll_clock_wait function to wait for LF clock to settle
only once after power up.

Regression introduced in commit 2b4763076e ("bluetooth:
controller: Adapt to onoff clock control").

Fixes #30480.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-01-10 15:40:58 -05:00
Trond Einar Snekvik
a40d31b153 [backport v2.4] Bluetooth: Mesh: Move RPL clear to bt_mesh_reset
Moves the clearing of RPL out of the bt_mesh_rx_reset() to avoid it
being called outside of the node reset procedure.

Fixes #29858 for v2.4.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
2021-01-10 15:33:57 -05:00
Joakim Andersson
c2a0b0f50b Bluetooth: GATT: Fix regression in lazy loading of CCCs
Fix regression in lazy loading handling of GATT CCCs.
Bug introduced by: 00d370b09a
The commit failed to account for ccc_set_direct calling ccc_set.

Fixes: #29150

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2020-11-17 16:47:02 -05:00
Joakim Andersson
60c27beb03 Bluetooth: ATT: Handle encrypt change event unrelated to current req
Fix issue where the encrypt change has an error code, but the
encrypt change request was unrelated to the current ATT request.

This lead to the current ATT transaction being interpreted as finished
an the ATT client would proceed with the next ATT request, which would
fail since the ATT client is now violating the ATT single transaction
rule.

Updated similar if statement checking for the opposite to improve
readability.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2020-11-17 16:46:47 -05:00
Vinayak Kariappa Chettimada
e8f0ec6e73 Bluetooth: controller: Fix regression in central event close
Fix regression in connection radio event close in central
role introduced in commit 222dca5598

Fixes #29957.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2020-11-17 16:46:15 -05:00
23 changed files with 193 additions and 88 deletions

View File

@@ -12,7 +12,7 @@ jobs:
steps:
- name: Update PATH for west
run: |
echo "::add-path::$HOME/.local/bin"
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: checkout
uses: actions/checkout@v2

View File

@@ -18,7 +18,7 @@ jobs:
steps:
- name: Update PATH for west
run: |
echo "::add-path::$HOME/.local/bin"
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Determine tag
id: tag

View File

@@ -625,7 +625,7 @@ static int dps310_init(const struct device *dev)
uint8_t tmp_coef_srce = 0;
res = i2c_write_read(data->i2c_master, config->i2c_addr,
&REG_ADDR_COEF_SRCE, 1, &tmp_coef_srce, 18);
&REG_ADDR_COEF_SRCE, 1, &tmp_coef_srce, sizeof(tmp_coef_srce));
if (res < 0) {
LOG_WRN("I2C error: %d", res);
return -EIO;

View File

@@ -128,7 +128,7 @@ extern "C" {
Z_DEVICE_DEFINE_PM(dev_name) \
static const Z_DECL_ALIGN(struct device) \
DEVICE_NAME_GET(dev_name) __used \
__attribute__((__section__(".device_" #level STRINGIFY(prio)))) = { \
__attribute__((__section__(".device_" #level STRINGIFY(prio)"_"))) = { \
.name = drv_name, \
.config = (cfg_ptr), \
.api = (api_ptr), \

View File

@@ -85,7 +85,7 @@ void z_sys_init_run_level(int32_t _level);
#define Z_INIT_ENTRY_DEFINE(_entry_name, _init_fn, _device, _level, _prio) \
static const Z_DECL_ALIGN(struct init_entry) \
_CONCAT(__init_, _entry_name) __used \
__attribute__((__section__(".init_" #_level STRINGIFY(_prio)))) = { \
__attribute__((__section__(".init_" #_level STRINGIFY(_prio)"_"))) = { \
.init = (_init_fn), \
.dev = (_device), \
}

View File

@@ -116,8 +116,8 @@
*/
#define CREATE_OBJ_LEVEL(object, level) \
__##object##_##level##_start = .; \
KEEP(*(SORT(.object##_##level[0-9]*))); \
KEEP(*(SORT(.object##_##level[1-9][0-9]*)));
KEEP(*(SORT(.object##_##level[0-9]_*))); \
KEEP(*(SORT(.object##_##level[1-9][0-9]_*)));
/*
* link in shell initialization objects for all modules that use shell and

View File

@@ -10,6 +10,7 @@
#include <sys/mempool_base.h>
#include <sys/mempool.h>
#include <sys/check.h>
#include <sys/math_extras.h>
#ifdef CONFIG_MISRA_SANE
#define LVL_ARRAY_SZ(n) (8 * sizeof(void *) / 2)
@@ -336,7 +337,12 @@ void *sys_mem_pool_alloc(struct sys_mem_pool *p, size_t size)
return NULL;
}
size += WB_UP(sizeof(struct sys_mem_pool_block));
if (size_add_overflow(size, WB_UP(sizeof(struct sys_mem_pool_block)),
&size)) {
ret = NULL;
goto out;
}
if (z_sys_mem_pool_block_alloc(&p->base, size, &level, &block,
(void **)&ret)) {
ret = NULL;

View File

@@ -64,10 +64,27 @@ int lll_clock_init(void)
int lll_clock_wait(void)
{
struct onoff_manager *mgr =
z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);
struct onoff_manager *mgr;
static bool done;
int err;
return blocking_on(mgr, LFCLOCK_TIMEOUT_MS);
if (done) {
return 0;
}
done = true;
mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF);
err = blocking_on(mgr, LFCLOCK_TIMEOUT_MS);
if (err) {
return err;
}
err = onoff_release(mgr);
if (err != ONOFF_STATE_ON) {
return -EIO;
}
return 0;
}
int lll_hfclock_on(void)

View File

@@ -650,7 +650,8 @@ static inline int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
lll->empty = 0;
pdu_data_tx = (void *)radio_pkt_empty_get();
if (IS_ENABLED(CONFIG_BT_CENTRAL) && !lll->role) {
if (IS_ENABLED(CONFIG_BT_CENTRAL) && !lll->role &&
!pdu_data_rx->md) {
*is_done = !pdu_data_tx->md;
}
@@ -693,7 +694,8 @@ static inline int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
*tx_release = tx;
}
if (IS_ENABLED(CONFIG_BT_CENTRAL) && !lll->role) {
if (IS_ENABLED(CONFIG_BT_CENTRAL) && !lll->role &&
!pdu_data_rx->md) {
*is_done = !pdu_data_tx->md;
}
}

View File

@@ -1690,6 +1690,11 @@ static void conn_cleanup(struct ll_conn *conn, uint8_t reason)
struct node_rx_pdu *rx;
uint32_t ticker_status;
/* reset mutex */
if (conn == conn_upd_curr) {
ull_conn_upd_curr_reset();
}
/* Only termination structure is populated here in ULL context
* but the actual enqueue happens in the LLL context in
* tx_lll_flush. The reason being to avoid passing the reason

View File

@@ -36,7 +36,7 @@ config BT_ATT_TX_MAX
config BT_EATT
bool "Enhanced ATT Bearers support [EXPERIMENTAL]"
depends on BT_L2CAP_DYNAMIC_CHANNEL
depends on BT_L2CAP_ECRED
help
This option enables support for Enhanced ATT bearers support. When
enabled additional L2CAP channels can be connected as bearers enabling

View File

@@ -56,6 +56,13 @@ config BT_L2CAP_DYNAMIC_CHANNEL
This option enables support for LE Connection oriented Channels,
allowing the creation of dynamic L2CAP Channels.
config BT_L2CAP_ECRED
bool "L2CAP Enhanced Credit Based Flow Control support"
depends on BT_L2CAP_DYNAMIC_CHANNEL
help
This option enables support for LE Connection oriented Channels with
Enhanced Credit Based Flow Control support on dynamic L2CAP Channels.
config BT_DEBUG_L2CAP
bool "Bluetooth L2CAP debug"
depends on BT_DEBUG

View File

@@ -2699,7 +2699,7 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,
* outstanding request about security failure.
*/
if (hci_status) {
if (att_chan->req) {
if (att_chan->req && att_chan->req->retrying) {
att_handle_rsp(att_chan, NULL, 0,
BT_ATT_ERR_AUTHENTICATION);
}
@@ -2713,7 +2713,7 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,
return;
}
if (!att_chan->req || !att_chan->req->retrying) {
if (!(att_chan->req && att_chan->req->retrying)) {
return;
}

View File

@@ -29,6 +29,7 @@ config BT_AUDIO_UNICAST
select BT_ISO
select BT_GATT_DYNAMIC_DB
select BT_GATT_CACHING
select BT_L2CAP_ECRED
select BT_EATT
help
This option enables support for Bluetooth Unicast Audio using

View File

@@ -4339,11 +4339,6 @@ next:
static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
void *cb_arg)
{
if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)) {
/* Only load CCCs on demand */
return 0;
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
struct ccc_store ccc_store[CCC_STORE_MAX];
struct ccc_load load;
@@ -4401,7 +4396,18 @@ static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
return 0;
}
SETTINGS_STATIC_HANDLER_DEFINE(bt_ccc, "bt/ccc", NULL, ccc_set, NULL, NULL);
static int ccc_set_cb(const char *name, size_t len_rd, settings_read_cb read_cb,
void *cb_arg)
{
if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)) {
/* Only load CCCs on demand */
return 0;
}
return ccc_set(name, len_rd, read_cb, cb_arg);
}
SETTINGS_STATIC_HANDLER_DEFINE(bt_ccc, "bt/ccc", NULL, ccc_set_cb, NULL, NULL);
static int ccc_set_direct(const char *key, size_t len, settings_read_cb read_cb,
void *cb_arg, void *param)

View File

@@ -466,6 +466,7 @@ static int l2cap_le_conn_req(struct bt_l2cap_le_chan *ch)
return 0;
}
#if defined(CONFIG_BT_L2CAP_ECRED)
static int l2cap_ecred_conn_req(struct bt_l2cap_chan **chan, int channels)
{
struct net_buf *buf;
@@ -506,6 +507,7 @@ static int l2cap_ecred_conn_req(struct bt_l2cap_chan **chan, int channels)
return 0;
}
#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
static void l2cap_le_encrypt_change(struct bt_l2cap_chan *chan, uint8_t status)
{
@@ -521,6 +523,7 @@ static void l2cap_le_encrypt_change(struct bt_l2cap_chan *chan, uint8_t status)
goto fail;
}
#if defined(CONFIG_BT_L2CAP_ECRED)
if (chan->ident) {
struct bt_l2cap_chan *echan[L2CAP_ECRED_CHAN_MAX];
struct bt_l2cap_le_chan *ch;
@@ -534,6 +537,7 @@ static void l2cap_le_encrypt_change(struct bt_l2cap_chan *chan, uint8_t status)
l2cap_ecred_conn_req(echan, i);
return;
}
#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
/* Retry to connect */
err = l2cap_le_conn_req(BT_L2CAP_LE_CHAN(chan));
@@ -1078,6 +1082,7 @@ rsp:
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
}
#if defined(CONFIG_BT_L2CAP_ECRED)
static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
struct net_buf *buf)
{
@@ -1098,6 +1103,13 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
}
req = net_buf_pull_mem(buf, sizeof(*req));
if (buf->len > sizeof(dcid)) {
BT_ERR("Too large LE conn req packet size");
result = BT_L2CAP_LE_ERR_INVALID_PARAMS;
goto response;
}
psm = sys_le16_to_cpu(req->psm);
mtu = sys_le16_to_cpu(req->mtu);
mps = sys_le16_to_cpu(req->mps);
@@ -1124,6 +1136,8 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
goto response;
}
memset(dcid, 0, sizeof(dcid));
while (buf->len >= sizeof(scid)) {
scid = net_buf_pull_le16(buf);
@@ -1135,28 +1149,20 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
dcid[i++] = sys_cpu_to_le16(ch->rx.cid);
continue;
/* Some connections refused invalid Source CID */
case BT_L2CAP_LE_ERR_INVALID_SCID:
/* Some connections refused Source CID already allocated */
case BT_L2CAP_LE_ERR_SCID_IN_USE:
/* Some connections refused not enough resources
* available.
*/
default:
/* If a Destination CID is 0x0000, the channel was not
* established.
*/
dcid[i++] = 0x0000;
continue;
/* Some connections refused not enough resources
* available.
*/
case BT_L2CAP_LE_ERR_NO_RESOURCES:
default:
goto response;
}
}
response:
if (!i) {
i = buf->len / sizeof(scid);
}
buf = l2cap_create_le_sig_pdu(buf, BT_L2CAP_ECRED_CONN_RSP, ident,
sizeof(*rsp) + (sizeof(scid) * i));
@@ -1254,6 +1260,7 @@ response:
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
}
#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
static struct bt_l2cap_le_chan *l2cap_remove_rx_cid(struct bt_conn *conn,
uint16_t cid)
@@ -1367,6 +1374,7 @@ static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err)
return 0;
}
#if defined(CONFIG_BT_L2CAP_ECRED)
static void le_ecred_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
struct net_buf *buf)
{
@@ -1473,6 +1481,7 @@ static void le_ecred_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
break;
}
}
#endif /* CONFIG_BT_L2CAP_ECRED */
static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
struct net_buf *buf)
@@ -1920,6 +1929,7 @@ static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
case BT_L2CAP_CMD_REJECT:
reject_cmd(l2cap, hdr->ident, buf);
break;
#if defined(CONFIG_BT_L2CAP_ECRED)
case BT_L2CAP_ECRED_CONN_REQ:
le_ecred_conn_req(l2cap, hdr->ident, buf);
break;
@@ -1929,6 +1939,7 @@ static int l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
case BT_L2CAP_ECRED_RECONF_REQ:
le_ecred_reconf_req(l2cap, hdr->ident, buf);
break;
#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
#else
case BT_L2CAP_CMD_REJECT:
/* Ignored */
@@ -2175,6 +2186,12 @@ static void l2cap_chan_le_recv(struct bt_l2cap_le_chan *chan,
return;
}
if (buf->len < 2) {
BT_WARN("Too short data packet");
bt_l2cap_chan_disconnect(&chan->chan);
return;
}
sdu_len = net_buf_pull_le16(buf);
BT_DBG("chan %p len %u sdu_len %u", chan, buf->len, sdu_len);
@@ -2403,6 +2420,7 @@ fail:
return err;
}
#if defined(CONFIG_BT_L2CAP_ECRED)
static int l2cap_ecred_init(struct bt_conn *conn,
struct bt_l2cap_le_chan *ch, uint16_t psm)
{
@@ -2463,6 +2481,7 @@ fail:
return err;
}
#endif /* defined(CONFIG_BT_L2CAP_ECRED) */
int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
uint16_t psm)

View File

@@ -737,14 +737,8 @@ static uint8_t get_encryption_key_size(struct bt_smp *smp)
/* Check that if a new pairing procedure with an existing bond will not lower
* the established security level of the bond.
*/
static bool update_keys_check(struct bt_smp *smp)
static bool update_keys_check(struct bt_smp *smp, struct bt_keys *keys)
{
struct bt_conn *conn = smp->chan.chan.conn;
if (!conn->le.keys) {
conn->le.keys = bt_keys_get_addr(conn->id, &conn->le.dst);
}
if (IS_ENABLED(CONFIG_BT_SMP_DISABLE_LEGACY_JW_PASSKEY) &&
!atomic_test_bit(smp->flags, SMP_FLAG_SC) &&
smp->method != LEGACY_OOB) {
@@ -756,27 +750,27 @@ static bool update_keys_check(struct bt_smp *smp)
return false;
}
if (!conn->le.keys ||
!(conn->le.keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK))) {
if (!keys ||
!(keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK))) {
return true;
}
if (conn->le.keys->enc_size > get_encryption_key_size(smp)) {
if (keys->enc_size > get_encryption_key_size(smp)) {
return false;
}
if ((conn->le.keys->keys & BT_KEYS_LTK_P256) &&
if ((keys->keys & BT_KEYS_LTK_P256) &&
!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
return false;
}
if ((conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
if ((keys->flags & BT_KEYS_AUTHENTICATED) &&
smp->method == JUST_WORKS) {
return false;
}
if (!IS_ENABLED(CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE) &&
(!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED)
(!(keys->flags & BT_KEYS_AUTHENTICATED)
&& smp->method == JUST_WORKS)) {
return false;
}
@@ -2938,7 +2932,7 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
smp->method = get_pair_method(smp, req->io_capability);
if (!update_keys_check(smp)) {
if (!update_keys_check(smp, conn->le.keys)) {
return BT_SMP_ERR_AUTH_REQUIREMENTS;
}
@@ -3139,7 +3133,7 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
smp->method = get_pair_method(smp, rsp->io_capability);
if (!update_keys_check(smp)) {
if (!update_keys_check(smp, conn->le.keys)) {
return BT_SMP_ERR_AUTH_REQUIREMENTS;
}
@@ -3737,6 +3731,18 @@ static uint8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf)
return BT_SMP_ERR_INVALID_PARAMS;
}
if (bt_addr_le_cmp(&conn->le.dst, &req->addr) != 0) {
struct bt_keys *keys = bt_keys_find_addr(conn->id, &req->addr);
if (keys) {
if (!update_keys_check(smp, keys)) {
return BT_SMP_ERR_UNSPECIFIED;
}
bt_keys_clear(keys);
}
}
if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) {
const bt_addr_le_t *dst;
struct bt_keys *keys;

View File

@@ -178,6 +178,12 @@ void bt_mesh_reset(void)
bt_mesh_rx_reset();
bt_mesh_tx_reset();
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_rpl();
} else {
(void)memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
}
bt_mesh_net_loopback_clear(BT_MESH_KEY_ANY);
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {

View File

@@ -1821,12 +1821,6 @@ void bt_mesh_rx_reset(void)
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
seg_rx_reset(&seg_rx[i], true);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_rpl();
} else {
(void)memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
}
}
void bt_mesh_tx_reset(void)

View File

@@ -189,6 +189,10 @@ static enum net_verdict ieee802154_recv(struct net_if *iface,
return NET_DROP;
}
if (mpdu.mhr.fs->fc.frame_type == IEEE802154_FRAME_TYPE_ACK) {
return NET_DROP;
}
if (mpdu.mhr.fs->fc.frame_type == IEEE802154_FRAME_TYPE_BEACON) {
return ieee802154_handle_beacon(iface, &mpdu,
net_pkt_ieee802154_lqi(pkt));

View File

@@ -215,6 +215,11 @@ void ieee802154_fragment(struct ieee802154_fragment_ctx *ctx,
ctx->offset = ctx->processed >> 3;
}
static inline uint8_t get_datagram_type(uint8_t *ptr)
{
return ptr[0] & NET_FRAG_DISPATCH_MASK;
}
static inline uint16_t get_datagram_size(uint8_t *ptr)
{
return ((ptr[0] & 0x1F) << 8) | ptr[1];
@@ -344,8 +349,7 @@ static inline struct frag_cache *get_reass_cache(uint16_t size, uint16_t tag)
static inline void fragment_append(struct net_pkt *pkt, struct net_buf *frag)
{
if ((frag->data[0] & NET_FRAG_DISPATCH_MASK) ==
NET_6LO_DISPATCH_FRAG1) {
if (get_datagram_type(frag->data) == NET_6LO_DISPATCH_FRAG1) {
/* Always make sure first fragment is inserted first
* This will be useful for fragment_cached_pkt_len()
*/
@@ -367,8 +371,7 @@ static inline size_t fragment_cached_pkt_len(struct net_pkt *pkt)
while (frag) {
uint16_t hdr_len = NET_6LO_FRAGN_HDR_LEN;
if ((frag->data[0] & NET_FRAG_DISPATCH_MASK) ==
NET_6LO_DISPATCH_FRAG1) {
if (get_datagram_type(frag->data) == NET_6LO_DISPATCH_FRAG1) {
hdr_len = NET_6LO_FRAG1_HDR_LEN;
}
@@ -396,8 +399,7 @@ static inline size_t fragment_cached_pkt_len(struct net_pkt *pkt)
static inline uint16_t fragment_offset(struct net_buf *frag)
{
if ((frag->data[0] & NET_FRAG_DISPATCH_MASK) ==
NET_6LO_DISPATCH_FRAG1) {
if (get_datagram_type(frag->data) == NET_6LO_DISPATCH_FRAG1) {
return 0;
}
@@ -435,8 +437,7 @@ static inline void fragment_remove_headers(struct net_pkt *pkt)
while (frag) {
uint16_t hdr_len = NET_6LO_FRAGN_HDR_LEN;
if ((frag->data[0] & NET_FRAG_DISPATCH_MASK) ==
NET_6LO_DISPATCH_FRAG1) {
if (get_datagram_type(frag->data) == NET_6LO_DISPATCH_FRAG1) {
hdr_len = NET_6LO_FRAG1_HDR_LEN;
}
@@ -471,6 +472,11 @@ static inline void fragment_reconstruct_packet(struct net_pkt *pkt)
fragment_remove_headers(pkt);
}
static inline bool fragment_packet_valid(struct net_pkt *pkt)
{
return (get_datagram_type(pkt->buffer->data) == NET_6LO_DISPATCH_FRAG1);
}
/**
* Parse size and tag from the fragment, check if we have any cache
* related to it. If not create a new cache.
@@ -486,18 +492,28 @@ static inline enum net_verdict fragment_add_to_cache(struct net_pkt *pkt)
struct net_buf *frag;
uint16_t size;
uint16_t tag;
uint8_t type;
frag = pkt->buffer;
type = get_datagram_type(frag->data);
if ((type == NET_6LO_DISPATCH_FRAG1 &&
frag->len < NET_6LO_FRAG1_HDR_LEN) ||
(type == NET_6LO_DISPATCH_FRAGN &&
frag->len < NET_6LO_FRAGN_HDR_LEN)) {
return NET_DROP;
}
/* Parse total size of packet */
size = get_datagram_size(pkt->buffer->data);
size = get_datagram_size(frag->data);
/* Parse the datagram tag */
tag = get_datagram_tag(pkt->buffer->data +
tag = get_datagram_tag(frag->data +
NET_6LO_FRAG_DATAGRAM_SIZE_LEN);
/* If there are no fragments in the cache means this frag
* is the first one. So cache Rx pkt otherwise not.
*/
frag = pkt->buffer;
pkt->buffer = NULL;
cache = get_reass_cache(size, tag);
@@ -515,15 +531,26 @@ static inline enum net_verdict fragment_add_to_cache(struct net_pkt *pkt)
fragment_append(cache->pkt, frag);
if (fragment_cached_pkt_len(cache->pkt) == cache->size) {
/* Assign buffer back to input packet. */
pkt->buffer = cache->pkt->buffer;
cache->pkt->buffer = NULL;
if (!first_frag) {
/* Assign buffer back to input packet. */
pkt->buffer = cache->pkt->buffer;
cache->pkt->buffer = NULL;
} else {
/* in case pkt == cache->pkt, we don't want
* to unref it while clearing the cach.
*/
cache->pkt = NULL;
}
clear_reass_cache(size, tag);
if (!fragment_packet_valid(pkt)) {
NET_ERR("Invalid fragmented packet");
return NET_DROP;
}
fragment_reconstruct_packet(pkt);
/* Once reassemble is done, cache is no longer needed. */
clear_reass_cache(size, tag);
if (!net_6lo_uncompress(pkt)) {
NET_ERR("Could not uncompress. Bogus packet?");
return NET_DROP;
@@ -556,8 +583,7 @@ enum net_verdict ieee802154_reassemble(struct net_pkt *pkt)
return NET_DROP;
}
if ((pkt->buffer->data[0] & NET_FRAG_DISPATCH_MASK) >=
NET_6LO_DISPATCH_FRAG1) {
if (get_datagram_type(pkt->buffer->data) >= NET_6LO_DISPATCH_FRAG1) {
return fragment_add_to_cache(pkt);
} else {
NET_DBG("No frag dispatch (%02x)", pkt->buffer->data[0]);

View File

@@ -89,10 +89,10 @@ struct ieee802154_fcf_seq *ieee802154_validate_fc_seq(uint8_t *buf, uint8_t **p_
return fs;
}
static inline struct ieee802154_address_field *
validate_addr(uint8_t *buf, uint8_t **p_buf, uint8_t *length,
enum ieee802154_addressing_mode mode,
bool pan_id_compression)
static inline bool validate_addr(uint8_t *buf, uint8_t **p_buf, uint8_t *length,
enum ieee802154_addressing_mode mode,
bool pan_id_compression,
struct ieee802154_address_field **addr)
{
uint8_t len = 0;
@@ -102,7 +102,8 @@ validate_addr(uint8_t *buf, uint8_t **p_buf, uint8_t *length,
buf, mode, pan_id_compression);
if (mode == IEEE802154_ADDR_MODE_NONE) {
return NULL;
*addr = NULL;
return true;
}
if (!pan_id_compression) {
@@ -117,13 +118,15 @@ validate_addr(uint8_t *buf, uint8_t **p_buf, uint8_t *length,
}
if (len > *length) {
return NULL;
return false;
}
*p_buf += len;
*length -= len;
return (struct ieee802154_address_field *)buf;
*addr = (struct ieee802154_address_field *)buf;
return true;
}
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
@@ -439,13 +442,15 @@ bool ieee802154_validate_frame(uint8_t *buf, uint8_t length,
return false;
}
mpdu->mhr.dst_addr = validate_addr(p_buf, &p_buf, &length,
mpdu->mhr.fs->fc.dst_addr_mode,
false);
mpdu->mhr.src_addr = validate_addr(p_buf, &p_buf, &length,
mpdu->mhr.fs->fc.src_addr_mode,
(mpdu->mhr.fs->fc.pan_id_comp));
if (!validate_addr(p_buf, &p_buf, &length,
mpdu->mhr.fs->fc.dst_addr_mode,
false, &mpdu->mhr.dst_addr) ||
!validate_addr(p_buf, &p_buf, &length,
mpdu->mhr.fs->fc.src_addr_mode,
(mpdu->mhr.fs->fc.pan_id_comp),
&mpdu->mhr.src_addr)) {
return false;
}
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
if (mpdu->mhr.fs->fc.security_enabled) {

View File

@@ -21,6 +21,7 @@ CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_L2CAP_TX_BUF_COUNT=4
CONFIG_BT_ID_MAX=2
CONFIG_BT_EATT=y
CONFIG_BT_L2CAP_ECRED=y
CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_HRS=y
CONFIG_BT_WHITELIST=y