Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");