// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2017 Joe Lawrence <joe.lawrence@redhat.com>
*/
/* * livepatch-shadow-fix1.c - Shadow variables, livepatch demo * * Purpose * ------- * * Fixes the memory leak introduced in livepatch-shadow-mod through the * use of a shadow variable. This fix demonstrates the "extending" of * short-lived data structures by patching its allocation and release * functions. * * * Usage * ----- * * This module is not intended to be standalone. See the "Usage" * section of livepatch-shadow-mod.c.
*/
/* Allocate new dummies every second */ #define ALLOC_PERIOD 1 /* Check for expired dummies after a few new ones have been allocated */ #define CLEANUP_PERIOD (3 * ALLOC_PERIOD) /* Dummies expire after a few cleanup instances */ #define EXPIRE_PERIOD (4 * CLEANUP_PERIOD)
/* * The constructor makes more sense together with klp_shadow_get_or_alloc(). * In this example, it would be safe to assign the pointer also to the shadow * variable returned by klp_shadow_alloc(). But we wanted to show the more * complicated use of the API.
*/ staticint shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
{ int **shadow_leak = shadow_data; int **leak = ctor_data;
if (!ctor_data) return -EINVAL;
*shadow_leak = *leak; return 0;
}
staticstruct dummy *livepatch_fix1_dummy_alloc(void)
{ struct dummy *d; int *leak; int **shadow_leak;
d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) return NULL;
/* * Patch: save the extra memory location into a SV_LEAK shadow * variable. A patched dummy_free routine can later fetch this * pointer to handle resource release.
*/
leak = kzalloc(sizeof(*leak), GFP_KERNEL); if (!leak) goto err_leak;
shadow_leak = klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
shadow_leak_ctor, &leak); if (!shadow_leak) {
pr_err("%s: failed to allocate shadow variable for the leaking pointer: dummy @ %p, leak @ %p\n",
__func__, d, leak); goto err_shadow;
}
staticvoid livepatch_fix1_dummy_free(struct dummy *d)
{ int **shadow_leak;
/* * Patch: fetch the saved SV_LEAK shadow variable, detach and * free it. Note: handle cases where this shadow variable does * not exist (ie, dummy structures allocated before this livepatch * was loaded.)
*/
shadow_leak = klp_shadow_get(d, SV_LEAK); if (shadow_leak)
klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor); else
pr_info("%s: dummy @ %p leaked!\n", __func__, d);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.