]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
libie: prevent memleak in fwlog code
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Wed, 11 Feb 2026 09:10:08 +0000 (10:10 +0100)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 17 Mar 2026 21:12:36 +0000 (14:12 -0700)
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: 96a9a9341cda ("ice: configure FW logging")
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/libie/fwlog.c

index 4d0c8370386bc7675da02cb261cb1c2a12540c46..96bba57c8a5b902ff82524f0d6168fa42c18e553 100644 (file)
@@ -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 @@ enable_write_error:
         */
        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 @@ log_size_write_error:
         */
        if (WARN_ON(ret != (ssize_t)count && ret >= 0))
                ret = -EIO;
+free_cmd_buf:
+       kfree(cmd_buf);
 
        return ret;
 }