summaryrefslogtreecommitdiff
path: root/samples/livepatch/livepatch-shadow-fix1.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-05-10 07:19:23 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-05-10 07:19:23 -0400
commit71db1cd7ff4ea3b525ae7d9c97633ea281b7d981 (patch)
tree53ff3b8ecfc2869ec919e3423d69e07ddfaddd9a /samples/livepatch/livepatch-shadow-fix1.c
parent7d95fb746c4eece67308f1642a666ea1ebdbd2cc (diff)
parent75bc37fefc4471e718ba8e651aa74673d4e0a9eb (diff)
Merge tag 'v4.17-rc4' into patchwork
Linux 4.17-rc4 * tag 'v4.17-rc4': (920 commits) Linux 4.17-rc4 KVM: x86: remove APIC Timer periodic/oneshot spikes genksyms: fix typo in parse.tab.{c,h} generation rules kbuild: replace hardcoded bison in cmd_bison_h with $(YACC) gcc-plugins: fix build condition of SANCOV plugin MAINTAINERS: Update Kbuild entry with a few paths Revert "usb: host: ehci: Use dma_pool_zalloc()" platform/x86: Kconfig: Fix dell-laptop dependency chain. platform/x86: asus-wireless: Fix NULL pointer dereference arm64: vgic-v2: Fix proxying of cpuif access KVM: arm/arm64: vgic_init: Cleanup reference to process_maintenance KVM: arm64: Fix order of vcpu_write_sys_reg() arguments MAINTAINERS & files: Canonize the e-mails I use at files media: imx-media-csi: Fix inconsistent IS_ERR and PTR_ERR tools: power/acpi, revert to LD = gcc bdi: Fix oops in wb_workfn() RDMA/cma: Do not query GID during QP state transition to RTR IB/mlx4: Fix integer overflow when calculating optimal MTT size IB/hfi1: Fix memory leak in exception path in get_irq_affinity() IB/{hfi1, rdmavt}: Fix memory leak in hfi1_alloc_devdata() upon failure ...
Diffstat (limited to 'samples/livepatch/livepatch-shadow-fix1.c')
-rw-r--r--samples/livepatch/livepatch-shadow-fix1.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/samples/livepatch/livepatch-shadow-fix1.c b/samples/livepatch/livepatch-shadow-fix1.c
index 830c55514f9f..49b13553eaae 100644
--- a/samples/livepatch/livepatch-shadow-fix1.c
+++ b/samples/livepatch/livepatch-shadow-fix1.c
@@ -56,6 +56,21 @@ struct dummy {
unsigned long jiffies_expire;
};
+/*
+ * 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.
+ */
+static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
+{
+ void **shadow_leak = shadow_data;
+ void *leak = ctor_data;
+
+ *shadow_leak = leak;
+ return 0;
+}
+
struct dummy *livepatch_fix1_dummy_alloc(void)
{
struct dummy *d;
@@ -74,7 +89,8 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
* pointer to handle resource release.
*/
leak = kzalloc(sizeof(int), GFP_KERNEL);
- klp_shadow_alloc(d, SV_LEAK, &leak, sizeof(leak), GFP_KERNEL);
+ klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
+ shadow_leak_ctor, leak);
pr_info("%s: dummy @ %p, expires @ %lx\n",
__func__, d, d->jiffies_expire);
@@ -82,9 +98,19 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
return d;
}
+static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
+{
+ void *d = obj;
+ void **shadow_leak = shadow_data;
+
+ kfree(*shadow_leak);
+ pr_info("%s: dummy @ %p, prevented leak @ %p\n",
+ __func__, d, *shadow_leak);
+}
+
void livepatch_fix1_dummy_free(struct dummy *d)
{
- void **shadow_leak, *leak;
+ void **shadow_leak;
/*
* Patch: fetch the saved SV_LEAK shadow variable, detach and
@@ -93,15 +119,10 @@ void livepatch_fix1_dummy_free(struct dummy *d)
* was loaded.)
*/
shadow_leak = klp_shadow_get(d, SV_LEAK);
- if (shadow_leak) {
- leak = *shadow_leak;
- klp_shadow_free(d, SV_LEAK);
- kfree(leak);
- pr_info("%s: dummy @ %p, prevented leak @ %p\n",
- __func__, d, leak);
- } else {
+ if (shadow_leak)
+ klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
+ else
pr_info("%s: dummy @ %p leaked!\n", __func__, d);
- }
kfree(d);
}
@@ -147,7 +168,7 @@ static int livepatch_shadow_fix1_init(void)
static void livepatch_shadow_fix1_exit(void)
{
/* Cleanup any existing SV_LEAK shadow variables */
- klp_shadow_free_all(SV_LEAK);
+ klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
WARN_ON(klp_unregister_patch(&patch));
}