Skip to content

Commit

Permalink
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2016-04-12

Here's a set of Bluetooth & 802.15.4 patches intended for the 4.7 kernel:

 - Fix for race condition in vhci driver
 - Memory leak fix for ieee802154/adf7242 driver
 - Improvements to deal with single-mode (LE-only) Bluetooth controllers
 - Fix for allowing the BT_SECURITY_FIPS security level
 - New BCM2E71 ACPI ID
 - NULL pointer dereference fix fox hci_ldisc driver

Let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 12, 2016
2 parents 9a6f2b0 + 8805eea commit 69fb781
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 39 deletions.
1 change: 1 addition & 0 deletions drivers/bluetooth/hci_bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ static const struct acpi_device_id bcm_acpi_match[] = {
{ "BCM2E64", 0 },
{ "BCM2E65", 0 },
{ "BCM2E67", 0 },
{ "BCM2E71", 0 },
{ "BCM2E7B", 0 },
{ "BCM2E7C", 0 },
{ },
Expand Down
57 changes: 31 additions & 26 deletions drivers/bluetooth/hci_bcsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,12 @@ static const u16 crc_table[] = {
/* Initialise the crc calculator */
#define BCSP_CRC_INIT(x) x = 0xffff

/*
Update crc with next data byte
Implementation note
The data byte is treated as two nibbles. The crc is generated
in reverse, i.e., bits are fed into the register from the top.
*/
/* Update crc with next data byte
*
* Implementation note
* The data byte is treated as two nibbles. The crc is generated
* in reverse, i.e., bits are fed into the register from the top.
*/
static void bcsp_crc_update(u16 *crc, u8 d)
{
u16 reg = *crc;
Expand Down Expand Up @@ -223,9 +222,10 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
}

/* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
(because bytes 0xc0 and 0xdb are escaped, worst case is
when the packet is all made of 0xc0 and 0xdb :) )
+ 2 (0xc0 delimiters at start and end). */
* (because bytes 0xc0 and 0xdb are escaped, worst case is
* when the packet is all made of 0xc0 and 0xdb :) )
* + 2 (0xc0 delimiters at start and end).
*/

nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
if (!nskb)
Expand Down Expand Up @@ -285,7 +285,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
struct bcsp_struct *bcsp = hu->priv;
unsigned long flags;
struct sk_buff *skb;

/* First of all, check for unreliable messages in the queue,
since they have priority */

Expand All @@ -305,8 +305,9 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
}

/* Now, try to send a reliable pkt. We can only send a
reliable packet if the number of packets sent but not yet ack'ed
is < than the winsize */
* reliable packet if the number of packets sent but not yet ack'ed
* is < than the winsize
*/

spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);

Expand All @@ -332,12 +333,14 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
spin_unlock_irqrestore(&bcsp->unack.lock, flags);

/* We could not send a reliable packet, either because there are
none or because there are too many unack'ed pkts. Did we receive
any packets we have not acknowledged yet ? */
* none or because there are too many unack'ed pkts. Did we receive
* any packets we have not acknowledged yet ?
*/

if (bcsp->txack_req) {
/* if so, craft an empty ACK pkt and send it on BCSP unreliable
channel 0 */
* channel 0
*/
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
return nskb;
}
Expand Down Expand Up @@ -399,8 +402,9 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
}

