~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/samples/livepatch/livepatch-shadow-fix2.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (C) 2017 Joe Lawrence <joe.lawrence@redhat.com>
  4  */
  5 
  6 /*
  7  * livepatch-shadow-fix2.c - Shadow variables, livepatch demo
  8  *
  9  * Purpose
 10  * -------
 11  *
 12  * Adds functionality to livepatch-shadow-mod's in-flight data
 13  * structures through a shadow variable.  The livepatch patches a
 14  * routine that periodically inspects data structures, incrementing a
 15  * per-data-structure counter, creating the counter if needed.
 16  *
 17  *
 18  * Usage
 19  * -----
 20  *
 21  * This module is not intended to be standalone.  See the "Usage"
 22  * section of livepatch-shadow-mod.c.
 23  */
 24 
 25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 26 
 27 #include <linux/module.h>
 28 #include <linux/kernel.h>
 29 #include <linux/livepatch.h>
 30 #include <linux/slab.h>
 31 
 32 /* Shadow variable enums */
 33 #define SV_LEAK         1
 34 #define SV_COUNTER      2
 35 
 36 struct dummy {
 37         struct list_head list;
 38         unsigned long jiffies_expire;
 39 };
 40 
 41 static bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
 42 {
 43         int *shadow_count;
 44 
 45         /*
 46          * Patch: handle in-flight dummy structures, if they do not
 47          * already have a SV_COUNTER shadow variable, then attach a
 48          * new one.
 49          */
 50         shadow_count = klp_shadow_get_or_alloc(d, SV_COUNTER,
 51                                 sizeof(*shadow_count), GFP_NOWAIT,
 52                                 NULL, NULL);
 53         if (shadow_count)
 54                 *shadow_count += 1;
 55 
 56         return time_after(jiffies, d->jiffies_expire);
 57 }
 58 
 59 static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
 60 {
 61         void *d = obj;
 62         int **shadow_leak = shadow_data;
 63 
 64         pr_info("%s: dummy @ %p, prevented leak @ %p\n",
 65                          __func__, d, *shadow_leak);
 66         kfree(*shadow_leak);
 67 }
 68 
 69 static void livepatch_fix2_dummy_free(struct dummy *d)
 70 {
 71         int **shadow_leak;
 72         int *shadow_count;
 73 
 74         /* Patch: copy the memory leak patch from the fix1 module. */
 75         shadow_leak = klp_shadow_get(d, SV_LEAK);
 76         if (shadow_leak)
 77                 klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor);
 78         else
 79                 pr_info("%s: dummy @ %p leaked!\n", __func__, d);
 80 
 81         /*
 82          * Patch: fetch the SV_COUNTER shadow variable and display
 83          * the final count.  Detach the shadow variable.
 84          */
 85         shadow_count = klp_shadow_get(d, SV_COUNTER);
 86         if (shadow_count) {
 87                 pr_info("%s: dummy @ %p, check counter = %d\n",
 88                         __func__, d, *shadow_count);
 89                 klp_shadow_free(d, SV_COUNTER, NULL);
 90         }
 91 
 92         kfree(d);
 93 }
 94 
 95 static struct klp_func funcs[] = {
 96         {
 97                 .old_name = "dummy_check",
 98                 .new_func = livepatch_fix2_dummy_check,
 99         },
100         {
101                 .old_name = "dummy_free",
102                 .new_func = livepatch_fix2_dummy_free,
103         }, { }
104 };
105 
106 static struct klp_object objs[] = {
107         {
108                 .name = "livepatch_shadow_mod",
109                 .funcs = funcs,
110         }, { }
111 };
112 
113 static struct klp_patch patch = {
114         .mod = THIS_MODULE,
115         .objs = objs,
116 };
117 
118 static int livepatch_shadow_fix2_init(void)
119 {
120         return klp_enable_patch(&patch);
121 }
122 
123 static void livepatch_shadow_fix2_exit(void)
124 {
125         /* Cleanup any existing SV_COUNTER shadow variables */
126         klp_shadow_free_all(SV_COUNTER, NULL);
127 }
128 
129 module_init(livepatch_shadow_fix2_init);
130 module_exit(livepatch_shadow_fix2_exit);
131 MODULE_LICENSE("GPL");
132 MODULE_INFO(livepatch, "Y");
133 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php