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-fix2.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)  * Adds functionality to livepatch-shadow-mod's in-flight data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * structures through a shadow variable.  The livepatch patches a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * routine that periodically inspects data structures, incrementing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * per-data-structure counter, creating the counter if needed.
^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) #define SV_COUNTER	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct dummy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	unsigned long jiffies_expire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	int *shadow_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	 * Patch: handle in-flight dummy structures, if they do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 * already have a SV_COUNTER shadow variable, then attach a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	 * new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	shadow_count = klp_shadow_get_or_alloc(d, SV_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 				sizeof(*shadow_count), GFP_NOWAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 				NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (shadow_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		*shadow_count += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	return time_after(jiffies, d->jiffies_expire);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	void *d = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	int **shadow_leak = shadow_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	kfree(*shadow_leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	pr_info("%s: dummy @ %p, prevented leak @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			 __func__, d, *shadow_leak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static void livepatch_fix2_dummy_free(struct dummy *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int **shadow_leak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int *shadow_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	/* Patch: copy the memory leak patch from the fix1 module. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	shadow_leak = klp_shadow_get(d, SV_LEAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (shadow_leak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		pr_info("%s: dummy @ %p leaked!\n", __func__, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * Patch: fetch the SV_COUNTER shadow variable and display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * the final count.  Detach the shadow variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	shadow_count = klp_shadow_get(d, SV_COUNTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (shadow_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		pr_info("%s: dummy @ %p, check counter = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			__func__, d, *shadow_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		klp_shadow_free(d, SV_COUNTER, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	kfree(d);
^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) static struct klp_func funcs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.old_name = "dummy_check",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		.new_func = livepatch_fix2_dummy_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.old_name = "dummy_free",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		.new_func = livepatch_fix2_dummy_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}, { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static struct klp_object objs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		.name = "livepatch_shadow_mod",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		.funcs = funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}, { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct klp_patch patch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.mod = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	.objs = objs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int livepatch_shadow_fix2_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return klp_enable_patch(&patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void livepatch_shadow_fix2_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* Cleanup any existing SV_COUNTER shadow variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	klp_shadow_free_all(SV_COUNTER, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) module_init(livepatch_shadow_fix2_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) module_exit(livepatch_shadow_fix2_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) MODULE_INFO(livepatch, "Y");