/* Handle BCSP link-establishment packets. When we
detect a "sync" packet, symptom that the BT module has reset,
we do nothing :) (yet) */
* detect a "sync" packet, symptom that the BT module has reset,
* we do nothing :) (yet)
*/
static void bcsp_handle_le_pkt(struct hci_uart *hu)
{
struct bcsp_struct *bcsp = hu->priv;
Expand Down Expand Up @@ -462,7 +466,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
case 0xdd:
memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
bcsp->rx_state != BCSP_W4_CRC)
bcsp->rx_state != BCSP_W4_CRC)
bcsp_crc_update(&bcsp->message_crc, 0xdb);
bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
bcsp->rx_count--;
Expand Down Expand Up @@ -534,7 +538,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
} else {
BT_ERR("Packet for unknown channel (%u %s)",
bcsp->rx_skb->data[1] & 0x0f,
bcsp->rx_skb->data[0] & 0x80 ?
bcsp->rx_skb->data[0] & 0x80 ?
"reliable" : "unreliable");
kfree_skb(bcsp->rx_skb);
}
Expand Down Expand Up @@ -562,7 +566,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
struct bcsp_struct *bcsp = hu->priv;
const unsigned char *ptr;

BT_DBG("hu %p count %d rx_state %d rx_count %ld",
BT_DBG("hu %p count %d rx_state %d rx_count %ld",
hu, count, bcsp->rx_state, bcsp->rx_count);

ptr = data;
Expand Down Expand Up @@ -591,7 +595,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
continue;
}
if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
&& (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
&& (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
BT_ERR("Out-of-order packet arrived, got %u expected %u",
bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);

Expand All @@ -601,7 +605,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
continue;
}
bcsp->rx_state = BCSP_W4_DATA;
bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
(bcsp->rx_skb->data[2] << 4); /* May be 0 */
continue;

Expand All @@ -615,7 +619,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)

case BCSP_W4_CRC:
if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) {
BT_ERR ("Checksum failed: computed %04x received %04x",
BT_ERR("Checksum failed: computed %04x received %04x",
bitrev16(bcsp->message_crc),
bscp_get_crc(bcsp));

Expand Down Expand Up @@ -653,8 +657,9 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
BCSP_CRC_INIT(bcsp->message_crc);

/* Do not increment ptr or decrement count
* Allocate packet. Max len of a BCSP pkt=
* 0xFFF (payload) +4 (header) +2 (crc) */
* Allocate packet. Max len of a BCSP pkt=
* 0xFFF (payload) +4 (header) +2 (crc)
*/

bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
if (!bcsp->rx_skb) {
Expand Down
11 changes: 7 additions & 4 deletions drivers/bluetooth/hci_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ static int hci_uart_flush(struct hci_dev *hdev)
tty_ldisc_flush(tty);
tty_driver_flush_buffer(tty);

if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
hu->proto->flush(hu);

return 0;
Expand Down Expand Up @@ -492,14 +492,15 @@ static void hci_uart_tty_close(struct tty_struct *tty)

cancel_work_sync(&hu->write_work);

if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) {
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);
hci_free_dev(hdev);
}
hu->proto->close(hu);
}
clear_bit(HCI_UART_PROTO_SET, &hu->flags);

kfree(hu);
}
Expand All @@ -526,7 +527,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
if (tty != hu->tty)
return;

if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
hci_uart_tx_wakeup(hu);
}

Expand All @@ -550,7 +551,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
if (!hu || tty != hu->tty)
return;

if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
return;

/* It does not need a lock here as it is already protected by a mutex in
Expand Down Expand Up @@ -638,9 +639,11 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
return err;

hu->proto = p;
set_bit(HCI_UART_PROTO_READY, &hu->flags);

err = hci_uart_register_dev(hu);
if (err) {
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
p->close(hu);
return err;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/bluetooth/hci_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct hci_uart {
/* HCI_UART proto flag bits */
#define HCI_UART_PROTO_SET 0
#define HCI_UART_REGISTERED 1
#define HCI_UART_PROTO_READY 2

/* TX states */
#define HCI_UART_SENDING 1
Expand Down
9 changes: 6 additions & 3 deletions drivers/bluetooth/hci_vhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
break;

case HCI_VENDOR_PKT:
cancel_delayed_work_sync(&data->open_timeout);

if (data->hdev) {
kfree_skb(skb);
return -EBADFD;
}

cancel_delayed_work_sync(&data->open_timeout);

