From patchwork Thu Jul 1 08:17:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Kerr X-Patchwork-Id: 1499450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=linux-fsi-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GFsTq2xc2z9sXL for ; Thu, 1 Jul 2021 18:54:39 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GFsTp3bK4z306R for ; Thu, 1 Jul 2021 18:54:38 +1000 (AEST) X-Original-To: linux-fsi@lists.ozlabs.org Delivered-To: linux-fsi@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=codeconstruct.com.au (client-ip=203.29.241.158; helo=codeconstruct.com.au; envelope-from=jk@codeconstruct.com.au; receiver=) Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4GFrsb0j1yz3033 for ; Thu, 1 Jul 2021 18:26:42 +1000 (AEST) Received: by codeconstruct.com.au (Postfix, from userid 10000) id 2A1702199D; Thu, 1 Jul 2021 16:18:18 +0800 (AWST) From: Jeremy Kerr To: linux-fsi@lists.ozlabs.org Subject: [PATCH 3/3] fsi: core: Make userspace access checks more explicit Date: Thu, 1 Jul 2021 16:17:58 +0800 Message-Id: <20210701081758.469776-3-jk@codeconstruct.com.au> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210701081758.469776-1-jk@codeconstruct.com.au> References: <20210701081758.469776-1-jk@codeconstruct.com.au> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 01 Jul 2021 18:54:36 +1000 X-BeenThere: linux-fsi@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-fsi-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "linux-fsi" Currently, we have some non-obvious checks on the offset and count values for cfam_read, cfam_write, sysfs_raw_read and sysfs_raw_write. This change simplifies these checks into their individual components, and moves them all into a common fsi_validate_range() function, shared between all userspace access functions. Signed-off-by: Jeremy Kerr Fixes: d1dcd6782576 ("fsi: Add cfam char devices") Reported-by: Luo Likang --- drivers/fsi/fsi-core.c | 50 ++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index efd0d78ef234..af681866b8f4 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -44,6 +44,10 @@ static const int engine_page_size = 0x400; #define FSI_SLAVE_BASE 0x800 +/* The FSI protocol itself has a maximum 23-bit address space, all addressing + * must be inder this size */ +#define FSI_ADDR_SIZE 0x00800000 + /* * FSI slave engine control register offsets */ @@ -575,6 +579,19 @@ static unsigned long aligned_access_size(size_t offset, size_t count) return BIT(__builtin_ctzl(offset_unit | count_unit)); } +static int fsi_validate_range(loff_t off, size_t count) +{ + if (off < 0) + return -EINVAL; + if (off >= FSI_ADDR_SIZE) + return -EINVAL; + if (count < 0) + return -EINVAL; + if (count > FSI_ADDR_SIZE - off) + return -EINVAL; + return 0; +} + static ssize_t fsi_slave_sysfs_raw_read(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -583,11 +600,9 @@ static ssize_t fsi_slave_sysfs_raw_read(struct file *file, size_t total_len, read_len; int rc; - if (off < 0) - return -EINVAL; - - if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff) - return -EINVAL; + rc = fsi_validate_range(off, count); + if (rc) + return rc; for (total_len = 0; total_len < count; total_len += read_len) { read_len = aligned_access_size(off, count - total_len); @@ -610,11 +625,9 @@ static ssize_t fsi_slave_sysfs_raw_write(struct file *file, size_t total_len, write_len; int rc; - if (off < 0) - return -EINVAL; - - if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff) - return -EINVAL; + rc = fsi_validate_range(off, count); + if (rc) + return rc; for (total_len = 0; total_len < count; total_len += write_len) { write_len = aligned_access_size(off, count - total_len); @@ -699,11 +712,9 @@ static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count, loff_t off = *offset; ssize_t rc; - if (off < 0) - return -EINVAL; - - if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff) - return -EINVAL; + rc = fsi_validate_range(off, count); + if (rc) + return rc; for (total_len = 0; total_len < count; total_len += read_len) { __be32 data; @@ -734,12 +745,9 @@ static ssize_t cfam_write(struct file *filep, const char __user *buf, loff_t off = *offset; ssize_t rc; - - if (off < 0) - return -EINVAL; - - if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff) - return -EINVAL; + rc = fsi_validate_range(off, count); + if (rc) + return rc; for (total_len = 0; total_len < count; total_len += write_len) { __be32 data;