--- a/nss_rps.c +++ b/nss_rps.c @@ -70,7 +70,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; @@ -109,7 +109,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; @@ -119,13 +119,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; @@ -140,14 +137,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; @@ -407,7 +405,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; @@ -458,7 +456,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]; @@ -521,7 +519,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]; @@ -529,10 +527,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,13 +115,11 @@ 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 *str; char *tokens[NSS_DSCP_MAP_PARAM_FIELD_COUNT]; unsigned int dscp, priority, action; @@ -135,15 +133,14 @@ static int nss_dscp_map_parse(struct ctl 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, " ");