Commit 69fb7812 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/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: default avatarDavid S. Miller <davem@davemloft.net>
parents 9a6f2b01 8805eea2
...@@ -825,6 +825,7 @@ static const struct acpi_device_id bcm_acpi_match[] = { ...@@ -825,6 +825,7 @@ static const struct acpi_device_id bcm_acpi_match[] = {
{ "BCM2E64", 0 }, { "BCM2E64", 0 },
{ "BCM2E65", 0 }, { "BCM2E65", 0 },
{ "BCM2E67", 0 }, { "BCM2E67", 0 },
{ "BCM2E71", 0 },
{ "BCM2E7B", 0 }, { "BCM2E7B", 0 },
{ "BCM2E7C", 0 }, { "BCM2E7C", 0 },
{ }, { },
......
...@@ -102,13 +102,12 @@ static const u16 crc_table[] = { ...@@ -102,13 +102,12 @@ static const u16 crc_table[] = {
/* Initialise the crc calculator */ /* Initialise the crc calculator */
#define BCSP_CRC_INIT(x) x = 0xffff #define BCSP_CRC_INIT(x) x = 0xffff
/* /* Update crc with next data byte
Update crc with next data byte *
* Implementation note
Implementation note * The data byte is treated as two nibbles. The crc is generated
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.
in reverse, i.e., bits are fed into the register from the top. */
*/
static void bcsp_crc_update(u16 *crc, u8 d) static void bcsp_crc_update(u16 *crc, u8 d)
{ {
u16 reg = *crc; u16 reg = *crc;
...@@ -223,9 +222,10 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data, ...@@ -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 /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
(because bytes 0xc0 and 0xdb are escaped, worst case is * (because bytes 0xc0 and 0xdb are escaped, worst case is
when the packet is all made of 0xc0 and 0xdb :) ) * when the packet is all made of 0xc0 and 0xdb :) )
+ 2 (0xc0 delimiters at start and end). */ * + 2 (0xc0 delimiters at start and end).
*/
nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC); nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
if (!nskb) if (!nskb)
...@@ -285,7 +285,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) ...@@ -285,7 +285,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
struct bcsp_struct *bcsp = hu->priv; struct bcsp_struct *bcsp = hu->priv;
unsigned long flags; unsigned long flags;
struct sk_buff *skb; struct sk_buff *skb;
/* First of all, check for unreliable messages in the queue, /* First of all, check for unreliable messages in the queue,
since they have priority */ since they have priority */
...@@ -305,8 +305,9 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) ...@@ -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 /* 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 * reliable packet if the number of packets sent but not yet ack'ed
is < than the winsize */ * is < than the winsize
*/
spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
...@@ -332,12 +333,14 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) ...@@ -332,12 +333,14 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
spin_unlock_irqrestore(&bcsp->unack.lock, flags); spin_unlock_irqrestore(&bcsp->unack.lock, flags);
/* We could not send a reliable packet, either because there are /* We could not send a reliable packet, either because there are
none or because there are too many unack'ed pkts. Did we receive * none or because there are too many unack'ed pkts. Did we receive
any packets we have not acknowledged yet ? */ * any packets we have not acknowledged yet ?
*/
if (bcsp->txack_req) { if (bcsp->txack_req) {
/* if so, craft an empty ACK pkt and send it on BCSP unreliable /* 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); struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
return nskb; return nskb;
} }
...@@ -399,8 +402,9 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) ...@@ -399,8 +402,9 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
} }
/* Handle BCSP link-establishment packets. When we /* Handle BCSP link-establishment packets. When we
detect a "sync" packet, symptom that the BT module has reset, * detect a "sync" packet, symptom that the BT module has reset,
we do nothing :) (yet) */ * we do nothing :) (yet)
*/
static void bcsp_handle_le_pkt(struct hci_uart *hu) static void bcsp_handle_le_pkt(struct hci_uart *hu)
{ {
struct bcsp_struct *bcsp = hu->priv; struct bcsp_struct *bcsp = hu->priv;
...@@ -462,7 +466,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char ...@@ -462,7 +466,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
case 0xdd: case 0xdd:
memcpy(skb_put(bcsp->rx_skb, 1), &db, 1); memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
if ((bcsp->rx_skb->data[0] & 0x40) != 0 && 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_crc_update(&bcsp->message_crc, 0xdb);
bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
bcsp->rx_count--; bcsp->rx_count--;
...@@ -534,7 +538,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) ...@@ -534,7 +538,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
} else { } else {
BT_ERR("Packet for unknown channel (%u %s)", BT_ERR("Packet for unknown channel (%u %s)",
bcsp->rx_skb->data[1] & 0x0f, bcsp->rx_skb->data[1] & 0x0f,
bcsp->rx_skb->data[0] & 0x80 ? bcsp->rx_skb->data[0] & 0x80 ?
"reliable" : "unreliable"); "reliable" : "unreliable");
kfree_skb(bcsp->rx_skb); kfree_skb(bcsp->rx_skb);
} }
...@@ -562,7 +566,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) ...@@ -562,7 +566,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
struct bcsp_struct *bcsp = hu->priv; struct bcsp_struct *bcsp = hu->priv;
const unsigned char *ptr; 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); hu, count, bcsp->rx_state, bcsp->rx_count);
ptr = data; ptr = data;
...@@ -591,7 +595,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) ...@@ -591,7 +595,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
continue; continue;
} }
if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */ 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", BT_ERR("Out-of-order packet arrived, got %u expected %u",
bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack); bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
...@@ -601,7 +605,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) ...@@ -601,7 +605,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
continue; continue;
} }
bcsp->rx_state = BCSP_W4_DATA; 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 */ (bcsp->rx_skb->data[2] << 4); /* May be 0 */
continue; continue;
...@@ -615,7 +619,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) ...@@ -615,7 +619,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
case BCSP_W4_CRC: case BCSP_W4_CRC:
if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) { 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), bitrev16(bcsp->message_crc),
bscp_get_crc(bcsp)); bscp_get_crc(bcsp));
...@@ -653,8 +657,9 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) ...@@ -653,8 +657,9 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
BCSP_CRC_INIT(bcsp->message_crc); BCSP_CRC_INIT(bcsp->message_crc);
/* Do not increment ptr or decrement count /* Do not increment ptr or decrement count
* Allocate packet. Max len of a BCSP pkt= * Allocate packet. Max len of a BCSP pkt=
* 0xFFF (payload) +4 (header) +2 (crc) */ * 0xFFF (payload) +4 (header) +2 (crc)
*/
bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC); bcsp->rx_skb = bt_skb_alloc(0x1005, GFP_ATOMIC);
if (!bcsp->rx_skb) { if (!bcsp->rx_skb) {
......
...@@ -227,7 +227,7 @@ static int hci_uart_flush(struct hci_dev *hdev) ...@@ -227,7 +227,7 @@ static int hci_uart_flush(struct hci_dev *hdev)
tty_ldisc_flush(tty); tty_ldisc_flush(tty);
tty_driver_flush_buffer(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); hu->proto->flush(hu);
return 0; return 0;
...@@ -492,7 +492,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) ...@@ -492,7 +492,7 @@ static void hci_uart_tty_close(struct tty_struct *tty)
cancel_work_sync(&hu->write_work); 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 (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags)) if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev); hci_unregister_dev(hdev);
...@@ -500,6 +500,7 @@ static void hci_uart_tty_close(struct tty_struct *tty) ...@@ -500,6 +500,7 @@ static void hci_uart_tty_close(struct tty_struct *tty)
} }
hu->proto->close(hu); hu->proto->close(hu);
} }
clear_bit(HCI_UART_PROTO_SET, &hu->flags);
kfree(hu); kfree(hu);
} }
...@@ -526,7 +527,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) ...@@ -526,7 +527,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
if (tty != hu->tty) if (tty != hu->tty)
return; return;
if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
hci_uart_tx_wakeup(hu); hci_uart_tx_wakeup(hu);
} }
...@@ -550,7 +551,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, ...@@ -550,7 +551,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
if (!hu || tty != hu->tty) if (!hu || tty != hu->tty)
return; return;
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
return; return;
/* It does not need a lock here as it is already protected by a mutex in /* It does not need a lock here as it is already protected by a mutex in
...@@ -638,9 +639,11 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) ...@@ -638,9 +639,11 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
return err; return err;
hu->proto = p; hu->proto = p;
set_bit(HCI_UART_PROTO_READY, &hu->flags);
err = hci_uart_register_dev(hu); err = hci_uart_register_dev(hu);
if (err) { if (err) {
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
p->close(hu); p->close(hu);
return err; return err;
} }
......
...@@ -95,6 +95,7 @@ struct hci_uart { ...@@ -95,6 +95,7 @@ struct hci_uart {
/* HCI_UART proto flag bits */ /* HCI_UART proto flag bits */
#define HCI_UART_PROTO_SET 0 #define HCI_UART_PROTO_SET 0
#define HCI_UART_REGISTERED 1 #define HCI_UART_REGISTERED 1
#define HCI_UART_PROTO_READY 2
/* TX states */ /* TX states */
#define HCI_UART_SENDING 1 #define HCI_UART_SENDING 1
......
...@@ -189,13 +189,13 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, ...@@ -189,13 +189,13 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
break; break;
case HCI_VENDOR_PKT: case HCI_VENDOR_PKT:
cancel_delayed_work_sync(&data->open_timeout);
if (data->hdev) { if (data->hdev) {
kfree_skb(skb); kfree_skb(skb);
return -EBADFD; return -EBADFD;
} }
cancel_delayed_work_sync(&data->open_timeout);
opcode = *((__u8 *) skb->data); opcode = *((__u8 *) skb->data);
skb_pull(skb, 1); skb_pull(skb, 1);
...@@ -333,15 +333,18 @@ static int vhci_open(struct inode *inode, struct file *file) ...@@ -333,15 +333,18 @@ static int vhci_open(struct inode *inode, struct file *file)
static int vhci_release(struct inode *inode, struct file *file) static int vhci_release(struct inode *inode, struct file *file)
{ {
struct vhci_data *data = file->private_data; struct vhci_data *data = file->private_data;
struct hci_dev *hdev = data->hdev; struct hci_dev *hdev;
cancel_delayed_work_sync(&data->open_timeout); cancel_delayed_work_sync(&data->open_timeout);
hdev = data->hdev;
if (hdev) { if (hdev) {
hci_unregister_dev(hdev); hci_unregister_dev(hdev);
hci_free_dev(hdev); hci_free_dev(hdev);
} }
skb_queue_purge(&data->readq);
file->private_data = NULL; file->private_data = NULL;
kfree(data); kfree(data);
......
...@@ -1030,6 +1030,7 @@ static int adf7242_hw_init(struct adf7242_local *lp) ...@@ -1030,6 +1030,7 @@ static int adf7242_hw_init(struct adf7242_local *lp)
if (ret) { if (ret) {
dev_err(&lp->spi->dev, dev_err(&lp->spi->dev,
"upload firmware failed with %d\n", ret); "upload firmware failed with %d\n", ret);
release_firmware(fw);
return ret; return ret;
} }
...@@ -1037,6 +1038,7 @@ static int adf7242_hw_init(struct adf7242_local *lp) ...@@ -1037,6 +1038,7 @@ static int adf7242_hw_init(struct adf7242_local *lp)
if (ret) { if (ret) {
dev_err(&lp->spi->dev, dev_err(&lp->spi->dev,
"verify firmware failed with %d\n", ret); "verify firmware failed with %d\n", ret);
release_firmware(fw);
return ret; return ret;
} }
......
...@@ -148,6 +148,11 @@ ...@@ -148,6 +148,11 @@
(((a)->s6_addr16[6]) == 0) && \ (((a)->s6_addr16[6]) == 0) && \
(((a)->s6_addr[14]) == 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_DCI(cid) (cid & 0x0f)
#define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4) #define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4)
...@@ -1101,7 +1106,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, ...@@ -1101,7 +1106,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
true); true);
iphc1 |= LOWPAN_IPHC_SAC; iphc1 |= LOWPAN_IPHC_SAC;
} else { } 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, iphc1 |= lowpan_compress_addr_64(&hc_ptr,
&hdr->saddr, &hdr->saddr,
saddr, true); saddr, true);
...@@ -1135,7 +1141,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, ...@@ -1135,7 +1141,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
false); false);
iphc1 |= LOWPAN_IPHC_DAC; iphc1 |= LOWPAN_IPHC_DAC;
} else { } 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, iphc1 |= lowpan_compress_addr_64(&hc_ptr,
&hdr->daddr, &hdr->daddr,
daddr, false); daddr, false);
......
...@@ -4727,6 +4727,19 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4727,6 +4727,19 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
u32 flags; u32 flags;
u8 *ptr, real_len; 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 /* Find the end of the data in case the report contains padded zero
* bytes at the end causing an invalid length value. * bytes at the end causing an invalid length value.
* *
......
...@@ -1065,6 +1065,9 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) ...@@ -1065,6 +1065,9 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV) if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV)
flags |= LE_AD_LIMITED; 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 (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) {
/* If a discovery flag wasn't provided, simply use the global /* If a discovery flag wasn't provided, simply use the global
* settings. * settings.
...@@ -1072,9 +1075,6 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) ...@@ -1072,9 +1075,6 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
if (!flags) if (!flags)
flags |= mgmt_get_adv_discov_flags(hdev); 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 /* If flags would still be empty, then there is no need to
* include the "Flags" AD field". * include the "Flags" AD field".
*/ */
......
...@@ -778,7 +778,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ...@@ -778,7 +778,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
} }
if (sec.level < BT_SECURITY_LOW || if (sec.level < BT_SECURITY_LOW ||
sec.level > BT_SECURITY_HIGH) { sec.level > BT_SECURITY_FIPS) {
err = -EINVAL; err = -EINVAL;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment