Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: bnep: Add support to extended headers of control frames

Handling extended headers of control frames is required BNEP
functionality. This patch refractor bnep rx frame handling function.
Extended header for control frames shouldn't be omitted as it was
previously done. Every control frame should be checked if it contains
extended header and then every extension should be parsed separately.

Signed-off-by: Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Grzegorz Kolodziejczyk and committed by
Marcel Holtmann
bf8b9a9c 0477e2e8

+38 -12
+38 -12
net/bluetooth/bnep/core.c
··· 292 292 { 293 293 struct net_device *dev = s->dev; 294 294 struct sk_buff *nskb; 295 - u8 type; 295 + u8 type, ctrl_type; 296 296 297 297 dev->stats.rx_bytes += skb->len; 298 298 299 299 type = *(u8 *) skb->data; 300 300 skb_pull(skb, 1); 301 + ctrl_type = *(u8 *)skb->data; 301 302 302 303 if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) 303 304 goto badframe; 304 305 305 306 if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { 306 - bnep_rx_control(s, skb->data, skb->len); 307 - kfree_skb(skb); 308 - return 0; 307 + if (bnep_rx_control(s, skb->data, skb->len) < 0) { 308 + dev->stats.tx_errors++; 309 + kfree_skb(skb); 310 + return 0; 311 + } 312 + 313 + if (!(type & BNEP_EXT_HEADER)) { 314 + kfree_skb(skb); 315 + return 0; 316 + } 317 + 318 + /* Verify and pull ctrl message since it's already processed */ 319 + switch (ctrl_type) { 320 + case BNEP_SETUP_CONN_REQ: 321 + /* Pull: ctrl type (1 b), len (1 b), data (len bytes) */ 322 + if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2)) 323 + goto badframe; 324 + break; 325 + case BNEP_FILTER_MULTI_ADDR_SET: 326 + case BNEP_FILTER_NET_TYPE_SET: 327 + /* Pull: ctrl type (1 b), len (2 b), data (len bytes) */ 328 + if (!skb_pull(skb, 3 + *(u16 *)(skb->data + 1) * 2)) 329 + goto badframe; 330 + break; 331 + default: 332 + kfree_skb(skb); 333 + return 0; 334 + } 335 + } else { 336 + skb_reset_mac_header(skb); 337 + 338 + /* Verify and pull out header */ 339 + if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) 340 + goto badframe; 341 + 342 + s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); 309 343 } 310 - 311 - skb_reset_mac_header(skb); 312 - 313 - /* Verify and pull out header */ 314 - if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) 315 - goto badframe; 316 - 317 - s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); 318 344 319 345 if (type & BNEP_EXT_HEADER) { 320 346 if (bnep_rx_extension(s, skb) < 0)