Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a38964b4 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: ipa: Fix copy destination compiler error



There are a lot of these error messages scattered throughout gsi and ipa
files:

./include/linux/thread_info.h:147:4: error: call to '__bad_copy_to' declared
with attribute error: copy destination size is too small

This is because the compiler can't be sure that the size of the copy will
fit in the structure. This seems to be caused by the bounds check that
precedes the copy_from_user calls:

  if (sizeof(dbg_buff) < count + 1)

It looks like this has to do with the possibility that (count + 1) could
wrap. This is logically the same check without the math:

  if (count >= sizeof(dbg_buff))

Change all the prior logic to the latter to quiet the warnings. But we can
go even further - most of the copy_from_user() functions are converted to
an integer of some type so we can skip a lot of the copy math and just use
strtoXXX_from_user where XXX is the type to convert from.  This helps get
rid of a lot of the original copy_from_user() complaints (but not all and
thats okay).

Fixes: 859783a1 ("msm: ipa: Add snapshot of IPA driver")
Change-Id: Ic0dedbad314dd4ba7a6c31e62b9d2f409f9a1593
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 0467cd78
Loading
Loading
Loading
Loading
+18 −39
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/completion.h>
@@ -39,7 +39,7 @@ static ssize_t gsi_dump_evt(struct file *file,
	struct gsi_evt_ctx *ctx;
	uint16_t i;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		return -EINVAL;

	missing = copy_from_user(dbg_buff, buf, count);
@@ -152,7 +152,7 @@ static ssize_t gsi_dump_ch(struct file *file,
	struct gsi_chan_ctx *ctx;
	uint16_t i;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		return -EINVAL;

	missing = copy_from_user(dbg_buff, buf, count);
@@ -291,18 +291,11 @@ static ssize_t gsi_dump_stats(struct file *file,
		const char __user *buf, size_t count, loff_t *ppos)
{
	int ch_id;
	int min, max;
	int min, max, ret;

	if (sizeof(dbg_buff) < count + 1)
		goto error;

	if (copy_from_user(dbg_buff, buf, count))
		goto error;

	dbg_buff[count] = '\0';

	if (kstrtos32(dbg_buff, 0, &ch_id))
		goto error;
	ret = kstrtos32_from_user(buf, count, 0, &ch_id);
	if (ret)
		return ret;

	if (ch_id == -1) {
		min = 0;
@@ -352,7 +345,7 @@ static ssize_t gsi_enable_dp_stats(struct file *file,
	bool enable;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		goto error;

	if (copy_from_user(dbg_buff, buf, count))
@@ -412,7 +405,7 @@ static ssize_t gsi_set_max_elem_dp_stats(struct file *file,
	char *sptr, *token;


	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		goto error;

	missing = copy_from_user(dbg_buff, buf, count);
@@ -532,18 +525,11 @@ static ssize_t gsi_rst_stats(struct file *file,
		const char __user *buf, size_t count, loff_t *ppos)
{
	int ch_id;
	int min, max;

	if (sizeof(dbg_buff) < count + 1)
		goto error;
	int min, max, ret;

	if (copy_from_user(dbg_buff, buf, count))
		goto error;

	dbg_buff[count] = '\0';

	if (kstrtos32(dbg_buff, 0, &ch_id))
		goto error;
	ret = kstrtos32_from_user(buf, count, 0, &ch_id);
	if (ret)
		return ret;

	if (ch_id == -1) {
		min = 0;
@@ -573,7 +559,7 @@ static ssize_t gsi_print_dp_stats(struct file *file,
	bool enable;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		goto error;

	if (copy_from_user(dbg_buff, buf, count))
@@ -627,19 +613,12 @@ static ssize_t gsi_print_dp_stats(struct file *file,
static ssize_t gsi_enable_ipc_low(struct file *file,
	const char __user *ubuf, size_t count, loff_t *ppos)
{
	unsigned long missing;
	s8 option = 0;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, ubuf, count);
	if (missing)
		return -EFAULT;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &option))
		return -EINVAL;
	ret = kstrtos8_from_user(ubuf, count, 0, &option);
	if (ret)
		return ret;

	mutex_lock(&gsi_ctx->mlock);
	if (option) {
+2 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/debugfs.h>
@@ -703,7 +703,7 @@ static ssize_t odu_debugfs_hw_bridge_mode_write(struct file *file,
	unsigned long missing;
	enum odu_bridge_mode mode;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		return -EFAULT;

	missing = copy_from_user(dbg_buff, ubuf, count);
+1 −1
Original line number Diff line number Diff line
@@ -4980,7 +4980,7 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf,

	char dbg_buff[32] = { 0 };

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		return -EFAULT;

	missing = copy_from_user(dbg_buff, buf, count);
+19 −61
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 */

#ifdef CONFIG_DEBUG_FS
@@ -144,7 +144,7 @@ static ssize_t ipa3_write_ep_holb(struct file *file,
	unsigned long missing;
	char *sptr, *token;

	if (sizeof(dbg_buff) < count + 1)
	if (count >= sizeof(dbg_buff))
		return -EFAULT;

	missing = copy_from_user(dbg_buff, buf, count);
@@ -184,19 +184,12 @@ static ssize_t ipa3_write_ep_holb(struct file *file,
static ssize_t ipa3_write_ep_reg(struct file *file, const char __user *buf,
		size_t count, loff_t *ppos)
{
	unsigned long missing;
	s8 option = 0;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, buf, count);
	if (missing)
		return -EFAULT;
	s8 option;
	int ret;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &option))
		return -EFAULT;
	ret = kstrtos8_from_user(buf, count, 0, &option);
	if (ret)
		return ret;

	if (option >= ipa3_ctx->ipa_num_pipes) {
		IPAERR("bad pipe specified %u\n", option);
@@ -322,19 +315,12 @@ static ssize_t ipa3_read_ep_reg(struct file *file, char __user *ubuf,
static ssize_t ipa3_write_keep_awake(struct file *file, const char __user *buf,
	size_t count, loff_t *ppos)
{
	unsigned long missing;
	s8 option = 0;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, buf, count);
	if (missing)
		return -EFAULT;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &option))
		return -EFAULT;
	ret = kstrtos8_from_user(buf, count, 0, &option);
	if (ret)
		return ret;

	if (option == 1)
		IPA_ACTIVE_CLIENTS_INC_SIMPLE();
@@ -1511,25 +1497,18 @@ static ssize_t ipa3_read_wdi(struct file *file, char __user *ubuf,
static ssize_t ipa3_write_dbg_cnt(struct file *file, const char __user *buf,
		size_t count, loff_t *ppos)
{
	unsigned long missing;
	u32 option = 0;
	struct ipahal_reg_debug_cnt_ctrl dbg_cnt_ctrl;
	int ret;

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		IPAERR("IPA_DEBUG_CNT_CTRL is not supported in IPA 4.0\n");
		return -EPERM;
	}

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, buf, count);
	if (missing)
		return -EFAULT;

	dbg_buff[count] = '\0';
	if (kstrtou32(dbg_buff, 0, &option))
		return -EFAULT;
	ret = kstrtou32_from_user(buf, count, 0, &option);
	if (ret)
		return ret;

	memset(&dbg_cnt_ctrl, 0, sizeof(dbg_cnt_ctrl));
	dbg_cnt_ctrl.type = DBG_CNT_TYPE_GENERAL;
@@ -2075,20 +2054,6 @@ static ssize_t ipa3_print_active_clients_log(struct file *file,
static ssize_t ipa3_clear_active_clients_log(struct file *file,
		const char __user *ubuf, size_t count, loff_t *ppos)
{
	unsigned long missing;
		s8 option = 0;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, ubuf, count);
	if (missing)
		return -EFAULT;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &option))
		return -EFAULT;

	ipa3_active_clients_log_clear();

	return count;
@@ -2097,19 +2062,12 @@ static ssize_t ipa3_clear_active_clients_log(struct file *file,
static ssize_t ipa3_enable_ipc_low(struct file *file,
	const char __user *ubuf, size_t count, loff_t *ppos)
{
	unsigned long missing;
	s8 option = 0;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, ubuf, count);
	if (missing)
		return -EFAULT;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &option))
		return -EFAULT;
	ret = kstrtos8_from_user(ubuf, count, 0, &option);
	if (ret)
		return ret;

	mutex_lock(&ipa3_ctx->lock);
	if (option) {
+4 −10
Original line number Diff line number Diff line
@@ -1186,19 +1186,13 @@ static ssize_t ipa3_dma_debugfs_reset_statistics(struct file *file,
					size_t count,
					loff_t *ppos)
{
	unsigned long missing;
	s8 in_num = 0;
	int ret;

	if (sizeof(dbg_buff) < count + 1)
		return -EFAULT;

	missing = copy_from_user(dbg_buff, ubuf, count);
	if (missing)
		return -EFAULT;
	ret = kstrtos8_from_user(ubuf, count, 0, &in_num);
	if (ret)
		return ret;

	dbg_buff[count] = '\0';
	if (kstrtos8(dbg_buff, 0, &in_num))
		return -EFAULT;
	switch (in_num) {
	case 0:
		if (ipa3_dma_work_pending())
Loading