nss-packages-qosmio/qca-nss-drv/patches-11.4/0025-nss_rps-fix-procfs-read-write.patch
Sean Khan febe0256ca nss-drv: nss_rps: fix buff size when writing
Signed-off-by: Sean Khan <datapronix@protonmail.com>
2025-07-10 20:19:24 -04:00

206 lines
7.5 KiB
Diff

--- a/nss_rps.c
+++ b/nss_rps.c
@@ -67,7 +67,7 @@ static inline void nss_rps_pri_map_usage
* nss_rps_pri_map_print()
* Sysctl handler for printing rps/pri mapping.
*/
-static int nss_rps_pri_map_print(struct ctl_table *ctl, void __user *buffer,
+static int nss_rps_pri_map_print(void *buffer,
size_t *lenp, loff_t *ppos, int *pri_map)
{
char *r_buf;
@@ -106,7 +106,7 @@ static int nss_rps_pri_map_print(struct
len = scnprintf(r_buf + cp_bytes, 4, "\n");
cp_bytes += len;
- cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
+ cp_bytes = memory_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
*lenp = cp_bytes;
kfree(r_buf);
return 0;
@@ -116,13 +116,10 @@ static int nss_rps_pri_map_print(struct
* nss_rps_pri_map_parse()
* Sysctl handler for rps/pri mappings.
*/
-static int nss_rps_pri_map_parse(struct ctl_table *ctl, void __user *buffer,
- size_t *lenp, loff_t *ppos, struct nss_rps_pri_map_parse_data *out)
+static int nss_rps_pri_map_parse(void *buffer,
+ size_t *lenp, struct nss_rps_pri_map_parse_data *out)
{
- size_t cp_bytes = 0;
char w_buf[5];
- loff_t w_offset = 0;
- char *str;
unsigned int pri;
int core, res;
@@ -137,14 +134,15 @@ static int nss_rps_pri_map_parse(struct
/*
* It's a write operation
*/
- cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 5);
- if (cp_bytes != *lenp) {
- nss_warning("failed to write to buffer\n");
- return -EFAULT;
+ if (*lenp >= sizeof(w_buf)) {
+ nss_warning("Input too large: %zu\n", *lenp);
+ return -EINVAL;
}
- str = w_buf;
- res = sscanf(str, "%u %d", &pri, &core);
+ memcpy(w_buf, buffer, *lenp);
+ w_buf[*lenp] = '\0'; /* Ensure null termination */
+
+ res = sscanf(w_buf, "%u %d", &pri, &core);
if (res != NSS_RPS_PRI_MAP_PARAM_FIELD_COUNT) {
nss_warning("failed to read the buffer\n");
return -EFAULT;
@@ -404,7 +402,7 @@ static nss_tx_status_t nss_rps_pri_map_c
* Enable NSS RPS.
*/
static int nss_rps_cfg_handler(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+ void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx;
@@ -455,7 +453,7 @@ static int nss_rps_cfg_handler(struct ct
* Configure NSS rps_hash_bitmap
*/
static int nss_rps_hash_bitmap_cfg_handler(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+ void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx __attribute__((unused)) = &nss_top->nss[0];
@@ -518,7 +516,7 @@ static int nss_rps_hash_bitmap_cfg_handl
* Configure NSS rps_pri_map
*/
static int nss_rps_pri_map_cfg_handler(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+ void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
@@ -526,10 +524,10 @@ static int nss_rps_pri_map_cfg_handler(s
int ret, ret_pri_map;
struct nss_rps_pri_map_parse_data out, current_state;
if (!write) {
- return nss_rps_pri_map_print(ctl, buffer, lenp, ppos, nss_rps_pri_map);
+ return nss_rps_pri_map_print(buffer, lenp, ppos, nss_rps_pri_map);
}
- ret = nss_rps_pri_map_parse(ctl, buffer, lenp, ppos, &out);
+ ret = nss_rps_pri_map_parse(buffer, lenp, &out);
if (ret != NSS_SUCCESS) {
nss_rps_pri_map_usage();
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -595,7 +595,7 @@ void nss_ipv6_free_conn_tables(void)
* nss_ipv6_accel_mode_cfg_handler()
* Configure acceleration mode for IPv6
*/
-static int nss_ipv6_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+static int nss_ipv6_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
@@ -639,7 +639,7 @@ static int nss_ipv6_accel_mode_cfg_handl
* nss_ipv6_dscp_map_cfg_handler()
* Sysctl handler for dscp/pri mappings.
*/
-static int nss_ipv6_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+static int nss_ipv6_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -599,7 +599,7 @@ void nss_ipv4_free_conn_tables(void)
* nss_ipv4_accel_mode_cfg_handler()
* Configure acceleration mode for IPv4
*/
-static int nss_ipv4_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+static int nss_ipv4_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
@@ -643,7 +643,7 @@ static int nss_ipv4_accel_mode_cfg_handl
* nss_ipv4_dscp_map_cfg_handler()
* Sysctl handler for dscp/pri mappings.
*/
-static int nss_ipv4_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+static int nss_ipv4_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
--- a/nss_dscp_map.h
+++ b/nss_dscp_map.h
@@ -46,7 +46,7 @@ struct nss_dscp_map_parse {
* nss_dscp_map_print()
* Sysctl handler for printing dscp/pri mapping.
*/
-static int nss_dscp_map_print(struct ctl_table *ctl, void __user *buffer, size_t *lenp,
+static int nss_dscp_map_print(struct ctl_table *ctl, void *buffer, size_t *lenp,
loff_t *ppos, struct nss_dscp_map_entry *mapping)
{
char *r_buf;
@@ -105,7 +105,7 @@ static int nss_dscp_map_print(struct ctl
len = scnprintf(r_buf + cp_bytes, 4, "\n");
cp_bytes += len;
- cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
+ cp_bytes = memory_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
*lenp = cp_bytes;
kfree(r_buf);
return 0;
@@ -115,35 +115,32 @@ static int nss_dscp_map_print(struct ctl
* nss_dscp_map_parse()
* Sysctl handler for dscp/pri mappings.
*/
-static int nss_dscp_map_parse(struct ctl_table *ctl, void __user *buffer, size_t *lenp,
+static int nss_dscp_map_parse(struct ctl_table *ctl, void *buffer, size_t *lenp,
loff_t *ppos, struct nss_dscp_map_parse *out)
{
int count;
- size_t cp_bytes = 0;
- char w_buf[7];
- loff_t w_offset = 0;
+ char w_buf[8];
char *str;
char *tokens[NSS_DSCP_MAP_PARAM_FIELD_COUNT];
unsigned int dscp, priority, action;
int ret;
/*
- * Buffer length cannot be more than 7 and less than 6.
+ * Buffer length cannot be more than 8 and less than 6.
*/
- if (*lenp < 6 || *lenp > 7) {
- nss_warning("Buffer is not correct. Invalid lenght: %d\n", (int)*lenp);
+ if (*lenp < 6 || *lenp > 8) {
+ nss_warning("Invalid length: %d\n", (int)*lenp);
return -EINVAL;
}
- /*
- * It's a write operation
- */
- cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 7);
- if (cp_bytes != *lenp) {
- nss_warning("failed to write to buffer\n");
- return -EFAULT;
+ if (*lenp >= sizeof(w_buf)) {
+ nss_warning("Input too large: %zu\n", *lenp);
+ return -EINVAL;
}
+ memcpy(w_buf, buffer, *lenp);
+ w_buf[*lenp] = '\0'; /* Ensure null termination */
+
count = 0;
str = w_buf;
tokens[count] = strsep(&str, " ");