From a5eddc1f77a2ad8d45f6494e719aa491217e4107 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Fri, 14 Jul 2017 16:47:10 +0530 Subject: [PATCH] USB: f_accessory: Check for length before updating accessory string It is possible that host sends SEND_STRING control request with zero length and in that case, driver ends up setting string as NULL. This results in CTS failure for accessory test. Hence add check for length and update string only if length is nonzero. Change-Id: I4594a46f830f45fc49f80a74ec6042383edf007d Signed-off-by: Vijayavardhan Vennapusa --- drivers/usb/gadget/function/f_accessory.c | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index 1ef3442cf618..7950f25136a5 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c @@ -346,6 +346,7 @@ static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) struct acc_dev *dev = ep->driver_data; char *string_dest = NULL; int length = req->actual; + unsigned long flags; if (req->status != 0) { pr_err("acc_complete_set_string, err %d\n", req->status); @@ -371,22 +372,26 @@ static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) case ACCESSORY_STRING_SERIAL: string_dest = dev->serial; break; - } - if (string_dest) { - unsigned long flags; - - if (length >= ACC_STRING_SIZE) - length = ACC_STRING_SIZE - 1; - - spin_lock_irqsave(&dev->lock, flags); - memcpy(string_dest, req->buf, length); - /* ensure zero termination */ - string_dest[length] = 0; - spin_unlock_irqrestore(&dev->lock, flags); - } else { + default: pr_err("unknown accessory string index %d\n", - dev->string_index); + dev->string_index); + return; } + + if (!length) { + pr_debug("zero length for accessory string index %d\n", + dev->string_index); + return; + } + + if (length >= ACC_STRING_SIZE) + length = ACC_STRING_SIZE - 1; + + spin_lock_irqsave(&dev->lock, flags); + memcpy(string_dest, req->buf, length); + /* ensure zero termination */ + string_dest[length] = 0; + spin_unlock_irqrestore(&dev->lock, flags); } static void acc_complete_set_hid_report_desc(struct usb_ep *ep,