Hello Jakub,
On Mon, Nov 18, 2024 at 06:33:36PM -0800, Jakub Kicinski wrote:
Sorry for the late review, I think this will miss v6.13 :(
That is fine, there is no rush for this change.
On Wed, 13 Nov 2024 07:10:53 -0800 Breno Leitao wrote:
/**
- struct netconsole_target - Represents a configured netconsole target.
- @list: Links this target into the target_list.
@@ -97,6 +105,7 @@ static struct console netconsole_ext;
- @userdata_group: Links to the userdata configfs hierarchy
- @userdata_complete: Cached, formatted string of append
- @userdata_length: String length of userdata_complete
- @userdata_auto: Kernel auto-populated bitwise fields in userdata.
- @enabled: On / off knob to enable / disable target.
Visible from userspace (read-write).
We maintain a strict 1:1 correspondence between this and
@@ -123,6 +132,7 @@ struct netconsole_target { struct config_group userdata_group; char userdata_complete[MAX_USERDATA_ENTRY_LENGTH * MAX_USERDATA_ITEMS]; size_t userdata_length;
- enum userdata_auto userdata_auto;
If you want to set multiple bits here type should probably be unsigned long. Otherwise the enum will contain combination of its values, which are in themselves not valid enum values ... if that makes sense.
Yes, it does make sense. I had the feeling that something was off as well, but I was unclear if using something different than `enum userdata_auto` would be better. I will change to `unsigned long`
#endif bool enabled; bool extended;
- /* Check if CPU NR should be populated, and append it to the user
* dictionary.
*/
- if (child_count < MAX_USERDATA_ITEMS && nt->userdata_auto & AUTO_CPU_NR)
scnprintf(&nt->userdata_complete[complete_idx],
MAX_USERDATA_ENTRY_LENGTH, " cpu=%u\n",
raw_smp_processor_id());
I guess it may be tricky for backward compat, but shouldn't we return an error rather than silently skip?
yes, this should be easy to do, in fact. Probably return -E2BIG to userspace when trying to update the entry. I thought about something as the following patch, and piggy-back into it.
Author: Breno Leitao leitao@debian.org Date: Tue Nov 19 04:32:56 2024 -0800
netconsole: Enforce userdata entry limit
Currently, attempting to add more than MAX_USERDATA_ITEMS to the userdata dictionary silently fails. This patch modifies the code to return -E2BIG when the number of elements exceeds the preallocated limit, providing clear feedback to userspace about the failure.
Suggested-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Breno Leitao leitao@debian.org
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4ea44a2f48f7b..41cff8c8e8f42 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -692,10 +692,11 @@ static ssize_t userdatum_value_show(struct config_item *item, char *buf) return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0])); }
-static void update_userdata(struct netconsole_target *nt) +static int update_userdata(struct netconsole_target *nt) { int complete_idx = 0, child_count = 0; struct list_head *entry; + int ret = 0;
/* Clear the current string in case the last userdatum was deleted */ nt->userdata_length = 0; @@ -705,8 +706,10 @@ static void update_userdata(struct netconsole_target *nt) struct userdatum *udm_item; struct config_item *item;
- if (child_count >= MAX_USERDATA_ITEMS) + if (child_count >= MAX_USERDATA_ITEMS) { + ret = -E2BIG; break; + } child_count++;
item = container_of(entry, struct config_item, ci_entry); @@ -726,6 +729,7 @@ static void update_userdata(struct netconsole_target *nt) } nt->userdata_length = strnlen(nt->userdata_complete, sizeof(nt->userdata_complete)); + return ret; }
static ssize_t userdatum_value_store(struct config_item *item, const char *buf, @@ -748,8 +752,9 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
ud = to_userdata(item->ci_parent); nt = userdata_to_target(ud); - update_userdata(nt); - ret = count; + ret = update_userdata(nt); + if (!ret) + ret = count; out_unlock: mutex_unlock(&dynamic_netconsole_mutex); return ret;
nt->userdata_length = strnlen(nt->userdata_complete, sizeof(nt->userdata_complete)); } @@ -757,7 +788,36 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf, return ret; } +static ssize_t populate_cpu_nr_store(struct config_item *item, const char *buf,
size_t count)
+{
- struct netconsole_target *nt = to_target(item->ci_parent);
- bool cpu_nr_enabled;
- ssize_t ret;
- if (!nt)
return -EINVAL;
Can this happen? Only if function gets called with a NULL @item which would be pretty nutty.
Probably not. It is just me being chicken here. I will remove it for the next version.
Thanks for the review, --breno