Skip to content

Commit

Permalink
NFC: Queue a copy of the transmitted LLCP skb
Browse files Browse the repository at this point in the history
Drivers are allowed to modify the sent skb and thus we need to make a copy
of it before passing it to the driver. Without this fix, LLCP Tx skbs were
not queued properly as the ptype check was failing due to e.g. the pn533
driver skb_pushing the Tx skb.

Reported-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Samuel Ortiz committed Nov 19, 2012
1 parent dd2bf43 commit be02b6b
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions net/nfc/llcp/llcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,29 +656,38 @@ static void nfc_llcp_tx_work(struct work_struct *work)
if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) {
nfc_llcp_send_symm(local->dev);
} else {
struct sk_buff *copy_skb = NULL;
u8 ptype = nfc_llcp_ptype(skb);
int ret;

pr_debug("Sending pending skb\n");
print_hex_dump(KERN_DEBUG, "LLCP Tx: ",
DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb->len, true);

if (ptype == LLCP_PDU_I)
copy_skb = skb_copy(skb, GFP_ATOMIC);

nfc_llcp_send_to_raw_sock(local, skb,
NFC_LLCP_DIRECTION_TX);

ret = nfc_data_exchange(local->dev, local->target_idx,
skb, nfc_llcp_recv, local);

if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) {
skb = skb_get(skb);
skb_queue_tail(&llcp_sock->tx_pending_queue,
skb);
if (ret) {
kfree_skb(copy_skb);
goto out;
}

if (ptype == LLCP_PDU_I && copy_skb)
skb_queue_tail(&llcp_sock->tx_pending_queue,
copy_skb);
}
} else {
nfc_llcp_send_symm(local->dev);
}

out:
mod_timer(&local->link_timer,
jiffies + msecs_to_jiffies(2 * local->remote_lto));
}
Expand Down

0 comments on commit be02b6b

Please sign in to comment.