Message ID | 20180518103811.GA29186@kroah.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Samuel Ortiz |
Headers | show |
On Fri, May 18, 2018 at 12:38:11PM +0200, Greg Kroah-Hartman wrote: > 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. > > The USB stack will free the buffer when the data has been transmitted, > that is why there is no kfree() to mirror the call to kmalloc(). It looks like you're now leaking all but the final transfer buffer that is allocated for outgoing commands, as the URBs themselves are not freed until disconnect() (and that's when core would free the buffers along with the URBs if URB_FREE_BUFFER is set). Johan
On Fri, May 18, 2018 at 05:48:47PM +0200, Johan Hovold wrote: > On Fri, May 18, 2018 at 12:38:11PM +0200, Greg Kroah-Hartman wrote: > > 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. > > > > The USB stack will free the buffer when the data has been transmitted, > > that is why there is no kfree() to mirror the call to kmalloc(). > > It looks like you're now leaking all but the final transfer buffer that > is allocated for outgoing commands, as the URBs themselves are not freed > until disconnect() (and that's when core would free the buffers along > with the URBs if URB_FREE_BUFFER is set). Ugh, you are right. The urb handling in this driver is crazy... Let me go redo this whole thing, give me a few days... thanks for the review, much appreciated. Carlos, it would be good to know if your testing showed that the patch at least enables the device to work for now. It will leak memory like crazy, so I don't recomment relying on the driver, but it should be good enough to see if my thinking as to why the driver was not working is correct or not. greg k-h
--- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -150,10 +150,16 @@ static int pn533_usb_send_ack(struct pn5 struct pn533_usb_phy *phy = dev->phy; static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ + char *buffer; int rc; - phy->out_urb->transfer_buffer = (u8 *)ack; + buffer = kmemdup(ack, sizeof(ack), GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + phy->out_urb->transfer_buffer = buffer; phy->out_urb->transfer_buffer_length = sizeof(ack); + phy->out_urb->transfer_flags |= URB_FREE_BUFFER; rc = usb_submit_urb(phy->out_urb, flags); return rc; @@ -170,6 +176,7 @@ static int pn533_usb_send_frame(struct p phy->out_urb->transfer_buffer = out->data; phy->out_urb->transfer_buffer_length = out->len; + phy->out_urb->transfer_flags &= ~URB_FREE_BUFFER; print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, out->data, out->len, false); @@ -375,20 +382,26 @@ static int pn533_acr122_poweron_rdr(stru /* Power on th reader (CCID cmd) */ u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON, 0, 0, 0, 0, 0, 0, 3, 0, 0}; + char *buffer; int rc; void *cntx; struct pn533_acr122_poweron_rdr_arg arg; dev_dbg(&phy->udev->dev, "%s\n", __func__); + buffer = kmemdup(cmd, sizeof(cmd), GFP_KERNEL); + if (!buffer) + return -ENOMEM; + init_completion(&arg.done); cntx = phy->in_urb->context; /* backup context */ phy->in_urb->complete = pn533_acr122_poweron_rdr_resp; phy->in_urb->context = &arg; - phy->out_urb->transfer_buffer = cmd; + phy->out_urb->transfer_buffer = buffer; phy->out_urb->transfer_buffer_length = sizeof(cmd); + phy->out_urb->transfer_flags |= URB_FREE_BUFFER; print_hex_dump_debug("ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1, cmd, sizeof(cmd), false);
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. The USB stack will free the buffer when the data has been transmitted, that is why there is no kfree() to mirror the call to kmalloc(). 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- v3: actually use the correct buffer (thanks to Arend van Spriel) use kmemdup (thanks to Johannes Berg and Julia Lawall) v2: set the urb flags correctly drivers/nfc/pn533/usb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)