From a3692762e9240a5eb9f9160f5ecdfaed52bef711 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Thu, 17 Apr 2025 22:55:00 -0400 Subject: [PATCH] nss-clients: nss_match fix read/write procfs files More fixes to read/write procfs files in nss_match. Signed-off-by: Sean Khan --- .../0033-match-fix-procfs-read-write.patch | 406 ++++++++++++++++++ .../0033-match-fix-procfs-read-write.patch | 406 ++++++++++++++++++ 2 files changed, 812 insertions(+) create mode 100644 qca-nss-clients/patches-11.4/0033-match-fix-procfs-read-write.patch create mode 100644 qca-nss-clients/patches/0033-match-fix-procfs-read-write.patch diff --git a/qca-nss-clients/patches-11.4/0033-match-fix-procfs-read-write.patch b/qca-nss-clients/patches-11.4/0033-match-fix-procfs-read-write.patch new file mode 100644 index 0000000..4504be5 --- /dev/null +++ b/qca-nss-clients/patches-11.4/0033-match-fix-procfs-read-write.patch @@ -0,0 +1,406 @@ +--- a/match/nss_match_cmd.c ++++ b/match/nss_match_cmd.c +@@ -127,29 +127,30 @@ static enum nss_match_profile_type nss_m + static int nss_match_cmd_procfs_config_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) + { + char *command_str, *token, *param, *value; +- char *input_msg, *input_msg_orig; ++ char *input_msg, *pos; + nss_match_cmd_t command; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + size_t count = *lenp; + int ret = proc_dostring(ctl, write, buffer, lenp, ppos); ++ char cmd_buf[100] = {0}; /* Use a fixed buffer size matching nss_match_data */ + + if (!write) { + return ret; + } + +- input_msg = (char *)kzalloc(count + 1, GFP_KERNEL); +- if (!input_msg) { +- nss_match_warn("%px: Dynamic allocation falied while writing input message from file", ctl); +- return -ENOMEM; ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; + } + +- input_msg_orig = input_msg; +- if (copy_from_user(input_msg, buffer, count)) { +- kfree(input_msg); +- nss_match_warn("%px: Cannot copy user's entry to kernel memory\n", ctl); +- return -EFAULT; ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; + } + ++ input_msg = cmd_buf; + command_str = strsep(&input_msg, " "); + command = nss_match_cmd_parse(command_str); + +@@ -161,20 +162,17 @@ static int nss_match_cmd_procfs_config_h + profile_type = nss_match_cmd_get_profile_type(input_msg); + if (profile_type == NSS_MATCH_PROFILE_TYPE_NONE) { + pr_warn("%px: Please provide a valid profile type\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + + table_id = nss_match_instance_create(); + if (table_id <= 0) { + pr_warn("%px: Cannot create a new match instance\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + + nss_match_db_profile_type_add(profile_type, table_id); + pr_warn("%px: New match instance created, table_id = %d\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -194,32 +192,27 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_table_validate(table_id)) { + pr_warn("%px: Table is already configured, %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_parse_cmd(table_id, input_msg, &input_mask_param, NSS_MATCH_ADD_MASK)) { +- kfree(input_msg_orig); + return -EINVAL; + } + + nss_match_db_mask_add(&input_mask_param.msg.configure_msg, table_id); + pr_warn("%px: Mask added to instance successfully. %d", ctl, table_id); + +- kfree(input_msg_orig); + return count; + } + +@@ -240,43 +233,36 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if ((table_id == 0) || (table_id > NSS_MATCH_INSTANCE_MAX)) { + pr_warn("%px: Invalid table_id %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_table_validate(table_id)) { + pr_warn("%px: Table is already configured, %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (!nss_match_db_instance_config_get(&config_msg, &if_num, table_id)) { + pr_warn("%px: Unable to fetch stored configuration %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (if_num < 0) { + nss_match_warn("%px: Incorrect interface number: %d\n", ctl, if_num); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_cmd_enable_instance(&config_msg, if_num, table_id)) { + pr_warn("%px: Failed to enable table %d\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Table %d enabled successfully\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -298,14 +284,12 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + +@@ -313,7 +297,6 @@ static int nss_match_cmd_procfs_config_h + + if (nss_match_db_parse_cmd(table_id, input_msg, &input_rule_param, NSS_MATCH_ADD_RULE)) { + pr_warn("%px: Wrong input", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + +@@ -325,12 +308,10 @@ static int nss_match_cmd_procfs_config_h + + if (rule_id < 0) { + pr_warn("%px: Failed to add rule into table %d.\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Rule added to table %d successfully with rule_id: %d\n", ctl, table_id, rule_id); +- kfree(input_msg_orig); + return count; + } + +@@ -352,7 +333,6 @@ static int nss_match_cmd_procfs_config_h + if (!(strncasecmp(param, "rule_id", strlen("rule_id")))) { + if (!sscanf(token, "%hu", &rule_id)) { + pr_warn("%px: Cannot convert to integer. Wrong input\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + continue; +@@ -361,36 +341,30 @@ static int nss_match_cmd_procfs_config_h + if (!strncasecmp(param, "table_id", strlen("table_id"))) { + if (!sscanf(token, "%u", &table_id)) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + continue; + } + +- kfree(input_msg_orig); + return -EINVAL; + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (rule_id == 0 || rule_id > NSS_MATCH_INSTANCE_RULE_MAX) { + pr_warn("%px: Invalid rule_id: %d", ctl, rule_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_rule_delete(nss_ctx, rule_id, table_id)) { + pr_warn("%px: Failed to delete rule from table %d.\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Rule deleted from table %d successfully\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -410,39 +384,33 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(token, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", input_msg); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_instance_destroy(table_id)) { + pr_warn("%px: Failed to destroy table %d\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Table %d destroyed successfully.\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + + default: + { + pr_warn("%px: Input command is not as per syntax, Please enter a valid command", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + fail: + pr_warn("%px: Wrong input, check help. (cat /proc/sys/dev/nss/match/help)", ctl); +- kfree(input_msg_orig); + return ret; + + } +@@ -456,11 +424,12 @@ static int nss_match_cmd_procfs_reset_ne + struct net_device *dev; + uint32_t if_num, type = 0; + int ret; +- char *dev_name; +- char *cmd_buf = nss_match_data; ++ char *pos; ++ char cmd_buf[IFNAMSIZ] = {0}; + nss_tx_status_t nss_tx_status; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + struct nss_ctx_instance *wifili_nss_ctx = nss_wifili_get_context(); ++ size_t count = *lenp; + + if (!nss_ctx || !wifili_nss_ctx) { + pr_warn("%px: NSS Context not found. wifili_nss_ctx: %px. Reset nexthop failed", nss_ctx, wifili_nss_ctx); +@@ -473,19 +442,30 @@ static int nss_match_cmd_procfs_reset_ne + return ret; + } + ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; ++ } ++ ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; ++ } ++ + /* + * Parse and read the devname from command. + */ +- dev_name = strsep(&cmd_buf, "\0"); +- dev = dev_get_by_name(&init_net, dev_name); ++ dev = dev_get_by_name(&init_net, cmd_buf); + if (!dev) { +- pr_warn("%px: Cannot find the net device: %s. Reset nexthop failed.\n", nss_ctx, dev_name); ++ pr_warn("%px: Cannot find the net device: %s. Reset nexthop failed.\n", nss_ctx, cmd_buf); + return -ENODEV; + } + + if_num = nss_cmn_get_interface_number_by_dev(dev); + if (if_num < 0) { +- pr_warn("%px: Invalid if_num for interface: %s. Reset nexthop failed.\n", nss_ctx, dev_name); ++ pr_warn("%px: Invalid if_num for interface: %s. Reset nexthop failed.\n", nss_ctx, cmd_buf); + dev_put(dev); + return -ENODEV; + } +@@ -529,7 +509,7 @@ static int nss_match_cmd_procfs_set_if_n + int table_id; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + struct nss_ctx_instance *wifili_nss_ctx = nss_wifili_get_context(); +- char *dev_name, *nexthop_msg; ++ char *dev_name, *pos; + char *cmd_buf = NULL; + size_t count = *lenp; + nss_tx_status_t nss_tx_status; +@@ -544,31 +524,28 @@ static int nss_match_cmd_procfs_set_if_n + return -ENOMEM; + } + +- cmd_buf = (char *)kzalloc(count + 1, GFP_KERNEL); +- nexthop_msg = cmd_buf; +- if (!cmd_buf) { +- pr_warn("%px: Cannot allocate buffer to read input", nss_ctx); +- return -ENOMEM; ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; + } + +- if (copy_from_user(cmd_buf, buffer, count)) { +- kfree(nexthop_msg); +- pr_warn("%px: Cannot copy user's entry to kernel memory\n", nss_ctx); +- return -EFAULT; ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; + } + + dev_name = strsep(&cmd_buf, " "); + dev = dev_get_by_name(&init_net, dev_name); + if (!dev) { + pr_warn("%px: Cannot find the net device\n", nss_ctx); +- kfree(nexthop_msg); + return -ENODEV; + } + + if_num = nss_cmn_get_interface_number_by_dev(dev); + if (if_num < 0) { + pr_warn("%px: Invalid interface number:%d\n", nss_ctx, if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } +@@ -576,20 +553,17 @@ static int nss_match_cmd_procfs_set_if_n + if (isdigit(cmd_buf[0])) { + if (!sscanf(cmd_buf, "%u", &nh_if_num)) { + pr_warn("%px, Failed to write the nexthop if_num token to integer\n", nss_ctx); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } + } else { + pr_warn("%px: Invalid nexthop interface number.\n", nss_ctx); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } + + if (nh_if_num < 0) { + pr_warn("%px: Invalid nexthop interface number:%d\n", nss_ctx, if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } +@@ -597,7 +571,6 @@ static int nss_match_cmd_procfs_set_if_n + table_id = nss_match_get_table_id_by_ifnum(nh_if_num); + if (table_id <= 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("Invalid match interface. Failed to set %d as nexthop.\n", nh_if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } +@@ -614,7 +587,6 @@ static int nss_match_cmd_procfs_set_if_n + nss_tx_status = nss_phys_if_set_nexthop(nss_ctx, if_num, nh_if_num); + } else { + pr_warn("Invalid interface to set nexthop. Failed to set nexthop on if_num %d.\n", if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } +@@ -623,7 +595,6 @@ static int nss_match_cmd_procfs_set_if_n + pr_warn("%px: Sending message failed, cannot change nexthop\n", nss_ctx); + } + +- kfree(nexthop_msg); + dev_put(dev); + return ret; + } diff --git a/qca-nss-clients/patches/0033-match-fix-procfs-read-write.patch b/qca-nss-clients/patches/0033-match-fix-procfs-read-write.patch new file mode 100644 index 0000000..4504be5 --- /dev/null +++ b/qca-nss-clients/patches/0033-match-fix-procfs-read-write.patch @@ -0,0 +1,406 @@ +--- a/match/nss_match_cmd.c ++++ b/match/nss_match_cmd.c +@@ -127,29 +127,30 @@ static enum nss_match_profile_type nss_m + static int nss_match_cmd_procfs_config_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) + { + char *command_str, *token, *param, *value; +- char *input_msg, *input_msg_orig; ++ char *input_msg, *pos; + nss_match_cmd_t command; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + size_t count = *lenp; + int ret = proc_dostring(ctl, write, buffer, lenp, ppos); ++ char cmd_buf[100] = {0}; /* Use a fixed buffer size matching nss_match_data */ + + if (!write) { + return ret; + } + +- input_msg = (char *)kzalloc(count + 1, GFP_KERNEL); +- if (!input_msg) { +- nss_match_warn("%px: Dynamic allocation falied while writing input message from file", ctl); +- return -ENOMEM; ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; + } + +- input_msg_orig = input_msg; +- if (copy_from_user(input_msg, buffer, count)) { +- kfree(input_msg); +- nss_match_warn("%px: Cannot copy user's entry to kernel memory\n", ctl); +- return -EFAULT; ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; + } + ++ input_msg = cmd_buf; + command_str = strsep(&input_msg, " "); + command = nss_match_cmd_parse(command_str); + +@@ -161,20 +162,17 @@ static int nss_match_cmd_procfs_config_h + profile_type = nss_match_cmd_get_profile_type(input_msg); + if (profile_type == NSS_MATCH_PROFILE_TYPE_NONE) { + pr_warn("%px: Please provide a valid profile type\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + + table_id = nss_match_instance_create(); + if (table_id <= 0) { + pr_warn("%px: Cannot create a new match instance\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + + nss_match_db_profile_type_add(profile_type, table_id); + pr_warn("%px: New match instance created, table_id = %d\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -194,32 +192,27 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_table_validate(table_id)) { + pr_warn("%px: Table is already configured, %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_parse_cmd(table_id, input_msg, &input_mask_param, NSS_MATCH_ADD_MASK)) { +- kfree(input_msg_orig); + return -EINVAL; + } + + nss_match_db_mask_add(&input_mask_param.msg.configure_msg, table_id); + pr_warn("%px: Mask added to instance successfully. %d", ctl, table_id); + +- kfree(input_msg_orig); + return count; + } + +@@ -240,43 +233,36 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if ((table_id == 0) || (table_id > NSS_MATCH_INSTANCE_MAX)) { + pr_warn("%px: Invalid table_id %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_db_table_validate(table_id)) { + pr_warn("%px: Table is already configured, %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (!nss_match_db_instance_config_get(&config_msg, &if_num, table_id)) { + pr_warn("%px: Unable to fetch stored configuration %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (if_num < 0) { + nss_match_warn("%px: Incorrect interface number: %d\n", ctl, if_num); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_cmd_enable_instance(&config_msg, if_num, table_id)) { + pr_warn("%px: Failed to enable table %d\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Table %d enabled successfully\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -298,14 +284,12 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(value, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + +@@ -313,7 +297,6 @@ static int nss_match_cmd_procfs_config_h + + if (nss_match_db_parse_cmd(table_id, input_msg, &input_rule_param, NSS_MATCH_ADD_RULE)) { + pr_warn("%px: Wrong input", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + +@@ -325,12 +308,10 @@ static int nss_match_cmd_procfs_config_h + + if (rule_id < 0) { + pr_warn("%px: Failed to add rule into table %d.\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Rule added to table %d successfully with rule_id: %d\n", ctl, table_id, rule_id); +- kfree(input_msg_orig); + return count; + } + +@@ -352,7 +333,6 @@ static int nss_match_cmd_procfs_config_h + if (!(strncasecmp(param, "rule_id", strlen("rule_id")))) { + if (!sscanf(token, "%hu", &rule_id)) { + pr_warn("%px: Cannot convert to integer. Wrong input\n", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + continue; +@@ -361,36 +341,30 @@ static int nss_match_cmd_procfs_config_h + if (!strncasecmp(param, "table_id", strlen("table_id"))) { + if (!sscanf(token, "%u", &table_id)) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + continue; + } + +- kfree(input_msg_orig); + return -EINVAL; + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (rule_id == 0 || rule_id > NSS_MATCH_INSTANCE_RULE_MAX) { + pr_warn("%px: Invalid rule_id: %d", ctl, rule_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_rule_delete(nss_ctx, rule_id, table_id)) { + pr_warn("%px: Failed to delete rule from table %d.\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Rule deleted from table %d successfully\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + +@@ -410,39 +384,33 @@ static int nss_match_cmd_procfs_config_h + ret = sscanf(token, "%u", &table_id); + if (!ret) { + pr_warn("%px: Cannot convert to integer. Wrong input!!", input_msg); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + if (table_id == 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("%px: Invalid table_id: %d", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + if (nss_match_instance_destroy(table_id)) { + pr_warn("%px: Failed to destroy table %d\n", ctl, table_id); +- kfree(input_msg_orig); + return -EINVAL; + } + + pr_warn("%px: Table %d destroyed successfully.\n", ctl, table_id); +- kfree(input_msg_orig); + return count; + } + + default: + { + pr_warn("%px: Input command is not as per syntax, Please enter a valid command", ctl); +- kfree(input_msg_orig); + return -EINVAL; + } + } + + fail: + pr_warn("%px: Wrong input, check help. (cat /proc/sys/dev/nss/match/help)", ctl); +- kfree(input_msg_orig); + return ret; + + } +@@ -456,11 +424,12 @@ static int nss_match_cmd_procfs_reset_ne + struct net_device *dev; + uint32_t if_num, type = 0; + int ret; +- char *dev_name; +- char *cmd_buf = nss_match_data; ++ char *pos; ++ char cmd_buf[IFNAMSIZ] = {0}; + nss_tx_status_t nss_tx_status; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + struct nss_ctx_instance *wifili_nss_ctx = nss_wifili_get_context(); ++ size_t count = *lenp; + + if (!nss_ctx || !wifili_nss_ctx) { + pr_warn("%px: NSS Context not found. wifili_nss_ctx: %px. Reset nexthop failed", nss_ctx, wifili_nss_ctx); +@@ -473,19 +442,30 @@ static int nss_match_cmd_procfs_reset_ne + return ret; + } + ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; ++ } ++ ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; ++ } ++ + /* + * Parse and read the devname from command. + */ +- dev_name = strsep(&cmd_buf, "\0"); +- dev = dev_get_by_name(&init_net, dev_name); ++ dev = dev_get_by_name(&init_net, cmd_buf); + if (!dev) { +- pr_warn("%px: Cannot find the net device: %s. Reset nexthop failed.\n", nss_ctx, dev_name); ++ pr_warn("%px: Cannot find the net device: %s. Reset nexthop failed.\n", nss_ctx, cmd_buf); + return -ENODEV; + } + + if_num = nss_cmn_get_interface_number_by_dev(dev); + if (if_num < 0) { +- pr_warn("%px: Invalid if_num for interface: %s. Reset nexthop failed.\n", nss_ctx, dev_name); ++ pr_warn("%px: Invalid if_num for interface: %s. Reset nexthop failed.\n", nss_ctx, cmd_buf); + dev_put(dev); + return -ENODEV; + } +@@ -529,7 +509,7 @@ static int nss_match_cmd_procfs_set_if_n + int table_id; + struct nss_ctx_instance *nss_ctx = nss_match_get_context(); + struct nss_ctx_instance *wifili_nss_ctx = nss_wifili_get_context(); +- char *dev_name, *nexthop_msg; ++ char *dev_name, *pos; + char *cmd_buf = NULL; + size_t count = *lenp; + nss_tx_status_t nss_tx_status; +@@ -544,31 +524,28 @@ static int nss_match_cmd_procfs_set_if_n + return -ENOMEM; + } + +- cmd_buf = (char *)kzalloc(count + 1, GFP_KERNEL); +- nexthop_msg = cmd_buf; +- if (!cmd_buf) { +- pr_warn("%px: Cannot allocate buffer to read input", nss_ctx); +- return -ENOMEM; ++ if (count >= sizeof(cmd_buf)) { ++ nss_match_warn("%px: Input too large: %zu\n", ctl, count); ++ return -EINVAL; + } + +- if (copy_from_user(cmd_buf, buffer, count)) { +- kfree(nexthop_msg); +- pr_warn("%px: Cannot copy user's entry to kernel memory\n", nss_ctx); +- return -EFAULT; ++ memcpy(cmd_buf, buffer, count); ++ cmd_buf[count] = '\0'; /* Ensure null termination */ ++ ++ if ((pos = strrchr(cmd_buf, '\n')) != NULL) { ++ *pos = '\0'; + } + + dev_name = strsep(&cmd_buf, " "); + dev = dev_get_by_name(&init_net, dev_name); + if (!dev) { + pr_warn("%px: Cannot find the net device\n", nss_ctx); +- kfree(nexthop_msg); + return -ENODEV; + } + + if_num = nss_cmn_get_interface_number_by_dev(dev); + if (if_num < 0) { + pr_warn("%px: Invalid interface number:%d\n", nss_ctx, if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } +@@ -576,20 +553,17 @@ static int nss_match_cmd_procfs_set_if_n + if (isdigit(cmd_buf[0])) { + if (!sscanf(cmd_buf, "%u", &nh_if_num)) { + pr_warn("%px, Failed to write the nexthop if_num token to integer\n", nss_ctx); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } + } else { + pr_warn("%px: Invalid nexthop interface number.\n", nss_ctx); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } + + if (nh_if_num < 0) { + pr_warn("%px: Invalid nexthop interface number:%d\n", nss_ctx, if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -ENODEV; + } +@@ -597,7 +571,6 @@ static int nss_match_cmd_procfs_set_if_n + table_id = nss_match_get_table_id_by_ifnum(nh_if_num); + if (table_id <= 0 || table_id > NSS_MATCH_INSTANCE_MAX) { + pr_warn("Invalid match interface. Failed to set %d as nexthop.\n", nh_if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } +@@ -614,7 +587,6 @@ static int nss_match_cmd_procfs_set_if_n + nss_tx_status = nss_phys_if_set_nexthop(nss_ctx, if_num, nh_if_num); + } else { + pr_warn("Invalid interface to set nexthop. Failed to set nexthop on if_num %d.\n", if_num); +- kfree(nexthop_msg); + dev_put(dev); + return -EFAULT; + } +@@ -623,7 +595,6 @@ static int nss_match_cmd_procfs_set_if_n + pr_warn("%px: Sending message failed, cannot change nexthop\n", nss_ctx); + } + +- kfree(nexthop_msg); + dev_put(dev); + return ret; + }