Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kobject: make uevent_seqnum atomic

We will soon no longer acquire uevent_sock_mutex
for most kobject_uevent_net_broadcast() calls,
and also while calling uevent_net_broadcast().

Make uevent_seqnum an atomic64_t to get its own protection.

This fixes a race while reading /sys/kernel/uevent_seqnum.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Christian Brauner <brauner@kernel.org>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Link: https://lore.kernel.org/r/20240214084829.684541-2-edumazet@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Eric Dumazet and committed by
Greg Kroah-Hartman
2444a80c 5df9197e

+11 -10
+1 -1
include/linux/kobject.h
··· 38 38 #endif 39 39 40 40 /* counter to tag the uevent, read only except for the kobject core */ 41 - extern u64 uevent_seqnum; 41 + extern atomic64_t uevent_seqnum; 42 42 43 43 /* 44 44 * The actions here must match the index to the string array
+1 -1
kernel/ksysfs.c
··· 39 39 static ssize_t uevent_seqnum_show(struct kobject *kobj, 40 40 struct kobj_attribute *attr, char *buf) 41 41 { 42 - return sysfs_emit(buf, "%llu\n", (unsigned long long)uevent_seqnum); 42 + return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&uevent_seqnum)); 43 43 } 44 44 KERNEL_ATTR_RO(uevent_seqnum); 45 45
+9 -8
lib/kobject_uevent.c
··· 30 30 #include <net/net_namespace.h> 31 31 32 32 33 - u64 uevent_seqnum; 33 + atomic64_t uevent_seqnum; 34 34 #ifdef CONFIG_UEVENT_HELPER 35 35 char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; 36 36 #endif ··· 44 44 static LIST_HEAD(uevent_sock_list); 45 45 #endif 46 46 47 - /* This lock protects uevent_seqnum and uevent_sock_list */ 47 + /* This lock protects uevent_sock_list */ 48 48 static DEFINE_MUTEX(uevent_sock_mutex); 49 49 50 50 /* the strings here must match the enum in include/linux/kobject.h */ ··· 583 583 break; 584 584 } 585 585 586 - mutex_lock(&uevent_sock_mutex); 587 586 /* we will send an event, so request a new sequence number */ 588 - retval = add_uevent_var(env, "SEQNUM=%llu", ++uevent_seqnum); 589 - if (retval) { 590 - mutex_unlock(&uevent_sock_mutex); 587 + retval = add_uevent_var(env, "SEQNUM=%llu", 588 + atomic64_inc_return(&uevent_seqnum)); 589 + if (retval) 591 590 goto exit; 592 - } 591 + 592 + mutex_lock(&uevent_sock_mutex); 593 593 retval = kobject_uevent_net_broadcast(kobj, env, action_string, 594 594 devpath); 595 595 mutex_unlock(&uevent_sock_mutex); ··· 688 688 int ret; 689 689 690 690 /* bump and prepare sequence number */ 691 - ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu", ++uevent_seqnum); 691 + ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu", 692 + atomic64_inc_return(&uevent_seqnum)); 692 693 if (ret < 0 || (size_t)ret >= sizeof(buf)) 693 694 return -ENOMEM; 694 695 ret++;