[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 06/30] lib: code tagging module support



Add support for code tagging from dynamically loaded modules.

Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>
Co-developed-by: Kent Overstreet <kent.overstreet@xxxxxxxxx>
Signed-off-by: Kent Overstreet <kent.overstreet@xxxxxxxxx>
---
 include/linux/codetag.h | 12 ++++++++++
 kernel/module/main.c    |  4 ++++
 lib/codetag.c           | 51 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/include/linux/codetag.h b/include/linux/codetag.h
index a9d7adecc2a5..386733e89b31 100644
--- a/include/linux/codetag.h
+++ b/include/linux/codetag.h
@@ -42,6 +42,10 @@ struct codetag_module {
 struct codetag_type_desc {
        const char *section;
        size_t tag_size;
+       void (*module_load)(struct codetag_type *cttype,
+                           struct codetag_module *cmod);
+       void (*module_unload)(struct codetag_type *cttype,
+                             struct codetag_module *cmod);
 };
 
 struct codetag_iterator {
@@ -68,4 +72,12 @@ void codetag_to_text(struct seq_buf *out, struct codetag 
*ct);
 struct codetag_type *
 codetag_register_type(const struct codetag_type_desc *desc);
 
+#ifdef CONFIG_CODE_TAGGING
+void codetag_load_module(struct module *mod);
+void codetag_unload_module(struct module *mod);
+#else
+static inline void codetag_load_module(struct module *mod) {}
+static inline void codetag_unload_module(struct module *mod) {}
+#endif
+
 #endif /* _LINUX_CODETAG_H */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index a4e4d84b6f4e..d253277492fd 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -53,6 +53,7 @@
 #include <linux/bsearch.h>
 #include <linux/dynamic_debug.h>
 #include <linux/audit.h>
+#include <linux/codetag.h>
 #include <uapi/linux/module.h>
 #include "internal.h"
 
@@ -1151,6 +1152,7 @@ static void free_module(struct module *mod)
 {
        trace_module_free(mod);
 
+       codetag_unload_module(mod);
        mod_sysfs_teardown(mod);
 
        /*
@@ -2849,6 +2851,8 @@ static int load_module(struct load_info *info, const char 
__user *uargs,
        /* Get rid of temporary copy. */
        free_copy(info, flags);
 
+       codetag_load_module(mod);
+
        /* Done! */
        trace_module_load(mod);
 
diff --git a/lib/codetag.c b/lib/codetag.c
index 7708f8388e55..f0a3174f9b71 100644
--- a/lib/codetag.c
+++ b/lib/codetag.c
@@ -157,8 +157,11 @@ static int codetag_module_init(struct codetag_type 
*cttype, struct module *mod)
 
        down_write(&cttype->mod_lock);
        err = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
-       if (err >= 0)
+       if (err >= 0) {
                cttype->count += range_size(cttype, &range);
+               if (cttype->desc.module_load)
+                       cttype->desc.module_load(cttype, cmod);
+       }
        up_write(&cttype->mod_lock);
 
        if (err < 0) {
@@ -197,3 +200,49 @@ codetag_register_type(const struct codetag_type_desc *desc)
 
        return cttype;
 }
+
+void codetag_load_module(struct module *mod)
+{
+       struct codetag_type *cttype;
+
+       if (!mod)
+               return;
+
+       mutex_lock(&codetag_lock);
+       list_for_each_entry(cttype, &codetag_types, link)
+               codetag_module_init(cttype, mod);
+       mutex_unlock(&codetag_lock);
+}
+
+void codetag_unload_module(struct module *mod)
+{
+       struct codetag_type *cttype;
+
+       if (!mod)
+               return;
+
+       mutex_lock(&codetag_lock);
+       list_for_each_entry(cttype, &codetag_types, link) {
+               struct codetag_module *found = NULL;
+               struct codetag_module *cmod;
+               unsigned long mod_id, tmp;
+
+               down_write(&cttype->mod_lock);
+               idr_for_each_entry_ul(&cttype->mod_idr, cmod, tmp, mod_id) {
+                       if (cmod->mod && cmod->mod == mod) {
+                               found = cmod;
+                               break;
+                       }
+               }
+               if (found) {
+                       if (cttype->desc.module_unload)
+                               cttype->desc.module_unload(cttype, cmod);
+
+                       cttype->count -= range_size(cttype, &cmod->range);
+                       idr_remove(&cttype->mod_idr, mod_id);
+                       kfree(cmod);
+               }
+               up_write(&cttype->mod_lock);
+       }
+       mutex_unlock(&codetag_lock);
+}
-- 
2.37.2.672.g94769d06f0-goog




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.