Commit 6850deb6 authored by Michal Swiatkowski's avatar Michal Swiatkowski Committed by Tony Nguyen
Browse files

libie: prevent memleak in fwlog code



All cmd_buf buffers are allocated and need to be freed after usage.
Add an error unwinding path that properly frees these buffers.

The memory leak happens whenever fwlog configuration is changed. For
example:

$echo 256K > /sys/kernel/debug/ixgbe/0000\:32\:00.0/fwlog/log_size

Fixes: 96a9a934 ("ice: configure FW logging")
Reviewed-by: default avatarAleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent fc9c69be
Loading
Loading
Loading
Loading
+36 −13
Original line number Diff line number Diff line
@@ -433,17 +433,21 @@ libie_debugfs_module_write(struct file *filp, const char __user *buf,
	module = libie_find_module_by_dentry(fwlog->debugfs_modules, dentry);
	if (module < 0) {
		dev_info(dev, "unknown module\n");
		return -EINVAL;
		count = -EINVAL;
		goto free_cmd_buf;
	}

	cnt = sscanf(cmd_buf, "%s", user_val);
	if (cnt != 1)
		return -EINVAL;
	if (cnt != 1) {
		count = -EINVAL;
		goto free_cmd_buf;
	}

	log_level = sysfs_match_string(libie_fwlog_level_string, user_val);
	if (log_level < 0) {
		dev_info(dev, "unknown log level '%s'\n", user_val);
		return -EINVAL;
		count = -EINVAL;
		goto free_cmd_buf;
	}

	if (module != LIBIE_AQC_FW_LOG_ID_MAX) {
@@ -458,6 +462,9 @@ libie_debugfs_module_write(struct file *filp, const char __user *buf,
			fwlog->cfg.module_entries[i].log_level = log_level;
	}

free_cmd_buf:
	kfree(cmd_buf);

	return count;
}

@@ -515,23 +522,31 @@ libie_debugfs_nr_messages_write(struct file *filp, const char __user *buf,
		return PTR_ERR(cmd_buf);

	ret = sscanf(cmd_buf, "%s", user_val);
	if (ret != 1)
		return -EINVAL;
	if (ret != 1) {
		count = -EINVAL;
		goto free_cmd_buf;
	}

	ret = kstrtos16(user_val, 0, &nr_messages);
	if (ret)
		return ret;
	if (ret) {
		count = ret;
		goto free_cmd_buf;
	}

	if (nr_messages < LIBIE_AQC_FW_LOG_MIN_RESOLUTION ||
	    nr_messages > LIBIE_AQC_FW_LOG_MAX_RESOLUTION) {
		dev_err(dev, "Invalid FW log number of messages %d, value must be between %d - %d\n",
			nr_messages, LIBIE_AQC_FW_LOG_MIN_RESOLUTION,
			LIBIE_AQC_FW_LOG_MAX_RESOLUTION);
		return -EINVAL;
		count = -EINVAL;
		goto free_cmd_buf;
	}

	fwlog->cfg.log_resolution = nr_messages;

free_cmd_buf:
	kfree(cmd_buf);

	return count;
}

@@ -588,8 +603,10 @@ libie_debugfs_enable_write(struct file *filp, const char __user *buf,
		return PTR_ERR(cmd_buf);

	ret = sscanf(cmd_buf, "%s", user_val);
	if (ret != 1)
		return -EINVAL;
	if (ret != 1) {
		ret = -EINVAL;
		goto free_cmd_buf;
	}

	ret = kstrtobool(user_val, &enable);
	if (ret)
@@ -624,6 +641,8 @@ libie_debugfs_enable_write(struct file *filp, const char __user *buf,
	 */
	if (WARN_ON(ret != (ssize_t)count && ret >= 0))
		ret = -EIO;
free_cmd_buf:
	kfree(cmd_buf);

	return ret;
}
@@ -682,8 +701,10 @@ libie_debugfs_log_size_write(struct file *filp, const char __user *buf,
		return PTR_ERR(cmd_buf);

	ret = sscanf(cmd_buf, "%s", user_val);
	if (ret != 1)
		return -EINVAL;
	if (ret != 1) {
		ret = -EINVAL;
		goto free_cmd_buf;
	}

	index = sysfs_match_string(libie_fwlog_log_size, user_val);
	if (index < 0) {
@@ -712,6 +733,8 @@ libie_debugfs_log_size_write(struct file *filp, const char __user *buf,
	 */
	if (WARN_ON(ret != (ssize_t)count && ret >= 0))
		ret = -EIO;
free_cmd_buf:
	kfree(cmd_buf);

	return ret;
}