From patchwork Thu Dec 19 11:09:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 3376731 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B88A79F314 for ; Thu, 19 Dec 2013 11:10:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 01C832063D for ; Thu, 19 Dec 2013 11:10:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CF69020639 for ; Thu, 19 Dec 2013 11:10:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752188Ab3LSLKU (ORCPT ); Thu, 19 Dec 2013 06:10:20 -0500 Received: from mail-ee0-f45.google.com ([74.125.83.45]:43593 "EHLO mail-ee0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752165Ab3LSLKT (ORCPT ); Thu, 19 Dec 2013 06:10:19 -0500 Received: by mail-ee0-f45.google.com with SMTP id d49so389897eek.32 for ; Thu, 19 Dec 2013 03:10:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=J5kPwvi3iB7CptQOpEQbBnRLiAfMHLmIeza5WG051u0=; b=fg3NT47DrQDWdINY56IyjCVTFXXfptAC7OTncuUcr3KIC+FDAMyDykQfiioA6UYaG0 xito4vb03P2F+M20qhMjXfYLKDzQeCJ2fDypyLYx5zvQeMcPSwgutHHK8FaMr8pR/TIA voxmx5avXc7TO5stdQORAj3h8OrPH+wYzCwMgJwwNk+mhb6VBoUv8UojIlprNi/x3hPv uHvsA6lqRd8MHZ5pIjwbsNG5STigtw7csHq8pKWhea9kTSgSt21sZUDAUczdW9/gQGyG bB/o+F3TaTLilYm11IP4KLzxZLwQt1+bgdOQCNosAeRWuO1hOT4kqRm86OLZSB6kPKuR asKQ== X-Received: by 10.14.107.3 with SMTP id n3mr1131478eeg.67.1387451415735; Thu, 19 Dec 2013 03:10:15 -0800 (PST) Received: from localhost.localdomain (stgt-5f719d74.pool.mediaWays.net. [95.113.157.116]) by mx.google.com with ESMTPSA id 4sm8386161eed.14.2013.12.19.03.10.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 19 Dec 2013 03:10:14 -0800 (PST) From: David Herrmann To: linux-input@vger.kernel.org Cc: Jiri Kosina , , Marcel Holtmann , Gustavo Padovan , David Herrmann Subject: [PATCH] Bluetooth: hidp: make sure input buffers are big enough Date: Thu, 19 Dec 2013 12:09:32 +0100 Message-Id: <1387451372-6881-1-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.5.1 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Acked-by: Marcel Holtmann --- Hi Any ideas how to improve this patch? I'd like to avoid the extra copy but I have no clue how the skb stuff works exactly. I also haven't figured out a nice way to make HID-core honor the "size" parameter. hid-input depends on getting the whole input-report. Comments welcome! David 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 */