opcode = *((__u8 *) skb->data);
skb_pull(skb, 1);

Expand Down Expand Up @@ -333,15 +333,18 @@ static int vhci_open(struct inode *inode, struct file *file)
static int vhci_release(struct inode *inode, struct file *file)
{
struct vhci_data *data = file->private_data;
struct hci_dev *hdev = data->hdev;
struct hci_dev *hdev;

cancel_delayed_work_sync(&data->open_timeout);

hdev = data->hdev;

if (hdev) {
hci_unregister_dev(hdev);
hci_free_dev(hdev);
}

skb_queue_purge(&data->readq);
file->private_data = NULL;
kfree(data);

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ieee802154/adf7242.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,13 +1030,15 @@ static int adf7242_hw_init(struct adf7242_local *lp)
if (ret) {
dev_err(&lp->spi->dev,
"upload firmware failed with %d\n", ret);
release_firmware(fw);
return ret;
}

ret = adf7242_verify_firmware(lp, (u8 *)fw->data, fw->size);
if (ret) {
dev_err(&lp->spi->dev,
"verify firmware failed with %d\n", ret);
release_firmware(fw);
return ret;
}

Expand Down
11 changes: 9 additions & 2 deletions net/6lowpan/iphc.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@
(((a)->s6_addr16[6]) == 0) && \
(((a)->s6_addr[14]) == 0))

#define lowpan_is_linklocal_zero_padded(a) \
(!(hdr->saddr.s6_addr[1] & 0x3f) && \
!hdr->saddr.s6_addr16[1] && \
!hdr->saddr.s6_addr32[1])

#define LOWPAN_IPHC_CID_DCI(cid) (cid & 0x0f)
#define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4)

Expand Down Expand Up @@ -1101,7 +1106,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
true);
iphc1 |= LOWPAN_IPHC_SAC;
} else {
if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL) {
if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL &&
lowpan_is_linklocal_zero_padded(hdr->saddr)) {
iphc1 |= lowpan_compress_addr_64(&hc_ptr,
&hdr->saddr,
saddr, true);
Expand Down Expand Up @@ -1135,7 +1141,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
false);
iphc1 |= LOWPAN_IPHC_DAC;
} else {
if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL) {
if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL &&
lowpan_is_linklocal_zero_padded(hdr->daddr)) {
iphc1 |= lowpan_compress_addr_64(&hc_ptr,
&hdr->daddr,
daddr, false);
Expand Down
13 changes: 13 additions & 0 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -4727,6 +4727,19 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
u32 flags;
u8 *ptr, real_len;

switch (type) {
case LE_ADV_IND:
case LE_ADV_DIRECT_IND:
case LE_ADV_SCAN_IND:
case LE_ADV_NONCONN_IND:
case LE_ADV_SCAN_RSP:
break;
default:
BT_ERR_RATELIMITED("Unknown advetising packet type: 0x%02x",
type);
return;
}

/* Find the end of the data in case the report contains padded zero
* bytes at the end causing an invalid length value.
*
Expand Down
6 changes: 3 additions & 3 deletions net/bluetooth/hci_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,16 +1065,16 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
flags |= LE_AD_LIMITED;

if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
flags |= LE_AD_NO_BREDR;

if (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
/* If a discovery flag wasn't provided, simply use the global
* settings.
*/
if (!flags)
flags |= mgmt_get_adv_discov_flags(hdev);

if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
flags |= LE_AD_NO_BREDR;

/* If flags would still be empty, then there is no need to
* include the "Flags" AD field".
*/
Expand Down
2 changes: 1 addition & 1 deletion net/bluetooth/l2cap_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
}

if (sec.level < BT_SECURITY_LOW ||
sec.level > BT_SECURITY_HIGH) {
sec.level > BT_SECURITY_FIPS) {
err = -EINVAL;
break;
}
Expand Down

0 comments on commit 69fb781

Please sign in to comment.