^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Joe Lawrence <joe.lawrence@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * livepatch-shadow-fix1.c - Shadow variables, livepatch demo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * -------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Fixes the memory leak introduced in livepatch-shadow-mod through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * use of a shadow variable. This fix demonstrates the "extending" of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * short-lived data structures by patching its allocation and release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * This module is not intended to be standalone. See the "Usage"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * section of livepatch-shadow-mod.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/livepatch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Shadow variable enums */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SV_LEAK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Allocate new dummies every second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ALLOC_PERIOD 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Check for expired dummies after a few new ones have been allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CLEANUP_PERIOD (3 * ALLOC_PERIOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Dummies expire after a few cleanup instances */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define EXPIRE_PERIOD (4 * CLEANUP_PERIOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct dummy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned long jiffies_expire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * The constructor makes more sense together with klp_shadow_get_or_alloc().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * In this example, it would be safe to assign the pointer also to the shadow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * variable returned by klp_shadow_alloc(). But we wanted to show the more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * complicated use of the API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int **shadow_leak = shadow_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int **leak = ctor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (!ctor_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *shadow_leak = *leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static struct dummy *livepatch_fix1_dummy_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct dummy *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int *leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int **shadow_leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) d = kzalloc(sizeof(*d), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) d->jiffies_expire = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) msecs_to_jiffies(1000 * EXPIRE_PERIOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Patch: save the extra memory location into a SV_LEAK shadow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * variable. A patched dummy_free routine can later fetch this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * pointer to handle resource release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) leak = kzalloc(sizeof(*leak), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!leak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto err_leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) shadow_leak = klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) shadow_leak_ctor, &leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!shadow_leak) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pr_err("%s: failed to allocate shadow variable for the leaking pointer: dummy @ %p, leak @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __func__, d, leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto err_shadow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_info("%s: dummy @ %p, expires @ %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) __func__, d, d->jiffies_expire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) err_shadow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) kfree(leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err_leak:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void *d = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int **shadow_leak = shadow_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kfree(*shadow_leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pr_info("%s: dummy @ %p, prevented leak @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) __func__, d, *shadow_leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void livepatch_fix1_dummy_free(struct dummy *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int **shadow_leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Patch: fetch the saved SV_LEAK shadow variable, detach and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * free it. Note: handle cases where this shadow variable does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * not exist (ie, dummy structures allocated before this livepatch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * was loaded.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) shadow_leak = klp_shadow_get(d, SV_LEAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (shadow_leak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) pr_info("%s: dummy @ %p leaked!\n", __func__, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static struct klp_func funcs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .old_name = "dummy_alloc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .new_func = livepatch_fix1_dummy_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .old_name = "dummy_free",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .new_func = livepatch_fix1_dummy_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }, { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static struct klp_object objs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .name = "livepatch_shadow_mod",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .funcs = funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }, { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static struct klp_patch patch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .mod = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .objs = objs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int livepatch_shadow_fix1_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return klp_enable_patch(&patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static void livepatch_shadow_fix1_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Cleanup any existing SV_LEAK shadow variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) module_init(livepatch_shadow_fix1_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) module_exit(livepatch_shadow_fix1_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) MODULE_INFO(livepatch, "Y");