From patchwork Fri Apr 4 09:58:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Whitcroft X-Patchwork-Id: 336896 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 559361400C6 for ; Fri, 4 Apr 2014 20:58:53 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WW0tb-0001CV-P1; Fri, 04 Apr 2014 09:58:47 +0000 Received: from mail-we0-f178.google.com ([74.125.82.178]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WW0tQ-0001Aw-UB for kernel-team@lists.ubuntu.com; Fri, 04 Apr 2014 09:58:36 +0000 Received: by mail-we0-f178.google.com with SMTP id u56so3170634wes.9 for ; Fri, 04 Apr 2014 02:58:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DifymMuSWyYyEQ1bicgwdY0/brAPgQoOYQEtAAxoRPg=; b=gFjGlLnep2PX/4myy4wwnkRcQXxJvmXk4JHGsXM3RWbcvfQ03QZpVC5tXjra9t7s0Q lh8QMMUNEy4qHx/mDgDncHSf3MGdbA7abvieHa5aMN3S/SgFndG35AjAJrNnz4gLgoMa 7MTGnKKDY1FJTYxFYlM23vgcPo6cJ1ZHfr+1bJuQzsruB/NL0u4WxcEWyKiAg07lx1iz 542DrgE3tGTOHMzvY46FHZUhO93IF3b0wS90PhGmVCAXVa4DChQA3Cr24TfGhzYpxAwS whfc89Ky5mEBBJ96CD5T38UrNY13uEf6dVBrOm4ACGjbehHTghNKRCpym+FE0KYxq1jN Bdpg== X-Gm-Message-State: ALoCoQlS9C1zgJJoZwfBgKx/gBWs41qiKG7v3/IMS4avaZ1wVBNlqKOTwgA8ZXvishIxwzpSXGID X-Received: by 10.180.24.72 with SMTP id s8mr3166825wif.20.1396605516757; Fri, 04 Apr 2014 02:58:36 -0700 (PDT) Received: from localhost ([2001:470:6973:2:221:70ff:fe81:b177]) by mx.google.com with ESMTPSA id hi1sm11708340wjb.17.2014.04.04.02.58.35 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 04 Apr 2014 02:58:36 -0700 (PDT) From: Andy Whitcroft To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/1] HID: Bluetooth: hidp: make sure input buffers are big enough Date: Fri, 4 Apr 2014 10:58:32 +0100 Message-Id: <1396605512-28181-2-git-send-email-apw@canonical.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1396605512-28181-1-git-send-email-apw@canonical.com> References: <1396605512-28181-1-git-send-email-apw@canonical.com> Cc: Andy Whitcroft X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: David Herrmann HID core expects the input buffers to be at least of size 4096 (HID_MAX_BUFFER_SIZE). Other sizes will result in buffer-overflows if an input-report is smaller than advertised. We could, like i2c, compute the biggest report-size instead of using HID_MAX_BUFFER_SIZE, but this will blow up if report-descriptors are changed after ->start() has been called. So lets be safe and just use the biggest buffer we have. Note that this adds an additional copy to the HIDP input path. If there is a way to make sure the skb-buf is big enough, we should use that instead. The best way would be to make hid-core honor the @size argument, though, that sounds easier than it is. So lets just fix the buffer-overflows for now and afterwards look for a faster way for all transport drivers. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina (cherry picked from commit a4b1b5877b514b276f0f31efe02388a9c2836728) BugLink: http://bugs.launchpad.net/bugs/1301990 Signed-off-by: Andy Whitcroft --- net/bluetooth/hidp/core.c | 16 ++++++++++++++-- net/bluetooth/hidp/hidp.h | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 292e619..d9fb934 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -430,6 +430,16 @@ static void hidp_del_timer(struct hidp_session *session) del_timer(&session->timer); } +static void hidp_process_report(struct hidp_session *session, + int type, const u8 *data, int len, int intr) +{ + if (len > HID_MAX_BUFFER_SIZE) + len = HID_MAX_BUFFER_SIZE; + + memcpy(session->input_buf, data, len); + hid_input_report(session->hid, type, session->input_buf, len, intr); +} + static void hidp_process_handshake(struct hidp_session *session, unsigned char param) { @@ -502,7 +512,8 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, hidp_input_report(session, skb); if (session->hid) - hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0); + hidp_process_report(session, HID_INPUT_REPORT, + skb->data, skb->len, 0); break; case HIDP_DATA_RTYPE_OTHER: @@ -584,7 +595,8 @@ static void hidp_recv_intr_frame(struct hidp_session *session, hidp_input_report(session, skb); if (session->hid) { - hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 1); + hidp_process_report(session, HID_INPUT_REPORT, + skb->data, skb->len, 1); BT_DBG("report len %d", skb->len); } } else { diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index ab52414..8798492 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h @@ -24,6 +24,7 @@ #define __HIDP_H #include +#include #include #include #include @@ -179,6 +180,9 @@ struct hidp_session { /* Used in hidp_output_raw_report() */ int output_report_success; /* boolean */ + + /* temporary input buffer */ + u8 input_buf[HID_MAX_BUFFER_SIZE]; }; /* HIDP init defines */