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

NFC: pn533: don't send USB data off of the stack

It's amazing that this driver ever worked, but now that x86 doesn't
allow USB data to be sent off of the stack, it really does not work at
all. Fix this up by properly allocating the data for the small
"commands" that get sent to the device off of the stack.

We do this for one command by having a whole urb just for ack messages,
as they can be submitted in interrupt context, so we can not use
usb_bulk_msg(). But the poweron command can sleep (and does), so use
usb_bulk_msg() for that transfer.

Reported-by: Carlos Manuel Santos <cmmpsantos@gmail.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: stable <stable@vger.kernel.org>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+30 -12
+30 -12
drivers/nfc/pn533/usb.c
··· 62 62 struct urb *out_urb; 63 63 struct urb *in_urb; 64 64 65 + struct urb *ack_urb; 66 + u8 *ack_buffer; 67 + 65 68 struct pn533 *priv; 66 69 }; 67 70 ··· 153 150 struct pn533_usb_phy *phy = dev->phy; 154 151 static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; 155 152 /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ 156 - int rc; 157 153 158 - phy->out_urb->transfer_buffer = (u8 *)ack; 159 - phy->out_urb->transfer_buffer_length = sizeof(ack); 160 - rc = usb_submit_urb(phy->out_urb, flags); 154 + if (!phy->ack_buffer) { 155 + phy->ack_buffer = kmemdup(ack, sizeof(ack), flags); 156 + if (!phy->ack_buffer) 157 + return -ENOMEM; 158 + } 161 159 162 - return rc; 160 + phy->ack_urb->transfer_buffer = phy->ack_buffer; 161 + phy->ack_urb->transfer_buffer_length = sizeof(ack); 162 + return usb_submit_urb(phy->ack_urb, flags); 163 163 } 164 164 165 165 static int pn533_usb_send_frame(struct pn533 *dev, ··· 381 375 /* Power on th reader (CCID cmd) */ 382 376 u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON, 383 377 0, 0, 0, 0, 0, 0, 3, 0, 0}; 378 + char *buffer; 379 + int transferred; 384 380 int rc; 385 381 void *cntx; 386 382 struct pn533_acr122_poweron_rdr_arg arg; 387 383 388 384 dev_dbg(&phy->udev->dev, "%s\n", __func__); 385 + 386 + buffer = kmemdup(cmd, sizeof(cmd), GFP_KERNEL); 387 + if (!buffer) 388 + return -ENOMEM; 389 389 390 390 init_completion(&arg.done); 391 391 cntx = phy->in_urb->context; /* backup context */ ··· 399 387 phy->in_urb->complete = pn533_acr122_poweron_rdr_resp; 400 388 phy->in_urb->context = &arg; 401 389 402 - phy->out_urb->transfer_buffer = cmd; 403 - phy->out_urb->transfer_buffer_length = sizeof(cmd); 404 - 405 390 print_hex_dump_debug("ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1, 406 391 cmd, sizeof(cmd), false); 407 392 408 - rc = usb_submit_urb(phy->out_urb, GFP_KERNEL); 409 - if (rc) { 393 + rc = usb_bulk_msg(phy->udev, phy->out_urb->pipe, buffer, sizeof(cmd), 394 + &transferred, 0); 395 + kfree(buffer); 396 + if (rc || (transferred != sizeof(cmd))) { 410 397 nfc_err(&phy->udev->dev, 411 398 "Reader power on cmd error %d\n", rc); 412 399 return rc; ··· 501 490 502 491 phy->in_urb = usb_alloc_urb(0, GFP_KERNEL); 503 492 phy->out_urb = usb_alloc_urb(0, GFP_KERNEL); 493 + phy->ack_urb = usb_alloc_urb(0, GFP_KERNEL); 504 494 505 - if (!phy->in_urb || !phy->out_urb) 495 + if (!phy->in_urb || !phy->out_urb || !phy->ack_urb) 506 496 goto error; 507 497 508 498 usb_fill_bulk_urb(phy->in_urb, phy->udev, ··· 513 501 usb_fill_bulk_urb(phy->out_urb, phy->udev, 514 502 usb_sndbulkpipe(phy->udev, out_endpoint), 515 503 NULL, 0, pn533_send_complete, phy); 516 - 504 + usb_fill_bulk_urb(phy->ack_urb, phy->udev, 505 + usb_sndbulkpipe(phy->udev, out_endpoint), 506 + NULL, 0, pn533_send_complete, phy); 517 507 518 508 switch (id->driver_info) { 519 509 case PN533_DEVICE_STD: ··· 568 554 error: 569 555 usb_free_urb(phy->in_urb); 570 556 usb_free_urb(phy->out_urb); 557 + usb_free_urb(phy->ack_urb); 571 558 usb_put_dev(phy->udev); 572 559 kfree(in_buf); 573 560 ··· 588 573 589 574 usb_kill_urb(phy->in_urb); 590 575 usb_kill_urb(phy->out_urb); 576 + usb_kill_urb(phy->ack_urb); 591 577 592 578 kfree(phy->in_urb->transfer_buffer); 593 579 usb_free_urb(phy->in_urb); 594 580 usb_free_urb(phy->out_urb); 581 + usb_free_urb(phy->ack_urb); 582 + kfree(phy->ack_buffer); 595 583 596 584 nfc_info(&interface->dev, "NXP PN533 NFC device disconnected\n"); 597 585 }