> Why do you want to store the target module src version in an elf > section, please? > Well, let me explain it again. Take fuse.ko as an example. Now, the running system have fuse.ko(v1) inside. I found fuse.ko(v1) have a bug, and try to fix it. fuse.ko(v1) have srcversion(src_v1) to tag its build. Now, I build an livepatch.ko for fuse.ko(v1). But how to make sure that this livepatch.ko will only patch the fuse.ko(v1)? ( Becase in other system, there may be fuse.ko(v2) or fuse.ko(v3) in the system. If this livepatch.ko patch to fuse.ko(v2) or fuse.ko(v3) may cause bugs.) To make sure this livepatch.ko will only patch the fuse.ko(v1), I can store the target srcversion of fuse.ko(v1) into the livepatch.ko. livepatch.ko now can carry its owner's information. When the system loading livepatch module, the system can know that this livepatch module can just only patch the target with srcversion(src_v1). And avoid the wrong patching. > IMHO, it would be much easier to store it in struct klp_object > as I proposed above. Then the check might be as simple as: > > diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h > index 51a258c24ff5..dfd7132eec4e 100644 > --- a/include/linux/livepatch.h > +++ b/include/linux/livepatch.h > @@ -104,6 +104,7 @@ struct klp_callbacks { > /** > * struct klp_object - kernel object structure for live patching > * @name: module name (or NULL for vmlinux) > + * @srcversion compactible srcversion (optional) > * @funcs: function entries for functions to be patched in the object > * @callbacks: functions to be executed pre/post (un)patching > * @kobj: kobject for sysfs resources > @@ -117,6 +118,7 @@ struct klp_callbacks { > struct klp_object { > /* external */ > const char *name; > + const char *srcversion; > struct klp_func *funcs; > struct klp_callbacks callbacks; > > diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c > index 0cd39954d5a1..61004502e72d 100644 > --- a/kernel/livepatch/core.c > +++ b/kernel/livepatch/core.c > @@ -66,6 +66,13 @@ static void klp_find_object_module(struct klp_object *obj) > * klp_module_going() instead. > */ > mod = find_module(obj->name); > + > + /* Do not livepatch an incompatible object. */ > + if (mod && obj->srcversion && mod->srcversion) { > + if (strcmp(obj->srcversion, mod->srcversion) != 0) > + goto out; > + } > + > /* > * Do not mess work of klp_module_coming() and klp_module_going(). > * Note that the patch might still be needed before klp_module_going() > @@ -75,7 +82,7 @@ static void klp_find_object_module(struct klp_object *obj) > */ > if (mod && mod->klp_alive) > obj->mod = mod; > - > +out: > rcu_read_unlock_sched(); > } > > The above code causes that the livepatch would ignore an incompatible > object. > > Maybe, you want to return an error instead and block the incompatible > module load. > Oh, I got your point. Because I usually use livepatch to fix problems point to point, it is rare that all fixes are put in one patch....lol... So, I admit my design have shortcomings, which is ignored the situation that one livepatch module can patch many functions in one module... >>> It would be optional. I made just a quick look. It might be enough >>> to check it in klp_find_object_module() and do not set obj->mod >>> when obj->srcversion != NULL and does not match mod->srcversion. >>> >>> Wait! We need to check it also in klp_write_section_relocs(). >>> Otherwise, klp_apply_section_relocs() might apply the relocations >>> for non-compatible module. >>> >> >> As previously mentioned, if we can check the srcversion when calling >> the syscall `init_module`, refuse to load the module if the livepatch >> module have srcversion and the srcversion is not equal to the target >> in the system. Can it avoid such relocations problem? > > Honestly, I am not sure what you mean by target module src version. > > Anyway, you could prevent the module load also when > klp_find_object_module() returns an error. > Well, my target module srcversion is the fuse.ko(v1) as previous mentioned. Is it clear now? > > I do not understand this urgument. > > vmlinux can be identified by build_id stored in "vmlinux_build_id". > > And modules can be identified by both build_id and srcversion. Both > information are stored in struct module. > > A single livepatch could modify more objects: vmlinux and several > modules. The metadata for each modified object are in "struct > klp_object". The related obect is currently identified only by obj->name. > And we could add more precision identification by setting > also "obj->srcversion" and/or "obj->build_id". > Yep, but how can we get the obj->srcversion? If we tring to store it in klp_object, the information should be carried when livepatch is being build. Otherwise, we don't know which srcversion is good to patch, isn't it? > > My understanding is that "srcversion" a kind of checksum of the > sources. I guess that it will be always the same for the sources. > I guess that it is not affected by the compiler or compiler options. > You are right, Petr. I made some tests on a module, and seems that srcversion depends on the source code. > But build_id should be unique with each rebuild. It should be > afftected by the compiler or compiler options. > > Note that the compiler options might affect how the functions are > opimized (inlining). And it might affect compactibility of the livepatch. IMHO, we just need to make sure the target version (using srcversion) is correct will be enough?