Re: [PATCH v10 00/10] livepatch: Atomic replace feature

2018-03-12 Thread Joe Lawrence
Hi Petr,

These are the callback tests that I hacked up into a livepatch
kselftest.  (Basically I copied a bunch of the sample modules and
verified the expected dmesg output as I had listed in in the
Documentation/livepatch/callbacks.txt file.)  The script is still a
little rough and maybe this isn't the direction we want to go for proper
kselftests, but perhaps it saves you some time/sanity for verifying this
patchset.

Hope this helps,

-- Joe

-- >8 -- >8 -- >8 -- >8 --

>From 0364430c53e12e21923bed20cb651374b4cf9ba9 Mon Sep 17 00:00:00 2001
From: Joe Lawrence 
Date: Tue, 6 Mar 2018 17:32:25 -0500
Subject: WIP - livepatch kselftest

CONFIG_TEST_LIVEPATCH=m
% make -C tools/testing/selftests TARGETS=livepatch run_tests

Signed-off-by: Joe Lawrence 
---
 lib/Kconfig.debug|  11 +
 lib/Makefile |   9 +
 lib/test_klp_callbacks_busy.c|  58 ++
 lib/test_klp_callbacks_demo.c| 205 +++
 lib/test_klp_callbacks_demo2.c   | 149 +
 lib/test_klp_callbacks_mod.c |  39 ++
 tools/testing/selftests/Makefile |   1 +
 tools/testing/selftests/livepatch/Makefile   |   5 +
 tools/testing/selftests/livepatch/config |   1 +
 tools/testing/selftests/livepatch/livepatch-test | 658 +++
 10 files changed, 1136 insertions(+)
 create mode 100644 lib/test_klp_callbacks_busy.c
 create mode 100644 lib/test_klp_callbacks_demo.c
 create mode 100644 lib/test_klp_callbacks_demo2.c
 create mode 100644 lib/test_klp_callbacks_mod.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100755 tools/testing/selftests/livepatch/livepatch-test

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 64155e310a9f..cd2a2d25314e 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1932,6 +1932,17 @@ config TEST_DEBUG_VIRTUAL
 
  If unsure, say N.
 
+config TEST_LIVEPATCH
+   tristate "Test livepatching"
+   default n
+   depends on LIVEPATCH
+   help
+ Test various kernel livepatching features for correctness.
+ The tests will load test modules that will be livepatched
+ in various scenarios.
+
+ If unsure, say N.
+
 endif # RUNTIME_TESTING_MENU
 
 config MEMTEST
diff --git a/lib/Makefile b/lib/Makefile
index a90d4fcd748f..919de0acf1a8 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -67,6 +67,15 @@ obj-$(CONFIG_TEST_PARMAN) += test_parman.o
 obj-$(CONFIG_TEST_KMOD) += test_kmod.o
 obj-$(CONFIG_TEST_DEBUG_VIRTUAL) += test_debug_virtual.o
 
+obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_callbacks_demo.o \
+   test_klp_callbacks_demo2.o \
+   test_klp_callbacks_busy.o \
+   test_klp_callbacks_mod.o
+CFLAGS_test_klp_callbacks_demo.o   += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_demo2.o  += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_busy.o   += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_mod.o+= $(CC_FLAGS_FTRACE)
+
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
 CFLAGS_kobject_uevent.o += -DDEBUG
diff --git a/lib/test_klp_callbacks_busy.c b/lib/test_klp_callbacks_busy.c
new file mode 100644
index ..f76a7e6bed00
--- /dev/null
+++ b/lib/test_klp_callbacks_busy.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Joe Lawrence 
+
+/*
+ * livepatch-callbacks-busymod.c - (un)patching callbacks demo support module
+ *
+ *
+ * Purpose
+ * ---
+ *
+ * Simple module to demonstrate livepatch (un)patching callbacks.
+ *
+ *
+ * Usage
+ * -
+ *
+ * This module is not intended to be standalone.  See the "Usage"
+ * section of livepatch-callbacks-mod.c.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+static int sleep_secs;
+module_param(sleep_secs, int, 0644);
+MODULE_PARM_DESC(sleep_secs, "sleep_secs (default=0)");
+
+static void busymod_work_func(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work, busymod_work_func);
+
+static void busymod_work_func(struct work_struct *work)
+{
+   pr_info("%s, sleeping %d seconds ...\n", __func__, sleep_secs);
+   msleep(sleep_secs * 1000);
+   pr_info("%s exit\n", __func__);
+}
+
+static int livepatch_callbacks_mod_init(void)
+{
+   pr_info("%s\n", __func__);
+   schedule_delayed_work(,
+   msecs_to_jiffies(1000 * 0));
+   return 0;
+}
+
+static void livepatch_callbacks_mod_exit(void)
+{
+   cancel_delayed_work_sync();
+   pr_info("%s\n", __func__);
+}
+
+module_init(livepatch_callbacks_mod_init);
+module_exit(livepatch_callbacks_mod_exit);
+MODULE_LICENSE("GPL");
diff --git a/lib/test_klp_callbacks_demo.c 

[PATCH] Add livepatch kselftests

2018-03-28 Thread Joe Lawrence
Hi all,

This patch was motivated by the increasing corner cases in the livepatch
code.  These tests don't cover anywhere near all of them, but were
mostly already written up as demonstrations / documentation of the
livepatch callback functionality.  Converting them into a test rig
didn't take long.

So the testing methodology is a little hokey as it relies on dmesg order
and filtering.  That said, it's already been used to verify livepatch
callback for "livepatch: Atomic replace feature" patchset.  Any
suggestions for better testing would be welcome.

I didn't get to the shadow variable testing script yet.  I figured that
I'd share the current state before I got too far along in writing tests.
Suggestions for additional tests and test categories welcome as well.

To try out the tests, configure with:
CONFIG_TEST_LIVEPATCH=m
  
Build kernel, modules, install, etc. then reboot and kick off:
% make -C tools/testing/selftests TARGETS=livepatch run_tests

The tests expect to on top of v10+ of the "livepatch: Atomic replace
feature" series and take ~2.5 minutes to complete.

rfc changes:
- SPDX-License-Identifiers
- Moved livepatch test modules into lib/livepatch
- Renamed livepatch.sh (filename suffix)
- Reduced between-test delay time
- Split off common functions.sh file
- Split into separate livepatch, callbacks, and shadow-vars scrips
- Gave the tests short descriptions instead of TEST1, TEST2, etc.

Joe Lawrence (1):
  selftests/livepatch: introduce tests

 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  18 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 ++
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 202 
 .../testing/selftests/livepatch/test-callbacks.sh  | 526 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 177 +++
 .../selftests/livepatch/test-shadow-vars.sh|  13 +
 16 files changed, 1394 insertions(+)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

-- 
1.8.3.1



[PATCH] selftests/livepatch: introduce tests

2018-03-28 Thread Joe Lawrence
Add a few livepatch modules and simple target modules that the included
regression suite can run tests against.

Signed-off-by: Joe Lawrence 
---
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  18 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 ++
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 202 
 .../testing/selftests/livepatch/test-callbacks.sh  | 526 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 177 +++
 .../selftests/livepatch/test-shadow-vars.sh|  13 +
 16 files changed, 1394 insertions(+)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 64155e310a9f..e4a0e81542ff 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1932,6 +1932,18 @@ config TEST_DEBUG_VIRTUAL
 
  If unsure, say N.
 
+config TEST_LIVEPATCH
+   tristate "Test livepatching"
+   default n
+   depends on LIVEPATCH
+   depends on m
+   help
+ Test various kernel livepatching features for correctness.
+ The tests will load test modules that will be livepatched
+ in various scenarios.
+
+ If unsure, say N.
+
 endif # RUNTIME_TESTING_MENU
 
 config MEMTEST
diff --git a/lib/Makefile b/lib/Makefile
index a90d4fcd748f..98a38441afb0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -67,6 +67,8 @@ obj-$(CONFIG_TEST_PARMAN) += test_parman.o
 obj-$(CONFIG_TEST_KMOD) += test_kmod.o
 obj-$(CONFIG_TEST_DEBUG_VIRTUAL) += test_debug_virtual.o
 
+obj-$(CONFIG_TEST_LIVEPATCH) += livepatch/
+
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
 CFLAGS_kobject_uevent.o += -DDEBUG
diff --git a/lib/livepatch/Makefile b/lib/livepatch/Makefile
new file mode 100644
index ..3c588564e518
--- /dev/null
+++ b/lib/livepatch/Makefile
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for livepatch test code.
+
+obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_atomic_replace.o \
+   test_klp_callbacks_demo.o \
+   test_klp_callbacks_demo2.o \
+   test_klp_callbacks_busy.o \
+   test_klp_callbacks_mod.o \
+   test_klp_livepatch.o
+
+# Livepatch modules require CC_FLAGS_FTRACE to hook functions
+CFLAGS_test_klp_atomic_replace.o   += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_demo.o   += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_demo2.o  += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_busy.o   += $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_callbacks_mod.o+= $(CC_FLAGS_FTRACE)
+CFLAGS_test_klp_livepatch.o+= $(CC_FLAGS_FTRACE)
diff --git a/lib/livepatch/test_klp_atomic_replace.c 
b/lib/livepatch/test_klp_atomic_replace.c
new file mode 100644
index ..481941050e60
--- /dev/null
+++ b/lib/livepatch/test_klp_atomic_replace.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Joe Lawrence 
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+
+static int replace;
+module_param(replace, int, 0644);
+MODULE_PARM_DESC(replace, "replace (default=0)");
+
+#include 
+static int livepatch_meminfo_proc_show(struct seq_file *m, void *v)
+{
+   seq_printf(m, "%s: %s\n", THIS_MODULE->name,
+  "this has been live patched");
+   return 0;
+}
+
+static struct klp_func funcs[] = {
+   {
+   .old_name = "meminfo_proc_show",
+   .new_func = livepatch_meminfo

Re: [PATCH v10 00/10] livepatch: Atomic replace feature

2018-03-08 Thread Joe Lawrence
On 03/08/2018 10:01 AM, Petr Mladek wrote:
> On Wed 2018-03-07 16:55:53, Joe Lawrence wrote:
>> Running against v10, callbacks seem to be good up until I disable an
>> atomic replace patch.  My understanding is that the original patch's
>> unpatch callbacks should be skipped (as they were).  I was surprised to
>> see that atomic replacement patch only ran it's post-unpatch callback.
> 
> Great catch!
> 
> I guess that it is caused by the heuristic used in
> klp_unpatch_object() to decide whether the object is patched
> or not.
> 
> We need to change the state only when manipulating the
> statically defined functions.
> 
> Thanks a lot for so extensive testing!!!

Sorry for not getting to this series sooner.  I'm trying to refit these
tests into a kselftest so we can more easily reuse them.  Still hacking
away at it, but I'll post when something soon to start a livepatch
selftests conversation :)

-- Joe


[PATCH v4 0/1] Add livepatch kselftests

2018-04-25 Thread Joe Lawrence
This round incorporates feedback from SUSE folks, Miroslav, Petr and
Libor.  Thanks for the reviews and feedback!

Like the previous version, this applies on top of Petr's shadow variable
changes and the atomic replace patchset.

-- Joe

changes from v3:
- add MAINTAINERS entry for tools/testing/selftests/livepatch/
- make more test_klp_shadow_vars.c functions static (Miroslav)
- use git format-patch --base to generate base-commit and prerequisite
  patch info (kbuild test robot)
- tweak TEST_LIVEPATCH help text (Petr)
- add note in callbacks.txt pointing to sample/test examples (Petr)
- add a kmsg log() function (Libor)
- various whitespace and comment cleanups (Libor)
- add "$(dirname $0)/" directory prefix to functions.sh sourcing (Libor)
- add loop_until() function instead of redundant inline retry/loops (Libor)
- wait_for_transition() looks for any transition (Libor)

changes from v2:
- fix module_exit(test_klp_shadow_vars_exit) in test_klp_shadow_vars.c
- silence kbuild test robot's "XXX can be static" and "Using plain
  integer as NULL pointer" complaints
- re-run tests with CONFIG_LOCKDEP=y and CONFIG_PROVE_LOCKING=y
- use GFP_ATOMIC in test_klp_shadow_vars.c constructor code

changes from v1:
- Only add $(CC_FLAGS_FTRACE) for target modules
- Remove between test delay
- Reduce RETRY_INTERVAL to .1 sec
- Reduce test_callback_mod's busymod_work_func delay from 60 to 10 sec
- s/PASS/ok and s/FAIL/not ok for test output
- Move test descriptions from Documentation/livepatch/callbacks.txt
  into tools/testing/selftests/livepatch/test-callbacks.sh
- Add a shadow variable test script and module
- Add a short tools/testing/selftests/livepatch/README
- to += linux-kselft...@vger.kernel.org
- cc += Libor, Nicolai, Artem

changes from rfc:
- SPDX-License-Identifiers
- Moved livepatch test modules into lib/livepatch
- Renamed livepatch.sh (filename suffix)
- Reduced between-test delay time
- Split off common functions.sh file
- Split into separate livepatch, callbacks, and shadow-vars scrips
- Gave the tests short descriptions instead of TEST1, TEST2, etc.

Joe Lawrence (1):
  selftests/livepatch: introduce tests

 Documentation/livepatch/callbacks.txt | 489 +-
 MAINTAINERS   |   1 +
 lib/Kconfig.debug |  21 +
 lib/Makefile  |   2 +
 lib/livepatch/Makefile|  15 +
 lib/livepatch/test_klp_atomic_replace.c   |  69 ++
 lib/livepatch/test_klp_callbacks_busy.c   |  43 ++
 lib/livepatch/test_klp_callbacks_demo.c   | 132 
 lib/livepatch/test_klp_callbacks_demo2.c  | 104 +++
 lib/livepatch/test_klp_callbacks_mod.c|  24 +
 lib/livepatch/test_klp_livepatch.c|  62 ++
 lib/livepatch/test_klp_shadow_vars.c  | 236 +++
 tools/testing/selftests/Makefile  |   1 +
 tools/testing/selftests/livepatch/Makefile|   8 +
 tools/testing/selftests/livepatch/README  |  43 ++
 tools/testing/selftests/livepatch/config  |   1 +
 .../testing/selftests/livepatch/functions.sh  | 164 +
 .../selftests/livepatch/test-callbacks.sh | 607 ++
 .../selftests/livepatch/test-livepatch.sh | 173 +
 .../selftests/livepatch/test-shadow-vars.sh   |  60 ++
 20 files changed, 1771 insertions(+), 484 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/README
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh


base-commit: 0adb32858b0bddf4ada5f364a84ed60b196dbcda
prerequisite-patch-id: 5ed747c1a89a5dc4bba08186e21f927d7f3bf049
prerequisite-patch-id: e9800288b71a9f339ea066e58d9ef70dece67083
prerequisite-patch-id: 415f2e190b1b50142c78f2940c7b8dd39b5321a0
prerequisite-patch-id: d229d9cf08af087e0a758d9df1da467103c2c200
prerequisite-patch-id: b8c7ef99b13c6b321cba5e8919ed0b3e29f213e9
prerequisite-patch-id: 4e10c0d08f151b18310fe0b1e5013d62db94cfeb
prerequisite-patch-id: 33046b190c114d202f3a52e0e274dbb2b1907a4c
prerequisite-patch-id: 6978944a725756317dd4e005d479b6101784aaf0
prerequisite-patch-id: cce9d3c7e1ae8887f387ca9e072552dc63479749
prerequisite-patch-id: c44ccc5dd7b1be6fe2b1f32ca

[PATCH v4 1/1] selftests/livepatch: introduce tests

2018-04-25 Thread Joe Lawrence
Add a few livepatch modules and simple target modules that the included
regression suite can run tests against:

  - basic livepatching (multiple patches, atomic replace)
  - pre/post (un)patch callbacks
  - shadow variable API

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt | 489 +-
 MAINTAINERS   |   1 +
 lib/Kconfig.debug |  21 +
 lib/Makefile  |   2 +
 lib/livepatch/Makefile|  15 +
 lib/livepatch/test_klp_atomic_replace.c   |  69 ++
 lib/livepatch/test_klp_callbacks_busy.c   |  43 ++
 lib/livepatch/test_klp_callbacks_demo.c   | 132 
 lib/livepatch/test_klp_callbacks_demo2.c  | 104 +++
 lib/livepatch/test_klp_callbacks_mod.c|  24 +
 lib/livepatch/test_klp_livepatch.c|  62 ++
 lib/livepatch/test_klp_shadow_vars.c  | 236 +++
 tools/testing/selftests/Makefile  |   1 +
 tools/testing/selftests/livepatch/Makefile|   8 +
 tools/testing/selftests/livepatch/README  |  43 ++
 tools/testing/selftests/livepatch/config  |   1 +
 .../testing/selftests/livepatch/functions.sh  | 164 +
 .../selftests/livepatch/test-callbacks.sh | 607 ++
 .../selftests/livepatch/test-livepatch.sh | 173 +
 .../selftests/livepatch/test-shadow-vars.sh   |  60 ++
 20 files changed, 1771 insertions(+), 484 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/README
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
index c9776f48e458..182e31d4abce 100644
--- a/Documentation/livepatch/callbacks.txt
+++ b/Documentation/livepatch/callbacks.txt
@@ -118,488 +118,9 @@ similar change to their hw_features value.  (Client 
functions of the
 value may need to be updated accordingly.)
 
 
-Test cases
-==
-
-What follows is not an exhaustive test suite of every possible livepatch
-pre/post-(un)patch combination, but a selection that demonstrates a few
-important concepts.  Each test case uses the kernel modules located in
-the samples/livepatch/ and assumes that no livepatches are loaded at the
-beginning of the test.
-
-
-Test 1
---
-
-Test a combination of loading a kernel module and a livepatch that
-patches a function in the first module.  (Un)load the target module
-before the livepatch module:
-
-- load target module
-- load livepatch
-- disable livepatch
-- unload target module
-- unload livepatch
-
-First load a target module:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   34.475708] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-On livepatch enable, before the livepatch transition starts, pre-patch
-callbacks are executed for vmlinux and livepatch_callbacks_mod (those
-klp_objects currently loaded).  After klp_objects are patched according
-to the klp_patch, their post-patch callbacks run and the transition
-completes:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   36.503719] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   36.504213] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
-  [   36.504238] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   36.504721] livepatch_callbacks_demo: pre_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   36.505849] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
-  [   37.727133] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
-  [   37.727232] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   37.727860] livepatch_callbacks_demo: post_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   37.728792] livepatch: 'livepatch_callbacks_demo': patching complete
-
-Similarly, on livepatch disable, pre-patch callbacks run before the
-unpatching transition starts.  klp_objects are reverted, post-patch
-callbacks execute and the transition completes:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_dem

Re: [PATCH v4 0/1] Add livepatch kselftests

2018-04-26 Thread Joe Lawrence
>On 04/25/2018 02:28 PM, Joe Lawrence wrote:

> [ ... snip ... ]
> 
> base-commit: 0adb32858b0bddf4ada5f364a84ed60b196dbcda
> prerequisite-patch-id: 5ed747c1a89a5dc4bba08186e21f927d7f3bf049
> prerequisite-patch-id: e9800288b71a9f339ea066e58d9ef70dece67083
> prerequisite-patch-id: 415f2e190b1b50142c78f2940c7b8dd39b5321a0
> prerequisite-patch-id: d229d9cf08af087e0a758d9df1da467103c2c200
> prerequisite-patch-id: b8c7ef99b13c6b321cba5e8919ed0b3e29f213e9
> prerequisite-patch-id: 4e10c0d08f151b18310fe0b1e5013d62db94cfeb
> prerequisite-patch-id: 33046b190c114d202f3a52e0e274dbb2b1907a4c
> prerequisite-patch-id: 6978944a725756317dd4e005d479b6101784aaf0
> prerequisite-patch-id: cce9d3c7e1ae8887f387ca9e072552dc63479749
> prerequisite-patch-id: c44ccc5dd7b1be6fe2b1f32ca6abde1da73fae79
> 

Hi kbuild test robot folks,

I attempted to use the --base option with git format-patch as suggested
by Philip, but the bot still sent me mail (addressed only to myself and
cc'd kbuild-...@01.org) about build test ERRORs against the wrong base:

> [auto build test ERROR on v4.16]
> [also build test ERROR on next-20180424]
> [cannot apply to linus/master jikos-livepatching/for-next]

I'm assuming operator error :(  Here's a summary of my workflow:

* Save an .mbox of the entire base patchset, as posted to the
live-patching list:

  https://lkml.org/lkml/2018/3/23/665

* Create a "base" branch and apply the mbox:

  % git checkout -b test_base v4.16
  Switched to a new branch 'test_base'

  % git am /tmp/pm.mbox
  Applying: livepatch: Use lists to manage patches, objects and functions
  Applying: livepatch: Free only structures with initialized kobject
  Applying: livepatch: Add atomic replace
  Applying: livepatch: Add an extra flag to distinguish registered   patches
  Applying: livepatch: Remove replaced patches from the stack
  Applying: livepatch: Remove Nop structures when unused
  Applying: livepatch: Allow to replace even disabled patches
  Applying: livepatch: Atomic replace and cumulative patches documentation

* Create a new dev branch from the base, make a trivial change and commit:

  % git checkout -b test_branch test_base
  % sed -i 's/^EXTRAVERSION =/EXTRAVERSION = .test/' Makefile
  % git commit Makefile -m 'test commit'

* Create .patch files with --base:

  % git format-patch --base=v4.16 -1 --cover-letter
  % grep -e '^base-commit' -e 'prereq' -cover-letter.patch
  base-commit: 0adb32858b0bddf4ada5f364a84ed60b196dbcda
  prerequisite-patch-id: 5ed747c1a89a5dc4bba08186e21f927d7f3bf049
  prerequisite-patch-id: e9800288b71a9f339ea066e58d9ef70dece67083
  prerequisite-patch-id: 415f2e190b1b50142c78f2940c7b8dd39b5321a0
  prerequisite-patch-id: d229d9cf08af087e0a758d9df1da467103c2c200
  prerequisite-patch-id: b8c7ef99b13c6b321cba5e8919ed0b3e29f213e9
  prerequisite-patch-id: 4e10c0d08f151b18310fe0b1e5013d62db94cfeb
  prerequisite-patch-id: 33046b190c114d202f3a52e0e274dbb2b1907a4c
  prerequisite-patch-id: 6978944a725756317dd4e005d479b6101784aaf0

I notice that these patch-ids are only added to the cover-letter... do I
need to force them each individual patch as well?  /confused

Thanks,

-- Joe


Re: [PATCH v4 0/1] Add livepatch kselftests

2018-05-10 Thread Joe Lawrence
On Fri, May 11, 2018 at 10:53:24AM +0800, Ye Xiaolong wrote:
> Hi, Joe
> 
> Sorry for the late response.

Hi Xiaolong, no worries...

> On 04/26, Joe Lawrence wrote:
> >>On 04/25/2018 02:28 PM, Joe Lawrence wrote:
> >
> >> [ ... snip ... ]
> >> 
> >> base-commit: 0adb32858b0bddf4ada5f364a84ed60b196dbcda
> >> prerequisite-patch-id: 5ed747c1a89a5dc4bba08186e21f927d7f3bf049
> >> prerequisite-patch-id: e9800288b71a9f339ea066e58d9ef70dece67083
> >> prerequisite-patch-id: 415f2e190b1b50142c78f2940c7b8dd39b5321a0
> >> prerequisite-patch-id: d229d9cf08af087e0a758d9df1da467103c2c200
> >> prerequisite-patch-id: b8c7ef99b13c6b321cba5e8919ed0b3e29f213e9
> >> prerequisite-patch-id: 4e10c0d08f151b18310fe0b1e5013d62db94cfeb
> >> prerequisite-patch-id: 33046b190c114d202f3a52e0e274dbb2b1907a4c
> >> prerequisite-patch-id: 6978944a725756317dd4e005d479b6101784aaf0
> >> prerequisite-patch-id: cce9d3c7e1ae8887f387ca9e072552dc63479749
> >> prerequisite-patch-id: c44ccc5dd7b1be6fe2b1f32ca6abde1da73fae79
> >> 
> >
> >Hi kbuild test robot folks,
> >
> >I attempted to use the --base option with git format-patch as suggested
> >by Philip, but the bot still sent me mail (addressed only to myself and
> >cc'd kbuild-...@01.org) about build test ERRORs against the wrong base:
> >
> >> [auto build test ERROR on v4.16]
> >> [also build test ERROR on next-20180424]
> >> [cannot apply to linus/master jikos-livepatching/for-next]
> 
> I noticed this error report was for [PATCH v3] selftests/livepatch: introduce 
> tests
> which doesn't include the base commit info.

That must have been it!  Looking back in my mail archives, I don't see
any complaints against v4.  The bot must have sent me v3 mail just after I
fired off v4.

> > [ ... snip workflow detail ... ]
> I think the work flow you described above is ok, you can just send them with
> git send-email after doing that, and base commit/prerequisite patch info in
> cover-letter is fine, the question here is I can't find the patch emails of
> your patchset except the cover letter in 0day's mail archive, do you send them
> as a whole series, could you tell the subjects of them so I can take a look in
> 0day's log.

My patchset v4 (this subject/thread):

  [PATCH v4 0/1] Add livepatch kselftests
  https://lkml.org/lkml/2018/4/25/1139

based on Petr's patchsets:

  [PATCH 0/8] livepatch: Atomic replace feature
  https://lkml.org/lkml/2018/3/23/665

  [PATCH v3 0/2] livepatch: Allocate and free shadow variables more safely
  https://lkml.org/lkml/2018/4/16/326

All of which should have been posted to linux-kernel as well as
linux-livepatching.  I can dig up Message-Ids or other headers if that
helps any.

Regards,

-- Joe


Re: [PATCH v4 1/3] livepatch: add (un)patch callbacks

2017-08-29 Thread Joe Lawrence
On 08/29/2017 11:49 AM, Josh Poimboeuf wrote:
> On Fri, Aug 25, 2017 at 03:10:00PM -0400, Joe Lawrence wrote:
>> +Test 6
>> +--
>> +
>> +Test a scenario where a vmlinux pre-patch callback returns a non-zero
>> +status (ie, failure):
>> +
>> +- load target module
>> +- load livepatch -ENODEV
>> +- unload target module
>> +
>> +First load a target module:
>> +
>> +  % insmod samples/livepatch/livepatch-callbacks-mod.ko
>> +  [   80.740520] livepatch_callbacks_mod: livepatch_callbacks_mod_init
>> +
>> +Load the livepatch module, setting its 'pre_patch_ret' value to -19
>> +(-ENODEV).  When its vmlinux pre-patch callback executed, this status
>> +code will propagate back to the module-loading subsystem.  The result is
>> +that the insmod command refuses to load the livepatch module:
>> +
>> +  % insmod samples/livepatch/livepatch-callbacks-demo.ko pre_patch_ret=-19
>> +  [   82.747326] livepatch: enabling patch 'livepatch_callbacks_demo'
>> +  [   82.747743] livepatch: 'livepatch_callbacks_demo': initializing 
>> unpatching transition
>> +  [   82.747767] livepatch_callbacks_demo: pre_patch_callback: vmlinux
>> +  [   82.748237] livepatch: pre-patch callback failed for object 'vmlinux'
>> +  [   82.748637] livepatch: failed to enable patch 
>> 'livepatch_callbacks_demo'
>> +  [   82.749059] livepatch: 'livepatch_callbacks_demo': canceling 
>> transition, unpatching
>> +  [   82.749060] livepatch: 'livepatch_callbacks_demo': completing 
>> unpatching transition
>> +  [   82.749177] livepatch_callbacks_demo: post_unpatch_callback: 
>> livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
>> +  [   82.749868] livepatch: 'livepatch_callbacks_demo': unpatching complete
>> +  [   82.765809] insmod: ERROR: could not insert module 
>> samples/livepatch/livepatch-callbacks-demo.ko: No such device
>> +
>> +  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
>> +  [   84.774238] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
> 
> First off, this documentation is very nice because it clarifies all the
> callback scenarios and edge cases.
> 
> The above situation still seems a little odd to me.  If I understand
> correctly, the target module was never patched, and its pre_patch
> callback was never called.  But its post_unpatch callback *was* called.
> That doesn't seem right.

Ah, this does look to be a bug.

> Maybe we should change the condition a little bit.  Currently it's:
> 
>   No post-patch, pre-unpatch, or post-unpatch callbacks will be executed
>   for a given klp_object if its pre-patch callback returned non-zero
>   status.
> 
> I think that might have been my idea, but seeing the above case makes it
> clear that it's not quite right.

It could have been correct if the code differentiated between a
never-run pre_patch_status of 0 (by kzalloc) and a successful
pre_patch_status of 0 (by callback return), I think.

>   Maybe it should instead be:
> 
>   No post-patch, pre-unpatch, or post-unpatch callbacks will be executed
>   for a given klp_object if the object failed to patch, due to a failed
>   pre_patch callback or for any other reason.
> 
>   If the object did successfully patch, but the patch transition never
>   started for some reason (e.g., if another object failed to patch),
>   only the post-unpatch callback will be called.

That description sounds correct...

> So then, instead of tracking whether the pre-patch callback succeeded,
> we just need to track whether the object was patched (which we already
> do, with obj->patched).
> 
> What do you think?

I think this would only work if there was a sticky
"obj->was_ever_patched" variable.  We moved the post-unpatch-callback to
the very end of klp_complete_transition()... by that point, obj->patched
will have already been cleared by klp_unpatch_objects.

We could maybe move obj->patched assignments out to encapsulate the pre
and post callbacks... but I would need to think about that a while.  It
seems pretty clear and symmetric as it is today (immediately set in
klp_(un)patch_object().

Perhaps a more careful checking of obj->pre_patch_callback_status is all
we need?  (I can't think of anything more succinct than adding a
obj->pre_patch_callback_done variable to the mix.)

-- Joe


Re: [PATCH v4 1/3] livepatch: add (un)patch callbacks

2017-08-30 Thread Joe Lawrence
On Tue, Aug 29, 2017 at 02:59:12PM -0500, Josh Poimboeuf wrote:
> On Tue, Aug 29, 2017 at 03:22:06PM -0400, Joe Lawrence wrote:
> > On 08/29/2017 11:49 AM, Josh Poimboeuf wrote:
> > > On Fri, Aug 25, 2017 at 03:10:00PM -0400, Joe Lawrence wrote:
> > >> +Test 6
> > >> +--
> > >> +
> > >> +Test a scenario where a vmlinux pre-patch callback returns a non-zero
> > >> +status (ie, failure):
> > >> +
> > >> +- load target module
> > >> +- load livepatch -ENODEV
> > >> +- unload target module
> > >> +
> > >> +First load a target module:
> > >> +
> > >> +  % insmod samples/livepatch/livepatch-callbacks-mod.ko
> > >> +  [   80.740520] livepatch_callbacks_mod: livepatch_callbacks_mod_init
> > >> +
> > >> +Load the livepatch module, setting its 'pre_patch_ret' value to -19
> > >> +(-ENODEV).  When its vmlinux pre-patch callback executed, this status
> > >> +code will propagate back to the module-loading subsystem.  The result is
> > >> +that the insmod command refuses to load the livepatch module:
> > >> +
> > >> +  % insmod samples/livepatch/livepatch-callbacks-demo.ko 
> > >> pre_patch_ret=-19
> > >> +  [   82.747326] livepatch: enabling patch 'livepatch_callbacks_demo'
> > >> +  [   82.747743] livepatch: 'livepatch_callbacks_demo': initializing 
> > >> unpatching transition
> > >> +  [   82.747767] livepatch_callbacks_demo: pre_patch_callback: vmlinux
> > >> +  [   82.748237] livepatch: pre-patch callback failed for object 
> > >> 'vmlinux'
> > >> +  [   82.748637] livepatch: failed to enable patch 
> > >> 'livepatch_callbacks_demo'
> > >> +  [   82.749059] livepatch: 'livepatch_callbacks_demo': canceling 
> > >> transition, unpatching
> > >> +  [   82.749060] livepatch: 'livepatch_callbacks_demo': completing 
> > >> unpatching transition
> > >> +  [   82.749177] livepatch_callbacks_demo: post_unpatch_callback: 
> > >> livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
> > >> +  [   82.749868] livepatch: 'livepatch_callbacks_demo': unpatching 
> > >> complete
> > >> +  [   82.765809] insmod: ERROR: could not insert module 
> > >> samples/livepatch/livepatch-callbacks-demo.ko: No such device
> > >> +
> > >> +  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
> > >> +  [   84.774238] livepatch_callbacks_mod: livepatch_callbacks_mod_exit
> > > 
> > > First off, this documentation is very nice because it clarifies all the
> > > callback scenarios and edge cases.
> > > 
> > > The above situation still seems a little odd to me.  If I understand
> > > correctly, the target module was never patched, and its pre_patch
> > > callback was never called.  But its post_unpatch callback *was* called.
> > > That doesn't seem right.
> > 
> > Ah, this does look to be a bug.
> > 
> > > Maybe we should change the condition a little bit.  Currently it's:
> > > 
> > >   No post-patch, pre-unpatch, or post-unpatch callbacks will be executed
> > >   for a given klp_object if its pre-patch callback returned non-zero
> > >   status.
> > > 
> > > I think that might have been my idea, but seeing the above case makes it
> > > clear that it's not quite right.
> > 
> > It could have been correct if the code differentiated between a
> > never-run pre_patch_status of 0 (by kzalloc) and a successful
> > pre_patch_status of 0 (by callback return), I think.
> > 
> > >   Maybe it should instead be:
> > > 
> > >   No post-patch, pre-unpatch, or post-unpatch callbacks will be executed
> > >   for a given klp_object if the object failed to patch, due to a failed
> > >   pre_patch callback or for any other reason.
> > > 
> > >   If the object did successfully patch, but the patch transition never
> > >   started for some reason (e.g., if another object failed to patch),
> > >   only the post-unpatch callback will be called.
> > 
> > That description sounds correct...
> > 
> > > So then, instead of tracking whether the pre-patch callback succeeded,
> > > we just need to track whether the object was patched (which we already
> > > do, with obj->patched).
> > > 
> > > What do you think?
> > 
> > I think this would only work if there

[PATCH v5 0/3] livepatch callbacks

2017-08-31 Thread Joe Lawrence
 to 
loading module 'livepatch_callbacks_busymod'
  [ 1502.192664] livepatch_callbacks_demo: pre_patch_callback: 
livepatch_callbacks_busymod -> [MODULE_STATE_COMING] Full formed, running 
module_init
  [ 1502.197923] livepatch: *** forcing klp_patch_object() return of -EINVAL ***
  [ 1502.202389] livepatch: failed to apply patch 'livepatch_callbacks_demo' to 
module 'livepatch_callbacks_busymod' (-22)
  [ 1502.203727] livepatch_callbacks_demo: post_unpatch_callback: 
livepatch_callbacks_busymod -> [MODULE_STATE_COMING] Full formed, running 
module_init
  [ 1502.205356] livepatch: patch 'livepatch_callbacks_demo' failed for module 
'livepatch_callbacks_busymod', refusing to load module 
'livepatch_callbacks_busymod'
  [ 1502.222539] insmod: ERROR: could not insert module 
samples/livepatch/livepatch-callbacks-busymod.ko: Invalid parameters

When the livepatch is later disabled, the remaining klp_objects that are
loaded (vmlinux) will run their pre and post-unpatch callbacks:

  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  [ 1504.226238] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [ 1504.226836] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [ 1505.759301] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [ 1505.760111] livepatch: 'livepatch_callbacks_demo': unpatching complete

  % rmmod samples/livepatch/livepatch-callbacks-demo.ko


An additional test was run (modifying the sample livepatch module, so
again not included in the Documentation), where the livepatch did not
include a pre-patch callback, but did specify all the other callbacks.
This is a scenario Josh pointed out that v4's
klp_object.prepatch_callback_status did not fully cover.


Test 12
---

- load target module
- load livepatch
- disable livepatch
- unload target module
- unload livepatch

  % insmod samples/livepatch/livepatch-callbacks-mod.ko 
  [   92.874499] livepatch_callbacks_mod: module verification failed: signature 
and/or required key missing - tainting kernel
  [   92.875802] livepatch_callbacks_mod: livepatch_callbacks_mod_init

Notice when the livepatch module is loaded, no pre-patch callbacks run.
All other callbacks do execute later though:

  % insmod samples/livepatch/livepatch-callbacks-demo.ko 
  [   94.958399] livepatch_callbacks_demo: tainting kernel with TAINT_LIVEPATCH
  [   94.960493] livepatch: enabling patch 'livepatch_callbacks_demo'
  [   94.961183] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
  [   96.736263] livepatch_callbacks_demo: post_patch_callback: vmlinux
  [   96.736903] livepatch_callbacks_demo: post_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
  [   96.737819] livepatch: 'livepatch_callbacks_demo': patching complete

  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  [   96.965430] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [   96.966131] livepatch_callbacks_demo: pre_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
  [   96.967253] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [   98.720218] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [   98.721134] livepatch_callbacks_demo: post_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
  [   98.722217] livepatch: 'livepatch_callbacks_demo': unpatching complete

  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
  % rmmod samples/livepatch/livepatch-callbacks-mod.ko
  [  100.986947] livepatch_callbacks_mod: livepatch_callbacks_mod_exit

-- Joe

Joe Lawrence (3):
  livepatch: add (un)patch callbacks
  livepatch: move transition "complete" notice into
klp_complete_transition()
  livepatch: add transition notices

 Documentation/livepatch/callbacks.txt   | 594 
 include/linux/livepatch.h   |  25 +
 kernel/livepatch/core.c |  55 ++-
 kernel/livepatch/core.h |  37 ++
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  45 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-demo.c| 234 ++
 samples/livepatch/livepatch-callbacks-mod.c |  55 +++
 10 files changed, 1104 insertions(+), 17 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-busymod.c
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

-- 
1.8.3.1



[PATCH v5 2/3] livepatch: move transition "complete" notice into klp_complete_transition()

2017-08-31 Thread Joe Lawrence
klp_complete_transition() performs a bit of housework before a
transition to KLP_PATCHED or KLP_UNPATCHED is actually completed
(including post-(un)patch callbacks).  To be consistent, move the
transition "complete" kernel log notice out of
klp_try_complete_transition() and into klp_complete_transition().

Suggested-by: Josh Poimboeuf 
Signed-off-by: Joe Lawrence 
---
 kernel/livepatch/transition.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 7bf55b7f3687..53887f0bca10 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -136,6 +136,9 @@ static void klp_complete_transition(void)
klp_post_unpatch_callback(obj);
}
 
+   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
+ klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
/*
 * See complementary comment in __klp_enable_patch() for why we
 * keep the module reference for immediate patches.
@@ -423,9 +426,6 @@ void klp_try_complete_transition(void)
}
 
 success:
-   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
- klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
-
/* we're done, now cleanup the data structures */
klp_complete_transition();
 }
-- 
1.8.3.1



[PATCH v5 3/3] livepatch: add transition notices

2017-08-31 Thread Joe Lawrence
Log a few kernel debug messages at the beginning of the following livepatch
transition functions:

  klp_complete_transition()
  klp_cancel_transition()
  klp_init_transition()
  klp_reverse_transition()

Also update the log notice message in klp_start_transition() for similar
verbiage as the above messages.

Suggested-by: Josh Poimboeuf 
Signed-off-by: Joe Lawrence 
---
 kernel/livepatch/transition.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 53887f0bca10..3d44a3cf27be 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -82,6 +82,10 @@ static void klp_complete_transition(void)
unsigned int cpu;
bool immediate_func = false;
 
+   pr_debug("'%s': completing %s transition\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
if (klp_target_state == KLP_UNPATCHED) {
/*
 * All tasks have transitioned to KLP_UNPATCHED so we can now
@@ -163,6 +167,9 @@ void klp_cancel_transition(void)
if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED))
return;
 
+   pr_debug("'%s': canceling transition, unpatching\n",
+klp_transition_patch->mod->name);
+
klp_target_state = KLP_UNPATCHED;
klp_complete_transition();
 }
@@ -441,7 +448,8 @@ void klp_start_transition(void)
 
WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
 
-   pr_notice("'%s': %s...\n", klp_transition_patch->mod->name,
+   pr_notice("'%s': starting %s transition\n",
+ klp_transition_patch->mod->name,
  klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
 
/*
@@ -489,6 +497,9 @@ void klp_init_transition(struct klp_patch *patch, int state)
 
WARN_ON_ONCE(klp_target_state != KLP_UNDEFINED);
 
+   pr_debug("'%s': initializing %s transition\n", patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
klp_transition_patch = patch;
 
/*
@@ -562,6 +573,11 @@ void klp_reverse_transition(void)
unsigned int cpu;
struct task_struct *g, *task;
 
+   pr_debug("'%s': reversing transition from %s\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching to unpatching" :
+  "unpatching to patching");
+
klp_transition_patch->enabled = !klp_transition_patch->enabled;
 
klp_target_state = !klp_target_state;
-- 
1.8.3.1



[PATCH v5 1/3] livepatch: add (un)patch callbacks

2017-08-31 Thread Joe Lawrence
Provide livepatch modules a klp_object (un)patching notification
mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
setup or synchronize changes that would be difficult to support in only
patched-or-unpatched code contexts.

Callbacks can be registered for target module or vmlinux klp_objects,
but each implementation is klp_object specific.

  - Pre-(un)patch callbacks run before any (un)patching transition
starts.

  - Post-(un)patch callbacks run once an object has been (un)patched and
the klp_patch fully transitioned to its target state.

Example use cases include modification of global data and registration
of newly available services/handlers.

See Documentation/livepatch/callbacks.txt for details and
samples/livepatch/ for examples.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt   | 594 
 include/linux/livepatch.h   |  25 +
 kernel/livepatch/core.c |  50 +-
 kernel/livepatch/core.h |  37 ++
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  21 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-demo.c| 234 ++
 samples/livepatch/livepatch-callbacks-mod.c |  55 +++
 10 files changed, 1079 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-busymod.c
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
new file mode 100644
index ..689b3f399696
--- /dev/null
+++ b/Documentation/livepatch/callbacks.txt
@@ -0,0 +1,594 @@
+==
+(Un)patching Callbacks
+==
+
+Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
+to execute callback functions when a kernel object is (un)patched.  They
+can be considered a "power feature" that extends livepatching abilities
+to include:
+
+  - Safe updates to global data
+
+  - "Patches" to init and probe functions
+
+  - Patching otherwise unpatchable code (i.e. assembly)
+
+In most cases, (un)patch callbacks will need to be used in conjunction
+with memory barriers and kernel synchronization primitives, like
+mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.
+
+Callbacks differ from existing kernel facilities:
+
+  - Module init/exit code doesn't run when disabling and re-enabling a
+patch.
+
+  - A module notifier can't stop a to-be-patched module from loading.
+
+Callbacks are part of the klp_object structure and their implementation
+is specific to that klp_object.  Other livepatch objects may or may not
+be patched, irrespective of the target klp_object's current state.
+
+Callbacks can be registered for the following livepatch actions:
+
+  * Pre-patch- before a klp_object is patched
+
+  * Post-patch   - after a klp_object has been patched and is active
+   across all tasks
+
+  * Pre-unpatch  - before a klp_object is unpatched (ie, patched code is
+   active), used to clean up post-patch callback
+   resources
+
+  * Post-unpatch - after a klp_object has been patched, all code has
+   been restored and no tasks are running patched code,
+   used to cleanup pre-patch callback resources
+
+Each callback action is optional, omitting one does not preclude
+specifying any other.  Typical use cases however, pare a pre-patch with
+a post-unpatch handler and a post-patch with a pre-unpatch handler in
+symmetry: the patch handler acquires and configures resources and the
+unpatch handler tears down and releases those same resources.
+
+A callback is only executed if its host klp_object is loaded.  For
+in-kernel vmlinux targets, this means that callbacks will always execute
+when a livepatch is enabled/disabled.  For patch target kernel modules,
+callbacks will only execute if the target module is loaded.  When a
+module target is (un)loaded, its callbacks will execute only if the
+livepatch module is enabled.
+
+The pre-patch callback, if specified, is expected to return a status
+code (0 for success, -ERRNO on error).  An error status code indicates
+to the livepatching core that patching of the current klp_object is not
+safe and to stop the current patching request.  (When no pre-patch
+callback is provided, the transition is assumed to be safe.)  If a
+pre-patch callback returns failure, the kernel's module loader will:
+
+  - Refuse to load a livepatch, if the livepatch is loaded after
+targeted code.
+
+or:
+
+  - Refuse to load a module, if the livepatch was already succ

Re: [PATCH 2/8] kbuild: Support for Symbols.list creation

2017-08-31 Thread Joe Lawrence
Hi Joao,

A few nitpicks in-line below...

On Tue, Aug 29, 2017 at 04:01:34PM -0300, Joao Moreira wrote:
> For automatic resolution of livepatch relocations, a file called
> Symbols.list is used. This file maps symbols within every compiled
> kernel object allowing the identification of symbols whose name is
> unique, thus relocation can be automatically inferred, or providing
> information that helps developers when code annotation is required for
> solving the matter.
> 
> Add support for creating Symbols.list in the main Makefile. First,
> ensure that built-in is compiled when CONFIG_LIVEPATCH is enabled (as
> required to achieve a complete Symbols.list file). Define the command to
> build Symbols.list (cmd_klp_map) and hook it in the modules rule.
> 
> As it is undesirable to have symbols from livepatch objects inside
> Symbols.list, make livepatches discernible by modifying
> scripts/Makefile.build to create a .livepatch file for each livepatch
> in $(MODVERDIR). This file is then used by cmd_klp_map to identify and
> bypass livepatches.
> 
> For identifying livepatches during the build process, a flag variable
> LIVEPATCH_$(basetarget).o is considered in scripts/Makefile.build. This
> way, set this flag for the livepatch sample Makefile in
> samples/livepatch/Makefile.

I've never tried building a livepatch out of tree (is that even
possible?) but does this make it any more/less harder?
 
> Finally, Add a clean rule to ensure that Symbols.list is removed during
> clean.
> 
> Notes:
> 
> To achieve a correct Symbols.list file, all kernel objects must be
> considered, thus, its construction require these objects to be priorly
> built. On the other hand, invoking scripts/Makefile.modpost without
> having a complete Symbols.list in place would occasionally lead to
> in-tree livepatches being post-processed incorrectly. To prevent this
> from becoming a circular dependency, the construction of Symbols.list
> uses non-post-processed kernel objects and such does not cause harm as
> the symbols normally referenced from within livepatches are visible at
> this stage. Also due to these requirements, the spot in-between modules
> compilation and the invocation of scripts/Makefile.modpost was picked
> for hooking cmd_klp_map.
> 
> The approach based on .livepatch files was proposed as an alternative
> to using MODULE_INFO statementes. This approach was originally
   ^^^
nit: s/statementes/statements

> proposed by Miroslav Benes as a workaround for identifying livepathces
 ^^^
nit: s/livepathces/livepatches

> without depending on modinfo during the modpost stage. It was moved to
> this patch as the approach also shown to be useful while building
> Symbols.list.
> 
> Signed-off-by: Joao Moreira 
> ---
>  .gitignore |  1 +
>  Makefile   | 27 ---
>  samples/livepatch/Makefile |  1 +
>  scripts/Makefile.build |  6 ++
>  4 files changed, 32 insertions(+), 3 deletions(-)
> 
> diff --git a/.gitignore b/.gitignore
> index 0c39aa20b6ba..e6a67517a3bc 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -39,6 +39,7 @@ Module.symvers
>  *.dwo
>  *.su
>  *.c.[012]*.*
> +Symbols.list
>  
>  #
>  # Top-level generic files
> diff --git a/Makefile b/Makefile
> index e40c471abe29..e1d315e585d8 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -320,10 +320,13 @@ KBUILD_BUILTIN := 1
>  # If we have only "make modules", don't compile built-in objects.
>  # When we're building modules with modversions, we need to consider
>  # the built-in objects during the descend as well, in order to
> -# make sure the checksums are up to date before we record them.
> +# make sure the checksums are up to date before we record them. The
> +# same applies for building livepatches, as built-in objects may hold
> +# symbols which are referenced from livepatches and are required by
> +# klp-convert post-processing tool for resolving these cases.
>  
>  ifeq ($(MAKECMDGOALS),modules)
> -  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
> +  KBUILD_BUILTIN := $(if $(or $(CONFIG_MODVERSIONS), $(CONFIG_LIVEPATCH)),1)
>  endif
>  
>  # If we have "make  modules", compile modules
> @@ -1207,9 +1210,24 @@ all: modules
>  # duplicate lines in modules.order files.  Those are removed
>  # using awk while concatenating to the final file.
>  
> +quiet_cmd_klp_map = LIVEPATCHSymbols.list

nit: I don't think any other quiet_cmd invocations put a tab between the
label and file list.  That said, "LIVEPATCH" is > 8 chars, so it's not
going to line up anyway.

> +SLIST = $(objtree)/Symbols.list
> +
> +define cmd_klp_map
> + $(shell echo "*vmlinux" > $(SLIST)) 
> \
> + $(shell nm -f posix $(objtree)/vmlinux | cut -d\  -f1 >> $(SLIST))  
> \
> + $(foreach m, $(wildcard $(MODVERDIR)/*.mod),
> \
> + 

[PATCH v6] Livepatch shadow variables

2017-08-31 Thread Joe Lawrence
This version cleans up a few minor tweaks requested by Josh and
Miroslav.

v6:

- Convert an enum into a function argument flag
- Update code comment that still referenced updating existing shadow
  variables
- Doc: Add a closing ')' parenthesis character
- Doc: Add a blurb about callers providing mutual exclusion

Joe Lawrence (1):
  livepatch: introduce shadow variable API

 Documentation/livepatch/shadow-vars.txt   | 192 +
 include/linux/livepatch.h |   8 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 277 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 173 +++
 samples/livepatch/livepatch-shadow-fix2.c | 168 ++
 samples/livepatch/livepatch-shadow-mod.c  | 224 
 9 files changed, 1048 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

-- 
1.8.3.1



[PATCH v6] livepatch: introduce shadow variable API

2017-08-31 Thread Joe Lawrence
Add exported API for livepatch modules:

  klp_shadow_get()
  klp_shadow_alloc()
  klp_shadow_get_or_alloc()
  klp_shadow_free()
  klp_shadow_free_all()

that implement "shadow" variables, which allow callers to associate new
shadow fields to existing data structures.  This is intended to be used
by livepatch modules seeking to emulate additions to data structure
definitions.

See Documentation/livepatch/shadow-vars.txt for a summary of the new
shadow variable API, including a few common use cases.

See samples/livepatch/livepatch-shadow-* for example modules that
demonstrate shadow variables.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt   | 192 +
 include/linux/livepatch.h |   8 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 277 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 173 +++
 samples/livepatch/livepatch-shadow-fix2.c | 168 ++
 samples/livepatch/livepatch-shadow-mod.c  | 224 
 9 files changed, 1048 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
new file mode 100644
index ..e3ffc4301bfa
--- /dev/null
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -0,0 +1,192 @@
+
+Shadow Variables
+
+
+Shadow variables are a simple way for livepatch modules to associate
+additional "shadow" data with existing data structures.  Shadow data is
+allocated separately from parent data structures, which are left
+unmodified.  The shadow variable API described in this document is used
+to allocate/attach and detach/release shadow variables to their parents.
+
+The implementation introduces a global, in-kernel hashtable that
+associates pointers to parent objects and a numeric identifier of the
+shadow data.  The numeric identifier is a simple enumeration that may be
+used to describe shadow variable version, class or type, etc.  More
+specifically, the parent pointer serves as the hashtable key while the
+numeric id subsequently filters hashtable queries.  Multiple shadow
+variables may attach to the same parent object, but their numeric
+identifier distinguishes between them.
+
+
+1. Brief API summary
+
+
+(See the full API usage docbook notes in livepatch/shadow.c.)
+
+A hashtable references all shadow variables.  These references are
+stored and retrieved through a  pair.
+
+* The klp_shadow variable data structure encapsulates both tracking
+meta-data and shadow-data:
+  - meta-data
+- obj - pointer to parent object
+- id - data identifier
+  - data[] - storage for shadow data
+
+It is important to note that the klp_shadow_alloc() and
+klp_shadow_get_or_alloc() calls, described below, store a *copy* of the
+data that the functions are provided.  Callers should provide whatever
+mutual exclusion is required of the shadow data.
+
+* klp_shadow_get() - retrieve a shadow variable data pointer
+  - search hashtable for  pair
+
+* klp_shadow_alloc() - allocate and add a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- WARN and return NULL
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  to the global hashtable
+
+* klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_free() - detach and free a  shadow variable
+  - find and remove a  reference from global hashtable
+- if found, free shadow variable
+
+* klp_shadow_free_all() - detach and free all <*, id> shadow variables
+  - find and remove any <*, id> references from global hashtable
+- if found, free shadow variable
+
+
+2. Use cases
+
+
+(See the example shadow variable livepatch modules in samples/livepatch/
+for full working demonstrations.)
+
+For the following use-case examples, consider commit 1d147bfa6429
+("mac80211: fix AP powersave TX vs.  wakeup race"), which added a
+spinlock to net/mac80211/sta_info.h :: struct sta_info.  Each use-case
+example can be considered a stand-alone livepatch implementation of this
+fix.
+
+
+Matching parent's lifecycle
+---
+
+If par

[PATCH v3] add (un)patch callbacks

2017-08-16 Thread Joe Lawrence
ivepatch_callbacks_demo: pre_unpatch_callback: vmlinux
[   81.760994] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
[   82.862596] % rmmod samples/livepatch/livepatch-callbacks-demo.ko

Part 1: livepatch is loaded (no target module), only vmlinux callbacks
run.

Part 2: livepatch is disabled (no target module), only vmlinux callbacks
run.

[   84.878971] -- test6 - load target module, load livepatch -ENODEV, unload 
target module
[   84.879755] % insmod samples/livepatch/livepatch-callbacks-mod.ko
[   84.882842] livepatch_callbacks_mod: livepatch_callbacks_mod_init
[   86.885313] % insmod samples/livepatch/livepatch-callbacks-demo.ko 
pre_patch_ret=-19
[   86.889259] livepatch: enabling patch 'livepatch_callbacks_demo'
[   86.890160] livepatch_callbacks_demo: pre_patch_callback: vmlinux
[   86.890734] livepatch: pre-patch callback failed for object 'vmlinux'
[   86.891306] livepatch: failed to enable patch 'livepatch_callbacks_demo'
[   86.891931] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
[   86.892561] livepatch_callbacks_demo: post_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
[   86.908817] insmod: ERROR: could not insert module 
samples/livepatch/livepatch-callbacks-demo.ko: No such device
[   88.911655] % rmmod samples/livepatch/livepatch-callbacks-demo.ko
[   88.914815] rmmod: ERROR: Module livepatch_callbacks_demo is not currently 
loaded
[   90.917163] % rmmod samples/livepatch/livepatch-callbacks-mod.ko
[   90.919997] livepatch_callbacks_mod: livepatch_callbacks_mod_exit

Part 1: Livepatch is loaded after the target module, however the
vmlinux-pre-patch-callback returns -ENODEV, so the livepatch module
fails to load.

Note: both vmlinux and target module's post-unpatch-callbacks are
executed as part of the cancelled transition:

  klp_enable_patch
__klp_enable_patch
  klp_cancel_transition
klp_complete_transition

done:
  ...
  else if (klp_target_state == KLP_UNPATCHED)
   klp_post_unpatch_callback(obj);

[   92.934851] -- test7 - load livepatch, setup -ENODEV, load target module, 
disable livepatch, unload livepatch
[   92.935879] % insmod samples/livepatch/livepatch-callbacks-demo.ko
[   92.938683] livepatch: enabling patch 'livepatch_callbacks_demo'
[   92.939294] livepatch_callbacks_demo: pre_patch_callback: vmlinux
[   92.939823] livepatch: 'livepatch_callbacks_demo': patching...
[   93.727126] livepatch: 'livepatch_callbacks_demo': patching complete
[   93.727809] livepatch_callbacks_demo: post_patch_callback: vmlinux
[   94.942396] % echo -19 > 
/sys/module/livepatch_callbacks_demo/parameters/pre_patch_ret
[   96.944893] % insmod samples/livepatch/livepatch-callbacks-mod.ko
[   96.947557] livepatch: applying patch 'livepatch_callbacks_demo' to loading 
module 'livepatch_callbacks_mod'
[   96.948816] livepatch_callbacks_demo: pre_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
module_init
[   96.950416] livepatch: pre-patch callback failed for object 
'livepatch_callbacks_mod'
[   96.951424] livepatch: patch 'livepatch_callbacks_demo' failed for module 
'livepatch_callbacks_mod', refusing to load module 'livepatch_callbacks_mod'
[   96.966586] insmod: ERROR: could not insert module 
samples/livepatch/livepatch-callbacks-mod.ko: No such device
[   98.968923] % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
[   98.970179] livepatch: 'livepatch_callbacks_demo': unpatching...
[  100.703101] livepatch: 'livepatch_callbacks_demo': unpatching complete
[  100.704057] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
[  100.704898] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
[  100.972541] % rmmod samples/livepatch/livepatch-callbacks-mod.ko
[  100.975462] rmmod: ERROR: Module livepatch_callbacks_mod is not currently 
loaded
[  102.977392] % rmmod samples/livepatch/livepatch-callbacks-demo.ko

Part 1: Livepatch is loaded first, so vmlinux callbacks run

Part 2: The livepatch's pre-patch-callback is setup to now return
-ENODEV

Part 3: When a targetted module is loaded, the pre-patch-callback
returns -ENODEV and the target module fails to load.

Part 4: The livepatch is disabled and only the vmlinux unpatch-callbacks
are executed.

Note: this test should be consistent with the other test which fails a
pre-patch-callback status... ie, the post-unpatch-callback behavior for
said klp_object should be the same.

--

Joe Lawrence (1):
  livepatch: add (un)patch callbacks

 Documentation/livepatch/callbacks.txt|  87 
 include/linux/livepatch.h|  81 
 kernel/livepatch/core.c  |  37 --
 kernel/livepatch/patch.c |   5 +-
 kernel/livepatch/transition.c|  21 ++-
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-callbacks-demo.c | 190 +++
 samples/livepatch/livepatch-callbacks-mod.c  |  53 
 8 files changed, 462 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

-- 
1.8.3.1



[PATCH v3] livepatch: add (un)patch callbacks

2017-08-16 Thread Joe Lawrence
Provide livepatch modules a klp_object (un)patching notification
mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
setup or synchronize changes that would be difficult to support in only
patched-or-unpatched code contexts.

Callbacks can be registered for target module or vmlinux klp_objects,
but each implementation is klp_object specific.

  - Pre-(un)patch callbacks run before any (un)patching action takes
place.

  - Post-(un)patch callbacks run once an object has been (un)patched and
the klp_patch fully transitioned to its target state.

Example use cases include modification of global data and registration
of newly available services/handlers.

See Documentation/livepatch/callback.txt for details.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt|  87 
 include/linux/livepatch.h|  81 
 kernel/livepatch/core.c  |  37 --
 kernel/livepatch/patch.c |   5 +-
 kernel/livepatch/transition.c|  21 ++-
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-callbacks-demo.c | 190 +++
 samples/livepatch/livepatch-callbacks-mod.c  |  53 
 8 files changed, 462 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
new file mode 100644
index ..e18f2678f3bb
--- /dev/null
+++ b/Documentation/livepatch/callbacks.txt
@@ -0,0 +1,87 @@
+(Un)patching Callbacks
+==
+
+Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
+to execute callback functions when a kernel object is (un)patched.  They
+can be considered a "power feature" that extends livepatching abilities
+to include:
+
+  - Safe updates to global data
+
+  - "Patches" to init and probe functions
+
+  - Patching otherwise unpatchable code (i.e. assembly)
+
+In most cases, (un)patch hooks will need to be used in conjunction with
+memory barriers and kernel synchronization primitives, like
+mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.
+
+Callbacks differ from existing kernel facilities:
+
+  - Module init/exit code doesn't run when disabling and re-enabling a
+patch.
+
+  - A module notifier can't stop the to-be-patched module from loading.
+
+Callbacks are part of the klp_object structure and their implementation
+is specific to the given object.  Other livepatch objects may or may not
+be patched, irrespective of the target klp_object's current state.
+
+Callbacks can be registered for the following livepatch actions:
+
+  * Pre-patch- before klp_object is patched
+
+  * Post-patch   - after klp_object has been patched and is active
+   across all tasks
+
+  * Pre-unpatch  - before klp_object is unpatched, patched code is active
+
+  * Post-unpatch - after klp_object has been patched, all code has been
+  restored and no tasks are running patched code
+
+A callbacks is only executed if its host klp_object is loaded.  For
+in-kernel vmlinux targets, this means that callbacks will always execute
+when a livepatch is enabled/disabled.
+
+For kernel module targets, callbacks will only execute if the target
+module is loaded.  When a kernel module target is (un)loaded, its
+callbacks will execute only if the livepatch module is enabled.
+
+The pre-patch callback is expected to return a status code (0 for
+success, -ERRNO on error).  An error status code will indicate to the
+livepatching core that patching of the current klp_object is not safe
+and to stop the current patching request.  If the problematic klp_object
+is already loaded (i.e. a livepatch is loaded after target code), the
+kernel's module loader will refuse to load the livepatch.  On the other
+hand, if the problematic klp_object is already in place (i.e. a target
+module is loaded after a livepatch), then the module loader will refuse
+to load the target kernel module.
+
+
+Example Use-cases
+-
+
+1 - Update global data
+
+A pre-patch callback can be useful to update a global variable.  For
+example, 75ff39ccc1bd ("tcp: make challenge acks less predictable")
+changes a global sysctl, as well as patches the tcp_send_challenge_ack()
+function.
+
+In this case, if we're being super paranoid, it might make sense to
+patch the data *after* patching is complete with a post-patch callback,
+so that tcp_send_challenge_ack() could first be changed to read
+sysctl_tcp_challenge_ack_limit with READ_ONCE.
+
+
+2 - Support __init and probe function patches
+
+Although __init and probe functions are not directly livepatch-able, it
+may be possible to implement similar updates

Re: [PATCH v4] livepatch: introduce shadow variable API

2017-08-17 Thread Joe Lawrence
On 08/17/2017 10:05 AM, Petr Mladek wrote:
> On Mon 2017-08-14 16:02:43, Joe Lawrence wrote:
>> Add exported API for livepatch modules:
>>
>>   klp_shadow_get()
>>   klp_shadow_attach()
>>   klp_shadow_get_or_attach()
>>   klp_shadow_update_or_attach()
>>   klp_shadow_detach()
>>   klp_shadow_detach_all()
>>
>> that implement "shadow" variables, which allow callers to associate new
>> shadow fields to existing data structures.  This is intended to be used
>> by livepatch modules seeking to emulate additions to data structure
>> definitions.
>>
>> See Documentation/livepatch/shadow-vars.txt for a summary of the new
>> shadow variable API, including a few common use cases.
>>
>> See samples/livepatch/livepatch-shadow-* for example modules that
>> demonstrate shadow variables.
>>
>> diff --git a/kernel/livepatch/shadow.c b/kernel/livepatch/shadow.c
>> new file mode 100644
>> index ..0ebd4b635e4f
>> --- /dev/null
>> +++ b/kernel/livepatch/shadow.c
>> +/**
>> + * klp_shadow_match() - verify a shadow variable matches given 
>> + * @shadow: shadow variable to match
>> + * @obj:pointer to parent object
>> + * @id: data identifier
>> + *
>> + * Return: true if the shadow variable matches.
>> + *
>> + * Callers should hold the klp_shadow_lock.
>> + */
>> +static inline bool klp_shadow_match(struct klp_shadow *shadow, void *obj,
>> +unsigned long id)
>> +{
>> +return shadow->obj == obj && shadow->id == id;
>> +}
> 
> Do we really need this function? It is called only in situations
> where shadow->obj == obj is always true. Especially the use in
> klp_shadow_detach_all() is funny because we pass shadow->obj as
> the shadow parameter.

Personal preference.  Abstracting out all of the routines that operated
on the shadow variables (setting up, comparison) did save some code
lines and centralized these common bits.

>> +
>> +/**
>> + * klp_shadow_get() - retrieve a shadow variable data pointer
>> + * @obj:pointer to parent object
>> + * @id: data identifier
>> + *
>> + * Return: the shadow variable data element, NULL on failure.
>> + */
>> +void *klp_shadow_get(void *obj, unsigned long id)
>> +{
>> +struct klp_shadow *shadow;
>> +
>> +rcu_read_lock();
>> +
>> +hash_for_each_possible_rcu(klp_shadow_hash, shadow, node,
>> +   (unsigned long)obj) {
>> +
>> +if (klp_shadow_match(shadow, obj, id)) {
>> +rcu_read_unlock();
>> +return shadow->data;
>> +}
>> +}
>> +
>> +rcu_read_unlock();
>> +
>> +return NULL;
>> +}
>> +EXPORT_SYMBOL_GPL(klp_shadow_get);
>> +
>> +/*
>> + * klp_shadow_set() - initialize a shadow variable
>> + * @shadow: shadow variable to initialize
>> + * @obj:pointer to parent object
>> + * @id: data identifier
>> + * @data:   pointer to data to attach to parent
>> + * @size:   size of attached data
>> + *
>> + * Callers should hold the klp_shadow_lock.
>> + */
>> +static inline void klp_shadow_set(struct klp_shadow *shadow, void *obj,
>> +  unsigned long id, void *data, size_t size)
>> +{
>> +shadow->obj = obj;
>> +shadow->id = id;
>> +
>> +if (data)
>> +memcpy(shadow->data, data, size);
>> +}
> 
> The function name suggests that it is a counterpart of
> klp_shadow_get() but it is not. Which is a bit confusing.
I should have called it "setup" or "init", but perhaps that's moot ...

> Hmm, the purpose of this function is to reduce the size of cut
> code between all that klp_shadow_*attach() variants. But there
> is still too much cut code. In fact, the base logic of all
> variants is basically the same. The only small difference should be
> how they handle the situation when the variable is already there.

... this is true.  An earlier draft revision that I had discarded
attempted combining all cases.  I had used two extra function arguments,
"update" and "duplicates", to key off for each behavior... it turned
into a complicated, full-screen page of conditional logic, so I threw it
out.

However, I like the way you pulled it off using a jump-to-switch
statement at the bottom of the function...

> OK, there is a locking difference in the update variant but
> it is questionable, see below.
>

Re: [PATCH v4] livepatch: introduce shadow variable API

2017-08-18 Thread Joe Lawrence
On 08/17/2017 10:05 AM, Petr Mladek wrote:
> On Mon 2017-08-14 16:02:43, Joe Lawrence wrote:
>> [ ... snip ... ]
>> diff --git a/samples/livepatch/livepatch-shadow-fix1.c 
>> b/samples/livepatch/livepatch-shadow-fix1.c
>> new file mode 100644
>> index ..5acc838463d1
>> --- /dev/null
>> +++ b/samples/livepatch/livepatch-shadow-fix1.c
>> +void livepatch_fix1_dummy_free(struct dummy *d)
>> +{
>> +void **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_detach(d, SV_LEAK);
>> +kfree(*shadow_leak);
> 
> This should get removed. The buffer used for the shadow variable
> is freed by kfree_rcu() called from klp_shadow_detach().
> 
> Same problem is also in the other livepatch.
> 
>> +pr_info("%s: dummy @ %p, prevented leak @ %p\n",
>> + __func__, d, *shadow_leak);
> 
> This might access shadow_leak after it was (double) freed.
> 
>> +} else {
>> +pr_info("%s: dummy @ %p leaked!\n", __func__, d);
>> +}
>> +
>> +kfree(d);
>> +}

Hi Petr,

I think you're half correct.

The kfree is the crux of the memory leak patch, so it needs to stay.
However, the shadow variable is holding a copy of the pointer to the
memory leak area, so you're right that it can't be safely dereferenced
after the shadow variable is detached*.

The code should to be rearranged like:

void livepatch_fix1_dummy_free(struct dummy *d)
{
void **p_shadow_leak, *shadow_leak;

p_shadow_leak = klp_shadow_get(d, SV_LEAK);
if (p_shadow_leak) {
shadow_leak = *p_shadow_leak;   << deref before detach
klp_shadow_detach(d, SV_LEAK);
kfree(shadow_leak);
...

* Aside: I usually develop with slub_debug=FZPU set to catch silly
use-after-frees like this.  However, since the shadow variable is
released via kfree_rcu(), I think there was a window before the grace
period where this one worked out okay...  once I added a
synchronize_rcu() call in between the klp_shadow_detch() and kfree()
calls, I did see the poison pattern.  This is my first time using
kfree_rcu(), so it was interesting to dig into.

Thanks,

-- Joe



Re: [PATCH v4] livepatch: introduce shadow variable API

2017-08-18 Thread Joe Lawrence
On 08/18/2017 10:04 AM, Petr Mladek wrote:
> On Fri 2017-08-18 15:44:29, Nicolai Stange wrote:
>> Joe Lawrence  writes:
>>
>> 
>>> +
>>> +/**
>>> + * klp_shadow_get() - retrieve a shadow variable data pointer
>>> + * @obj:   pointer to parent object
>>> + * @id:data identifier
>>> + *
>>> + * Return: the shadow variable data element, NULL on failure.
>>> + */
>>> +void *klp_shadow_get(void *obj, unsigned long id)
>>> +{
>>> +   struct klp_shadow *shadow;
>>> +
>>> +   rcu_read_lock();
>>> +
>>> +   hash_for_each_possible_rcu(klp_shadow_hash, shadow, node,
>>> +  (unsigned long)obj) {
>>> +
>>> +   if (klp_shadow_match(shadow, obj, id)) {
>>> +   rcu_read_unlock();
>>> +   return shadow->data;
>>
>> I had to think a moment about what protects shadow from getting freed by
>> a concurrent detach after that rcu_read_unlock(). Then I noticed that if
>> obj and the livepatch are alive, then so is shadow, because there
>> obviously hasn't been any reason to detach it.
>>
>> So maybe it would be nice to have an additional comment at
>> klp_shadow_detach() that it's the API user's responsibility not to use a
>> shadow instance after detaching it...

Nicolai, I can add something like "This function releases the memory for
this shadow variable instance, callers should stop referencing it
accordingly."  Similar text for klp_shadow_detach_all().

> Good point. In fact, it might make sense to rename the functions:
> 
>  attach -> create
>  detach -> destroy
> 
> The name detach suggests that the variable is just not connected to
> the parent object but that it is still accessible/usable.

FWIW, kpatch calls them "kpatch_shadow_alloc" and "kpatch_shadow_free".
Now that it's clear that we're not going separate shadow variable
allocation from hash table insertion, going back to alloc/create and
destroy/free is fine w/me.

-- Joe


Re: [PATCH v4] livepatch: introduce shadow variable API

2017-08-18 Thread Joe Lawrence
On 08/17/2017 10:05 AM, Petr Mladek wrote:
> On Mon 2017-08-14 16:02:43, Joe Lawrence wrote:
>> [ ... snip ... ]
>> +/* Allocate a new shadow variable for use inside the lock below */
>> +new_shadow = kzalloc(size + sizeof(*new_shadow), gfp_flags);
> 
> We should print an error message when the memory cannot be allocated.
> Otherwise we will return NULL without explanation. It will be
> especially helpful when a caller forgets to check for NULL.

Interesting, I hadn't seen this checkpatch complaint before:

WARNING: Possible unnecessary 'out of memory' message
#416: FILE: kernel/livepatch/shadow.c:143:
+   if (!new_shadow) {
+   pr_err("failed to allocate shadow variable <0x%p, %lu>\n",

Discussion thread:
https://lkml.org/lkml/2014/6/10/382

Think the stack trace that the memory subsystem would emit is good
enough, or would you like to see  for debugging purposes?

-- Joe


[PATCH v2] livepatch: unpatch all klp_objects if klp_module_coming fails

2017-10-02 Thread Joe Lawrence
When an incoming module is considered for livepatching by
klp_module_coming(), it iterates over multiple patches and multiple
kernel objects in this order:

list_for_each_entry(patch, _patches, list) {
klp_for_each_object(patch, obj) {

which means that if one of the kernel objects fails to patch,
klp_module_coming()'s error path needs to unpatch and cleanup any kernel
objects that were already patched by a previous patch.

Reported-by: Miroslav Benes 
Suggested-by: Petr Mladek 
Signed-off-by: Joe Lawrence 
---
v2:

 - cleanup comment describing the new function
 - s/klp_cleanup_module_objects_limited/klp_cleanup_module_patches_limited
 - added a suggested-by tag for Petr since he suggested both code and
   commentary :)

 kernel/livepatch/core.c | 60 ++---
 1 file changed, 37 insertions(+), 23 deletions(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index b9628e43c78f..bf8c8fd72589 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -830,6 +830,41 @@ int klp_register_patch(struct klp_patch *patch)
 }
 EXPORT_SYMBOL_GPL(klp_register_patch);
 
+/*
+ * Remove parts of patches that touch a given kernel module. The list of
+ * patches processed might be limited. When limit is NULL, all patches
+ * will be handled.
+ */
+static void klp_cleanup_module_patches_limited(struct module *mod,
+  struct klp_patch *limit)
+{
+   struct klp_patch *patch;
+   struct klp_object *obj;
+
+   list_for_each_entry(patch, _patches, list) {
+   if (patch == limit)
+   break;
+
+   klp_for_each_object(patch, obj) {
+   if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
+   continue;
+
+   /*
+* Only unpatch the module if the patch is enabled or
+* is in transition.
+*/
+   if (patch->enabled || patch == klp_transition_patch) {
+   pr_notice("reverting patch '%s' on unloading 
module '%s'\n",
+ patch->mod->name, obj->mod->name);
+   klp_unpatch_object(obj);
+   }
+
+   klp_free_object_loaded(obj);
+   break;
+   }
+   }
+}
+
 int klp_module_coming(struct module *mod)
 {
int ret;
@@ -894,7 +929,7 @@ int klp_module_coming(struct module *mod)
pr_warn("patch '%s' failed for module '%s', refusing to load module 
'%s'\n",
patch->mod->name, obj->mod->name, obj->mod->name);
mod->klp_alive = false;
-   klp_free_object_loaded(obj);
+   klp_cleanup_module_patches_limited(mod, patch);
mutex_unlock(_mutex);
 
return ret;
@@ -902,9 +937,6 @@ int klp_module_coming(struct module *mod)
 
 void klp_module_going(struct module *mod)
 {
-   struct klp_patch *patch;
-   struct klp_object *obj;
-
if (WARN_ON(mod->state != MODULE_STATE_GOING &&
mod->state != MODULE_STATE_COMING))
return;
@@ -917,25 +949,7 @@ void klp_module_going(struct module *mod)
 */
mod->klp_alive = false;
 
-   list_for_each_entry(patch, _patches, list) {
-   klp_for_each_object(patch, obj) {
-   if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
-   continue;
-
-   /*
-* Only unpatch the module if the patch is enabled or
-* is in transition.
-*/
-   if (patch->enabled || patch == klp_transition_patch) {
-   pr_notice("reverting patch '%s' on unloading 
module '%s'\n",
- patch->mod->name, obj->mod->name);
-   klp_unpatch_object(obj);
-   }
-
-   klp_free_object_loaded(obj);
-   break;
-   }
-   }
+   klp_cleanup_module_patches_limited(mod, NULL);
 
mutex_unlock(_mutex);
 }
-- 
1.8.3.1



[PATCH v2 3/3] pipe: add proc_dopipe_max_size() to safely assign pipe_max_size

2017-10-02 Thread Joe Lawrence
pipe_max_size is assigned directly via procfs sysctl:

  static struct ctl_table fs_table[] = {
  ...
  {
  .procname   = "pipe-max-size",
  .data   = _max_size,
  .maxlen = sizeof(int),
  .mode   = 0644,
  .proc_handler   = _proc_fn,
  .extra1 = _min_size,
  },
  ...

  int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
   size_t *lenp, loff_t *ppos)
  {
  ...
  ret = proc_dointvec_minmax(table, write, buf, lenp, ppos)
  ...

and then later rounded in-place a few statements later:

  ...
  pipe_max_size = round_pipe_size(pipe_max_size);
  ...

This leaves a window of time between initial assignment and rounding
that may be visible to other threads.  (For example, one thread sets a
non-rounded value to pipe_max_size while another reads its value.)

Similar reads of pipe_max_size are potentially racey:

  pipe.c :: alloc_pipe_info()
  pipe.c :: pipe_set_size()

Add a new proc_dopipe_max_size() function that consolidates reading the
new value from the user buffer, verifying bounds, and calling
round_pipe_size() with a single assignment to pipe_max_size.

Reported-by: Mikulas Patocka 
Signed-off-by: Joe Lawrence 
---

v2:

 - Fix !CONFIG_PROC_SYSCTL build case

 fs/pipe.c | 16 ++--
 include/linux/pipe_fs_i.h |  1 +
 include/linux/sysctl.h|  3 +++
 kernel/sysctl.c   | 49 +++
 4 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 8cbc97d97753..4db3cd2d139c 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1019,7 +1019,7 @@ static int fifo_open(struct inode *inode, struct file 
*filp)
  * Currently we rely on the pipe array holding a power-of-2 number
  * of pages. Returns 0 on error.
  */
-static inline unsigned int round_pipe_size(unsigned int size)
+unsigned int round_pipe_size(unsigned int size)
 {
unsigned long nr_pages;
 
@@ -1130,19 +1130,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, 
unsigned long arg)
 int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
 size_t *lenp, loff_t *ppos)
 {
-   unsigned int rounded_pipe_max_size;
-   int ret;
-
-   ret = proc_douintvec_minmax(table, write, buf, lenp, ppos);
-   if (ret < 0 || !write)
-   return ret;
-
-   rounded_pipe_max_size = round_pipe_size(pipe_max_size);
-   if (rounded_pipe_max_size == 0)
-   return -EINVAL;
-
-   pipe_max_size = rounded_pipe_max_size;
-   return ret;
+   return proc_dopipe_max_size(table, write, buf, lenp, ppos);
 }
 
 /*
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index e7497c9dde7f..485cf7a7aa8f 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -190,5 +190,6 @@ static inline int pipe_buf_steal(struct pipe_inode_info 
*pipe,
 struct pipe_inode_info *get_pipe_info(struct file *file);
 
 int create_pipe_files(struct file **, int);
+unsigned int round_pipe_size(unsigned int size);
 
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 1d4dba490fb6..ba24ca72800c 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -50,6 +50,9 @@ extern int proc_dointvec_minmax(struct ctl_table *, int,
 extern int proc_douintvec_minmax(struct ctl_table *table, int write,
 void __user *buffer, size_t *lenp,
 loff_t *ppos);
+extern int proc_dopipe_max_size(struct ctl_table *table, int write,
+   void __user *buffer, size_t *lenp,
+   loff_t *ppos);
 extern int proc_dointvec_jiffies(struct ctl_table *, int,
 void __user *, size_t *, loff_t *);
 extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c976719bf37a..30b01b22014d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -67,6 +67,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -2631,6 +2632,47 @@ int proc_douintvec_minmax(struct ctl_table *table, int 
write,
 do_proc_douintvec_minmax_conv, );
 }
 
+struct do_proc_dopipe_max_size_conv_param {
+   unsigned int *min;
+};
+
+static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
+   unsigned int *valp,
+   int write, void *data)
+{
+   struct do_proc_dopipe_max_size_conv_param *param = data;
+
+   if (write) {
+   unsigned int val = round_pipe_size(*lvalp);
+
+   if (val == 0)
+   return -EINVAL;
+
+   if (param->min && *param->min > val)
+   

[PATCH v6 2/3] livepatch: move transition "complete" notice into klp_complete_transition()

2017-10-13 Thread Joe Lawrence
klp_complete_transition() performs a bit of housework before a
transition to KLP_PATCHED or KLP_UNPATCHED is actually completed
(including post-(un)patch callbacks).  To be consistent, move the
transition "complete" kernel log notice out of
klp_try_complete_transition() and into klp_complete_transition().

Suggested-by: Josh Poimboeuf 
Signed-off-by: Joe Lawrence 
Acked-by: Miroslav Benes 
Reviewed-by: Petr Mladek 
---
 kernel/livepatch/transition.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 7bf55b7f3687..53887f0bca10 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -136,6 +136,9 @@ static void klp_complete_transition(void)
klp_post_unpatch_callback(obj);
}
 
+   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
+ klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
/*
 * See complementary comment in __klp_enable_patch() for why we
 * keep the module reference for immediate patches.
@@ -423,9 +426,6 @@ void klp_try_complete_transition(void)
}
 
 success:
-   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
- klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
-
/* we're done, now cleanup the data structures */
klp_complete_transition();
 }
-- 
1.8.3.1



[PATCH v6 3/3] livepatch: add transition notices

2017-10-13 Thread Joe Lawrence
Log a few kernel debug messages at the beginning of the following livepatch
transition functions:

  klp_complete_transition()
  klp_cancel_transition()
  klp_init_transition()
  klp_reverse_transition()

Also update the log notice message in klp_start_transition() for similar
verbiage as the above messages.

Suggested-by: Josh Poimboeuf 
Signed-off-by: Joe Lawrence 
Acked-by: Miroslav Benes 
---
 kernel/livepatch/transition.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 53887f0bca10..56add6327736 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -82,6 +82,10 @@ static void klp_complete_transition(void)
unsigned int cpu;
bool immediate_func = false;
 
+   pr_debug("'%s': completing %s transition\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
if (klp_target_state == KLP_UNPATCHED) {
/*
 * All tasks have transitioned to KLP_UNPATCHED so we can now
@@ -163,6 +167,9 @@ void klp_cancel_transition(void)
if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED))
return;
 
+   pr_debug("'%s': canceling patching transition, going to unpatch\n",
+klp_transition_patch->mod->name);
+
klp_target_state = KLP_UNPATCHED;
klp_complete_transition();
 }
@@ -441,7 +448,8 @@ void klp_start_transition(void)
 
WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
 
-   pr_notice("'%s': %s...\n", klp_transition_patch->mod->name,
+   pr_notice("'%s': starting %s transition\n",
+ klp_transition_patch->mod->name,
  klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
 
/*
@@ -497,6 +505,9 @@ void klp_init_transition(struct klp_patch *patch, int state)
 */
klp_target_state = state;
 
+   pr_debug("'%s': initializing %s transition\n", patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
/*
 * If the patch can be applied or reverted immediately, skip the
 * per-task transitions.
@@ -562,6 +573,11 @@ void klp_reverse_transition(void)
unsigned int cpu;
struct task_struct *g, *task;
 
+   pr_debug("'%s': reversing transition from %s\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching to unpatching" :
+  "unpatching to patching");
+
klp_transition_patch->enabled = !klp_transition_patch->enabled;
 
klp_target_state = !klp_target_state;
-- 
1.8.3.1



[PATCH v6 1/3] livepatch: add (un)patch callbacks

2017-10-13 Thread Joe Lawrence
Provide livepatch modules a klp_object (un)patching notification
mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
setup or synchronize changes that would be difficult to support in only
patched-or-unpatched code contexts.

Callbacks can be registered for target module or vmlinux klp_objects,
but each implementation is klp_object specific.

  - Pre-(un)patch callbacks run before any (un)patching transition
starts.

  - Post-(un)patch callbacks run once an object has been (un)patched and
the klp_patch fully transitioned to its target state.

Example use cases include modification of global data and registration
of newly available services/handlers.

See Documentation/livepatch/callbacks.txt for details and
samples/livepatch/ for examples.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt   | 605 
 include/linux/livepatch.h   |  26 +
 kernel/livepatch/core.c |  51 +-
 kernel/livepatch/core.h |  38 ++
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  21 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-demo.c| 234 +
 samples/livepatch/livepatch-callbacks-mod.c |  53 +++
 10 files changed, 1091 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-busymod.c
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
new file mode 100644
index ..c9776f48e458
--- /dev/null
+++ b/Documentation/livepatch/callbacks.txt
@@ -0,0 +1,605 @@
+==
+(Un)patching Callbacks
+==
+
+Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
+to execute callback functions when a kernel object is (un)patched.  They
+can be considered a "power feature" that extends livepatching abilities
+to include:
+
+  - Safe updates to global data
+
+  - "Patches" to init and probe functions
+
+  - Patching otherwise unpatchable code (i.e. assembly)
+
+In most cases, (un)patch callbacks will need to be used in conjunction
+with memory barriers and kernel synchronization primitives, like
+mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.
+
+Callbacks differ from existing kernel facilities:
+
+  - Module init/exit code doesn't run when disabling and re-enabling a
+patch.
+
+  - A module notifier can't stop a to-be-patched module from loading.
+
+Callbacks are part of the klp_object structure and their implementation
+is specific to that klp_object.  Other livepatch objects may or may not
+be patched, irrespective of the target klp_object's current state.
+
+Callbacks can be registered for the following livepatch actions:
+
+  * Pre-patch- before a klp_object is patched
+
+  * Post-patch   - after a klp_object has been patched and is active
+   across all tasks
+
+  * Pre-unpatch  - before a klp_object is unpatched (ie, patched code is
+   active), used to clean up post-patch callback
+   resources
+
+  * Post-unpatch - after a klp_object has been patched, all code has
+   been restored and no tasks are running patched code,
+   used to cleanup pre-patch callback resources
+
+Each callback is optional, omitting one does not preclude specifying any
+other.  However, the livepatching core executes the handlers in
+symmetry: pre-patch callbacks have a post-unpatch counterpart and
+post-patch callbacks have a pre-unpatch counterpart.  An unpatch
+callback will only be executed if its corresponding patch callback was
+executed.  Typical use cases pair a patch handler that acquires and
+configures resources with an unpatch handler tears down and releases
+those same resources.
+
+A callback is only executed if its host klp_object is loaded.  For
+in-kernel vmlinux targets, this means that callbacks will always execute
+when a livepatch is enabled/disabled.  For patch target kernel modules,
+callbacks will only execute if the target module is loaded.  When a
+module target is (un)loaded, its callbacks will execute only if the
+livepatch module is enabled.
+
+The pre-patch callback, if specified, is expected to return a status
+code (0 for success, -ERRNO on error).  An error status code indicates
+to the livepatching core that patching of the current klp_object is not
+safe and to stop the current patching request.  (When no pre-patch
+callback is provided, the transition is assumed to be safe.)  If a
+pre-patch callback returns failure, the kernel's module loader will:
+

[PATCH v6 0/3] livepatch callbacks

2017-10-13 Thread Joe Lawrence
Another turn of the livepatch callback crank.  This version cleans up
some minor issues found in v5 and was rebased on top of Jiri's branches
listed below.

Unfortunately, I didn't have time to test out Petr's suggestion to move
the pre-patch callback inside klp_patch_object() and the post-unpatch
callback into klp_unpatch_object()... let me know if this is a
deal-breaker (I think it would be possible to revisit this later if
need be.)

Thanks for all the feedback and suggestions thus far!

-- Joe


v6:

- Rebased on-top of jiri_livepatching/
- for-4.14/upstream-fixes
- for-4.15/shadow-variables

Rebasing changes:
  - kernel/livepatch/core.c: code moved from klp_module_going() to
klp_cleanup_module_patches_limited()
  - samples/livepatch/Makefile: patch context changes due to shadow
variable samples

- Documentation
  - s/pare/pair
  - add note about reversed transitions and post-patch/pre-unpatch
callbacks
  - add Josh's extended text about which callbacks will run

- Debug messages
  - Fix pr_debug at beginning of klp_init_transition() to display the
intended target state
  - Expand "canceling patching transition" pr_debug message

- Misc
  - s/callbacks_enabled/post_unpatch_enabled and moved to struct
klp_callbacks per Miroslav's suggestion
  - Added Acked-by and Reviewed-by tags to patches 1 and 2


v5:

- Move code comments from kernel/livepatch/core.h to
  include/linux/livepatch.h's struct klp_callbacks definition

- Change int klp_object.prepatch_callback_status to a bool
  klp_object.callbacks_enabled

  - fixes a hole where returned status=0 wasn't distinguished from
"never-ran" status=0

- Removed a few extraneous checks in the execute callback routines

- In the module-coming case, be sure to execute the post-unpatch
  callback in the event that patching fails

- Moved my Signed-off-by line to the bottom in patches 2 and 3


v4:

- Move callback helpers into core.h

- Move klp_pre_patch_callback() and klp_pre_unpatch_callback()
  invocations into __klp_enable_patch() and __klp_disable_patch()

  - klp_patch_object() and klp_unpatch_objects()
- Do not run pre-unpatch callbacks from here

- Add a pre_patch_status member to klp_object so when a pre-patch
  callback fails, the helpers can skip any post-patch, pre-unpatch,
  post-unpatch callbacks

- klp_module_coming() and klp_module_going()
  - Do not run post-patch or pre-unpatch callbacks for current
klp_transition_patch

- Documentation
  - Add various test cases and provide commentary

- Samples
  - Create two target modules: a simple one and another that invokes a
worker function that sleeps for a long time

- Added two follow-up patches:

  - livepatch: move transition "complete" notice into
klp_complete_transition() - this pushes the "patching complete" message
after the post-patch callbacks

  - livepatch: add transition notices - these were helpful during
debugging of the callback patch.  The transaction annotations were
also used in the Documentation file tese cases to illustrate the
order of operations.


v3:

- livepatch.h
  - drop obj->patched checks from pre/post-(un)patch funcs,
add preceding comment and note about obj->patched assumptions
  - move core.c :: klp_is_module() to here

- klp_complete_transition()
  - fix "else if (klp_target_state == KLP_UNPATCHED)" case
  - combine conditional syntax when avoiding module_put for immediate
patches
  - add check for klp_is_object_loaded to avoid callbacks for any
unloaded modules (necessary after removing obj->patched checks in
livepatch.h)

- Documentation
  - added Josh's use-cases blurb in intro
  - s/Callbacks are only executed/A callbacks is only executed/

- livepatch-callbacks-demo.c
  - whitespace cleanup


v2:
- s/hooks/callbacks/g
- implemented pre-(un)patch and post-(un)patch callbacks
  - pre-patch and pre-unpatch callbacks run from callers of
klp_patch_object() and klp_unpatch_object()
  - post-patch and post-unpatch callbacks run from
klp_complete_transition() and klp_module_coming/going()
- reduce callbacks from a list to a single per-klp_object instance
- revamp the sample callback demo
- revamp documentation

Joe Lawrence (3):
  livepatch: add (un)patch callbacks
  livepatch: move transition "complete" notice into
klp_complete_transition()
  livepatch: add transition notices

 Documentation/livepatch/callbacks.txt   | 605 
 include/linux/livepatch.h   |  26 +
 kernel/livepatch/core.c |  51 +-
 kernel/livepatch/core.h |  38 ++
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  45 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-d

Re: [PATCH v3 0/4] A few round_pipe_size() and pipe-max-size fixups

2017-10-16 Thread Joe Lawrence
On 10/10/2017 02:04 PM, Joe Lawrence wrote:
> While backporting Michael's "pipe: fix limit handling" patchset to a
> distro-kernel, Mikulas noticed that current upstream pipe limit handling
> contains a few problems:
> 
>   1 - procfs signed wrap: echo'ing a large number into
>   /proc/sys/fs/pipe-max-size and then cat'ing it back out shows a
>   negative value.
> 
>   2 - round_pipe_size() nr_pages overflow on 32bit:  this would
>   subsequently try roundup_pow_of_two(0), which is undefined.
> 
>   3 - visible non-rounded pipe-max-size value: there is no mutual
>   exclusion or protection between the time pipe_max_size is assigned
>   a raw value from proc_dointvec_minmax() and when it is rounded.
> 
>   4 - unsigned long -> unsigned int conversion makes for potential odd
>   return errors from do_proc_douintvec_minmax_conv() and
>   do_proc_dopipe_max_size_conv().
> 
> This version underwent the same testing as v1:
> https://marc.info/?l=linux-kernel=150643571406022=2
> 
> v1 (from rfc):
> 
> - Re-arrange patchset order, push smaller fixes to the front
> - Add a check so that round_pipe_size(size < pipe_min_size) will round
>   up to round_pipe_size(pipe_min_size) as per man page [RD]
> - Add new procfs proc_dopipe_max_size() and helpers to consolidate user
>   space read / type validation / rounding / assignment [MP]
> 
> v2:
>  - Fix !CONFIG_PROC_SYSCTL build case [buildbots]
> 
> v3:
>  - s/proc_dointvec_minmax/proc_dopipe_max_size/ in comment 
>preceding pipe_proc_fn()
>  - Added a fourth patch to address -ERANGE vs. -EINVAL inconsistencies in
>do_proc_douintvec_minmax_conv() and do_proc_dopipe_max_size_conv().
> 
> Joe Lawrence (4):
>   pipe: match pipe_max_size data type with procfs
>   pipe: avoid round_pipe_size() nr_pages overflow on 32-bit
>   pipe: add proc_dopipe_max_size() to safely assign pipe_max_size
>   sysctl: check for UINT_MAX before unsigned int min/max
> 
>  fs/pipe.c | 23 ++-
>  include/linux/pipe_fs_i.h |  1 +
>  include/linux/sysctl.h|  3 +++
>  kernel/sysctl.c   | 57 
> ---
>  4 files changed, 70 insertions(+), 14 deletions(-)
> 

Thanks for the reviews, now who do I need to bug to get this merged into
a tree?  :)

v1:
Reviewed-by: Michael Kerrisk 
"Looks good" from Randy Dunlap 

v3:
Reviewed-by: Mikulas Patocka 

-- Joe


[PATCH] livepatch: unpatch all klp_objects if klp_module_coming fails

2017-09-28 Thread Joe Lawrence
When an incoming module is considered for livepatching by
klp_module_coming(), it iterates over multiple patches and multiple
kernel objects in this order:

list_for_each_entry(patch, _patches, list) {
klp_for_each_object(patch, obj) {

which means that if one of the kernel objects fails to patch,
klp_module_coming()'s error path needs to unpatch and cleanup any kernel
objects that were already patched by a previous patch.

Reported-by: Miroslav Benes 
Suggested-by: Petr Mladek 
Signed-off-by: Joe Lawrence 
---
v1:
  - separated this patch from the klp_callbacks patchset
  - adopted Petr's suggestion to reuse code from klp_module_going()

 kernel/livepatch/core.c | 61 ++---
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index b9628e43c78f..3d457e0bbe26 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -830,6 +830,42 @@ int klp_register_patch(struct klp_patch *patch)
 }
 EXPORT_SYMBOL_GPL(klp_register_patch);
 
+/*
+ * Revert patches (up to a given limit) to objects belonging to a given
+ * kernel module.  After unpatching such objects, the function also
+ * frees them.  When limit is NULL, all patches to the given module will
+ * be reverted.
+ */
+static void klp_cleanup_module_objects_limited(struct module *mod,
+  struct klp_patch *limit)
+{
+   struct klp_patch *patch;
+   struct klp_object *obj;
+
+   list_for_each_entry(patch, _patches, list) {
+   if (patch == limit)
+   break;
+
+   klp_for_each_object(patch, obj) {
+   if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
+   continue;
+
+   /*
+* Only unpatch the module if the patch is enabled or
+* is in transition.
+*/
+   if (patch->enabled || patch == klp_transition_patch) {
+   pr_notice("reverting patch '%s' on unloading 
module '%s'\n",
+ patch->mod->name, obj->mod->name);
+   klp_unpatch_object(obj);
+   }
+
+   klp_free_object_loaded(obj);
+   break;
+   }
+   }
+}
+
 int klp_module_coming(struct module *mod)
 {
int ret;
@@ -894,7 +930,7 @@ int klp_module_coming(struct module *mod)
pr_warn("patch '%s' failed for module '%s', refusing to load module 
'%s'\n",
patch->mod->name, obj->mod->name, obj->mod->name);
mod->klp_alive = false;
-   klp_free_object_loaded(obj);
+   klp_cleanup_module_objects_limited(mod, patch);
mutex_unlock(_mutex);
 
return ret;
@@ -902,9 +938,6 @@ int klp_module_coming(struct module *mod)
 
 void klp_module_going(struct module *mod)
 {
-   struct klp_patch *patch;
-   struct klp_object *obj;
-
if (WARN_ON(mod->state != MODULE_STATE_GOING &&
mod->state != MODULE_STATE_COMING))
return;
@@ -917,25 +950,7 @@ void klp_module_going(struct module *mod)
 */
mod->klp_alive = false;
 
-   list_for_each_entry(patch, _patches, list) {
-   klp_for_each_object(patch, obj) {
-   if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
-   continue;
-
-   /*
-* Only unpatch the module if the patch is enabled or
-* is in transition.
-*/
-   if (patch->enabled || patch == klp_transition_patch) {
-   pr_notice("reverting patch '%s' on unloading 
module '%s'\n",
- patch->mod->name, obj->mod->name);
-   klp_unpatch_object(obj);
-   }
-
-   klp_free_object_loaded(obj);
-   break;
-   }
-   }
+   klp_cleanup_module_objects_limited(mod, NULL);
 
mutex_unlock(_mutex);
 }
-- 
1.8.3.1



Re: [PATCH v2 0/7] pipe: buffer limits fixes and cleanups

2018-01-11 Thread Joe Lawrence
On 01/11/2018 12:28 AM, Eric Biggers wrote:
> This series simplifies the sysctl handler for pipe-max-size and fixes
> another set of bugs related to the pipe buffer limits:
> 
> - The root user wasn't allowed to exceed the limits when creating new
>   pipes.
> 
> - There was an off-by-one error when checking the limits, so a limit of
>   N was actually treated as N - 1.
> 
> - F_SETPIPE_SZ accepted values over UINT_MAX.
> 
> - Reading the pipe buffer limits could be racy.
> 
> Changed since v1:
> 
>   - Added "Fixes" tag to "pipe: fix off-by-one error when checking buffer 
> limits"
>   - In pipe_set_size(), checked 'nr_pages' rather than 'size'
>   - Fixed commit message for "pipe: simplify round_pipe_size()"
> 
> Eric Biggers (7):
>   pipe, sysctl: drop 'min' parameter from pipe-max-size converter
>   pipe, sysctl: remove pipe_proc_fn()
>   pipe: actually allow root to exceed the pipe buffer limits
>   pipe: fix off-by-one error when checking buffer limits
>   pipe: reject F_SETPIPE_SZ with size over UINT_MAX
>   pipe: simplify round_pipe_size()
>   pipe: read buffer limits atomically
> 
>  fs/pipe.c | 57 
> ---
>  include/linux/pipe_fs_i.h |  5 ++---
>  include/linux/sysctl.h|  3 ---
>  kernel/sysctl.c   | 33 +--
>  4 files changed, 32 insertions(+), 66 deletions(-)
> 

Bug fixes look good and thanks for continuing the code cleanup!

For the series:
Acked-by: Joe Lawrence 

-- Joe


Re: [PATCH RFC 2/3] pipe: protect pipe_max_size access with a mutex

2017-09-19 Thread Joe Lawrence
On 09/19/2017 03:53 AM, Mikulas Patocka wrote:
> On Fri, 15 Sep 2017, Joe Lawrence wrote:
> [ ... snip ... ]
>> Hi Mikulas,
>>
>> I'm not strong when it comes to memory barriers, but one of the
>> side-effects of using the mutex is that pipe_set_size() and
>> alloc_pipe_info() should have a consistent view of pipe_max_size.
>>
>> If I remove the mutex (and assume that I implement a custom
>> do_proc_dointvec "conv" callback), is it safe for these routines to
>> directly use pipe_max_size as they had done before?
>>
>> If not, is it safe to alias through a temporary stack variable (ie,
>> could the compiler re-read pipe_max_size multiple times in the function)?
>>
>> Would READ_ONCE() help in any way?
> 
> Theoretically re-reading the variable is possible and you should use 
> ACCESS_ONCE or READ_ONCE+WRITE_ONCE on that variable.
> 
> In practice, ACCESS_ONCE/READ_ONCE/WRITE_ONCE is missing at a lot of 
> kernel variables that could be modified asynchronously and no one is 
> complaining about it and no one is making any systematic effort to fix it.
> 
> That re-reading happens (I have some test code that makes the gcc 
> optimizer re-read a variable), but it happens very rarely.

This would be interesting to look at if you are willing to share (can
send offlist).

> Another theoretical problem is that when reading or writing a variable 
> without ACCESS_ONCE, the compiler could read and write the variable using 
> multiple smaller memory accesses. But in practice, it happens only on some 
> non-common architectures.

Smaller access than word size?

>> The mutex covered up some confusion on my part here.
>>
>> OTOH, since pipe_max_size is read-only for pipe_set_size() and
>> alloc_pipe_info() and only updated occasionally by pipe_proc_fn(), would
>> rw_semaphore or RCU be a fit here?
> 
> RW semaphore causes cache-line ping-pong between CPUs, it slows down the 
> kernel just like a normal spinlock or mutex.

Ah right.

> RCU would be useless here (i.e. you don't want to allocate memory and 
> atomically assign it with rcu_assign_pointer).

And good point here.

Thanks for the explanations, they confirm and expand what I as already
thinking in this space.

--- Joe


Re: [PATCH RFC 2/3] pipe: protect pipe_max_size access with a mutex

2017-09-19 Thread Joe Lawrence
On 09/14/2017 07:09 PM, Mikulas Patocka wrote:
> On Tue, 5 Sep 2017, Joe Lawrence wrote:
> 
>> pipe_max_size is assigned directly via procfs sysctl:
>>
>>   static struct ctl_table fs_table[] = {
>>   ...
>>   {
>>   .procname   = "pipe-max-size",
>>   .data   = _max_size,
>>   .maxlen = sizeof(int),
>>   .mode   = 0644,
>>   .proc_handler   = _proc_fn,
>>   .extra1 = _min_size,
>>   },
>>   ...
>>
>>   int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
>>size_t *lenp, loff_t *ppos)
>>   {
>>   ...
>>   ret = proc_dointvec_minmax(table, write, buf, lenp, ppos)
>>   ...
>>
>> and then later rounded in-place a few statements later:
>>
>>   ...
>>   pipe_max_size = round_pipe_size(pipe_max_size);
>>   ...
>>
>> This leaves a window of time between initial assignment and rounding
>> that may be visible to other threads.  (For example, one thread sets a
>> non-rounded value to pipe_max_size while another reads its value.)
>>
>> Similar reads of pipe_max_size are potentially racey:
>>
>>   pipe.c :: alloc_pipe_info()
>>   pipe.c :: pipe_set_size()
>>
>> Protect them and the procfs sysctl assignment with a mutex.
>>
>> Reported-by: Mikulas Patocka 
>> Signed-off-by: Joe Lawrence 
>> ---
>>  fs/pipe.c | 28 
>>  1 file changed, 24 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/pipe.c b/fs/pipe.c
>> index fa28910b3c59..33bb11b0d78e 100644
>> --- a/fs/pipe.c
>> +++ b/fs/pipe.c
>> @@ -35,6 +35,11 @@
>>  unsigned int pipe_max_size = 1048576;
>>  
>>  /*
>> + * Provide mutual exclusion around access to pipe_max_size
>> + */
>> +static DEFINE_MUTEX(pipe_max_mutex);
>> +
>> +/*
>>   * Minimum pipe size, as required by POSIX
>>   */
>>  unsigned int pipe_min_size = PAGE_SIZE;
>> @@ -623,13 +628,18 @@ struct pipe_inode_info *alloc_pipe_info(void)
>>  unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
>>  struct user_struct *user = get_current_user();
>>  unsigned long user_bufs;
>> +unsigned int max_size;
>>  
>>  pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
>>  if (pipe == NULL)
>>  goto out_free_uid;
>>  
>> -if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
>> -pipe_bufs = pipe_max_size >> PAGE_SHIFT;
>> +mutex_lock(_max_mutex);
>> +max_size = pipe_max_size;
>> +mutex_unlock(_max_mutex);
>> +
>> +if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
>> +pipe_bufs = max_size >> PAGE_SHIFT;
>>  
>>  user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
>>  
>> @@ -1039,6 +1049,7 @@ static long pipe_set_size(struct pipe_inode_info 
>> *pipe, unsigned long arg)
>>  struct pipe_buffer *bufs;
>>  unsigned int size, nr_pages;
>>  unsigned long user_bufs;
>> +unsigned int max_size;
>>  long ret = 0;
>>  
>>  size = round_pipe_size(arg);
>> @@ -1056,8 +1067,11 @@ static long pipe_set_size(struct pipe_inode_info 
>> *pipe, unsigned long arg)
>>   * Decreasing the pipe capacity is always permitted, even
>>   * if the user is currently over a limit.
>>   */
>> +mutex_lock(_max_mutex);
>> +max_size = pipe_max_size;
>> +mutex_unlock(_max_mutex);
>>  if (nr_pages > pipe->buffers &&
>> -size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
>> +size > max_size && !capable(CAP_SYS_RESOURCE))
>>  return -EPERM;
>>  
>>  user_bufs = account_pipe_buffers(pipe->user, pipe->buffers, nr_pages);
>> @@ -1131,18 +1145,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, 
>> void __user *buf,
>>  unsigned int rounded_pipe_max_size;
>>  int ret;
>>  
>> +mutex_lock(_max_mutex);
>>  orig_pipe_max_size = pipe_max_size;
>>  ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
>> -if (ret < 0 || !write)
>> +if (ret < 0 || !write) {
>> +mutex_unlock(_max_mutex);
>>  return ret;
>> +}

Re: [RFC] livepatch: unpatch all klp_objects if klp_module_coming fails

2017-09-20 Thread Joe Lawrence
On Wed, Sep 20, 2017 at 01:19:05PM +0200, Miroslav Benes wrote:
> On Wed, 13 Sep 2017, Joe Lawrence wrote:
> 
> > Hi Miroslav,
> 
> Hi,
> 
> sorry for the late response. I'm also travelling now and we have SUSECon 
> conference next week, so just a quick answer. It looks ok at first glance, 
> but I need to take a proper look.

No problem, thanks for the update and safe travels.
 
> > I worked out the code that I posted earlier today and I think this could
> > address the multiple-patch module_coming() issue you pointed out.
> > 
> > Note that this was tacked onto the end of the "[PATCH v5 0/3] livepatch
> > callbacks" patchset, so it includes unpatching callbacks.  I can easily
> > strip those out (and remove the additional debugging pr_'s) and make
> > this a stand-alone patch that would apply before the callback patchset.
> 
> I think this would be better. Strip callbacks out and send this either 
> separately (and base callbacks patch set on this), or make it 1/n of the 
> series.

Agreed.

> > See the test case below.
> > 
> > -- Joe
> > 
> > Test X
> > --
> > 
> > Multiple livepatches targeting the same klp_objects may be loaded at
> > the same time.  If a target module loads and any of the livepatch's
> > pre-patch callbacks fail, then the module is not allowed to load.
> > Furthermore, any livepatches that that did succeed will be reverted
> > (only the incoming module / klp_object) and their pre/post-unpatch
> > callbacks executed.
> > 
> >   - load livepatch
> >   - load livepatch2
> >   - load livepatch3
> >   - setup livepatch3 pre-patch return of -ENODEV
> >   - load target module (should fail)
> >   - disable livepatch3
> >   - disable livepatch2
> >   - disable livepatch
> >   - unload livepatch3
> >   - unload livepatch2
> >   - unload livepatch
> > 
> > 
> > Load three livepatches, each target a livepatch_callbacks_mod module and
> > vmlinux:
> > 
> >   % insmod samples/livepatch/livepatch-callbacks-demo.ko 
> >   [   26.032048] livepatch_callbacks_demo: module verification failed: 
> > signature and/or required key missing - tainting kernel
> >   [   26.033701] livepatch: enabling patch 'livepatch_callbacks_demo'
> >   [   26.034294] livepatch_callbacks_demo: pre_patch_callback: vmlinux
> >   [   26.034850] livepatch: 'livepatch_callbacks_demo': starting patching 
> > transition
> >   [   27.743212] livepatch_callbacks_demo: post_patch_callback: vmlinux
> >   [   27.744130] livepatch: 'livepatch_callbacks_demo': patching complete
> > 
> >   % insmod samples/livepatch/livepatch-callbacks-demo2.ko 
> >   [   29.120553] livepatch: enabling patch 'livepatch_callbacks_demo2'
> >   [   29.121077] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
> >   [   29.121610] livepatch: 'livepatch_callbacks_demo2': starting patching 
> > transition
> >   [   30.751215] livepatch_callbacks_demo2: post_patch_callback: vmlinux
> >   [   30.751786] livepatch: 'livepatch_callbacks_demo2': patching complete
> > 
> >   % insmod samples/livepatch/livepatch-callbacks-demo3.ko 
> >   [   32.144285] livepatch: enabling patch 'livepatch_callbacks_demo3'
> >   [   32.144779] livepatch_callbacks_demo3: pre_patch_callback: vmlinux
> >   [   32.145360] livepatch: 'livepatch_callbacks_demo3': starting patching 
> > transition
> >   [   33.695211] livepatch_callbacks_demo3: post_patch_callback: vmlinux
> >   [   33.695739] livepatch: 'livepatch_callbacks_demo3': patching complete
> > 
> > Setup the third livepatch to fail its pre-patch callback when the target
> > module is loaded:
> > 
> >   % echo samples/livepatch/livepatch-callbacks-demo3.ko > 
> > /sys/module/livepatch_callbacks_demo3/parameters/pre_patch_ret
> > 
> > Load the target module:
> > 
> >   % insmod samples/livepatch/livepatch-callbacks-mod.ko 
> > 
> > The first livepatch pre-patch callback succeeds, the klp_object is
> > patched, and its post-patch callback is executed:
> > 
> >   [   38.210512] livepatch: applying patch 'livepatch_callbacks_demo' to 
> > loading module 'livepatch_callbacks_mod'
> >   [   38.211430] livepatch_callbacks_demo: pre_patch_callback: 
> > livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
> > module_init
> >   [   38.212426] livepatch: JL: klp_patch_object(c02a9128) 
> > patch=c02a9000 obj->name: livepatch_callbacks_mod
> >   [   38.213243] livepatch_callbacks_demo: post_patch_callback: 
> > livepatch_callbacks_mod ->

Re: [PATCH v3] livepatch: introduce shadow variable API

2017-08-10 Thread Joe Lawrence
On Thu, Aug 10, 2017 at 04:40:05PM +0200, Miroslav Benes wrote:
> 
> It generally looks ok. Only few questions below...
> 
> [...]
> 
> > +In-flight parent objects
> > +
> > +   ps_lock = klp_shadow_get_or_attach(sta, PS_LOCK,
> > +   _lock_fallback, sizeof(ps_lock_fallback),
> > +   GFP_ATOMIC);
> > +
> > +   ps_lock = klp_shadow_get(sta, PS_LOCK);
> > +   if (ps_lock)
> > +   spin_lock(ps_lock);
> 
> ps_lock = klp_shadow_get(sta, PS_LOCK); should not be needed, should it?

Correct, I'll remove it.

> [...]
> 
> > +/*
> > + * klp_shadow_set() - initialize a shadow variable
> > + * @shadow:shadow variable to initialize
> > + * @obj:   pointer to parent object
> > + * @id:data identifier
> > + * @data:  pointer to data to attach to parent
> > + * @size:  size of attached data
> > + */
> > +static inline void klp_shadow_set(struct klp_shadow *shadow, void *obj,
> > + unsigned long id, void *data, size_t size)
> > +{
> > +   shadow->obj = obj;
> > +   shadow->id = id;
> > +
> > +   if (data)
> > +   memcpy(shadow->data, data, size);
> > +}
> > +
> > +/**
> > + * klp_shadow_add() - add a shadow variable to the hashtable
> > + * @shadow:shadow variable to add
> > + */
> > +static inline void klp_shadow_add(struct klp_shadow *shadow)
> > +{
> > +   hash_add_rcu(klp_shadow_hash, >node,
> > +(unsigned long)shadow->obj);
> > +}
> 
> It would be nice to add a comment that a caller must hold klp_shadow_lock 
> spinlock.

Since shadow_match(), klp_shadow_set(), and klp_shadow_add() are all in
the same boat, I can mention the lock for those functions as well.  BTW,
is there a convention to drop the "klp_" for static, local routines?  I
should be consistent here.
 
> > +void *klp_shadow_attach(void *obj, unsigned long id, void *data,
> > +   size_t size, gfp_t gfp_flags)
> > +   return shadow_data;
> 
> I may be missing something, but shouldn't this return new_shadow->data? 
> You return original data here which seems strange.
> 
> > +void *klp_shadow_get_or_attach(void *obj, unsigned long id, void *data,
> > +  size_t size, gfp_t gfp_flags)
> > +   shadow_data = data;
> 
> Again. "shadow_data = new_shadow->data;"?
> 
> > +void *klp_shadow_update_or_attach(void *obj, unsigned long id, void *data,
> > + size_t size, gfp_t gfp_flags)
> > +   shadow_data = data;
> 
> Dtto.
> 

Gah!  Thank you for spotting this!  It was leftover from v1 when there
were only pointers (and not data copies) being thrown about.

Thanks,

-- Joe


[PATCH v5] shadow variables

2017-08-21 Thread Joe Lawrence
v5:

- Adopt Petr's suggested combined __klp_shadow_get_or_attach() routine
- API
  - s/klp_shadow_attach/klp_shadow_alloc/g
  - s/klp_shadow_get_or_attach/klp_shadow_get_or_alloc/g
  - s/klp_shadow_detach/klp_shadow_free/g
  - remove klp_shadow_update_or_attach()
- Code comments
  - Add Petr's description for klp_shadow_get_or_alloc()
  - Swap paragraphs in klp_shadow_alloc() description
  - Add short description of klp_shadow_lock
  - Remove incorrect klp_shadow_lock comment in klp_shadow_match() and
klp_shadow_set()
  - Add a use-after-free disclaimer to klp_shadow_free() and
klp_shadow_free_all()
- Samples: Fix use-after-free in memory leak fix modules
- Doc: Simplify code in sta_info_free() use-case

Joe Lawrence (1):
  livepatch: introduce shadow variable API

 Documentation/livepatch/shadow-vars.txt   | 191 +++
 include/linux/livepatch.h |   8 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 296 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 173 +
 samples/livepatch/livepatch-shadow-fix2.c | 168 +
 samples/livepatch/livepatch-shadow-mod.c  | 224 ++
 9 files changed, 1066 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

-- 
1.8.3.1



[PATCH v5] livepatch: introduce shadow variable API

2017-08-21 Thread Joe Lawrence
Add exported API for livepatch modules:

  klp_shadow_get()
  klp_shadow_alloc()
  klp_shadow_get_or_alloc()
  klp_shadow_free()
  klp_shadow_free_all()

that implement "shadow" variables, which allow callers to associate new
shadow fields to existing data structures.  This is intended to be used
by livepatch modules seeking to emulate additions to data structure
definitions.

See Documentation/livepatch/shadow-vars.txt for a summary of the new
shadow variable API, including a few common use cases.

See samples/livepatch/livepatch-shadow-* for example modules that
demonstrate shadow variables.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt   | 191 +++
 include/linux/livepatch.h |   8 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 295 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 173 ++
 samples/livepatch/livepatch-shadow-fix2.c | 168 +
 samples/livepatch/livepatch-shadow-mod.c  | 224 +++
 9 files changed, 1065 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
new file mode 100644
index ..d7558a1e4797
--- /dev/null
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -0,0 +1,191 @@
+
+Shadow Variables
+
+
+Shadow variables are a simple way for livepatch modules to associate
+additional "shadow" data with existing data structures.  Shadow data is
+allocated separately from parent data structures, which are left
+unmodified.  The shadow variable API described in this document is used
+to allocate/attach and detach/release shadow variables to their parents.
+
+The implementation introduces a global, in-kernel hashtable that
+associates pointers to parent objects and a numeric identifier of the
+shadow data.  The numeric identifier is a simple enumeration that may be
+used to describe shadow variable version, class or type, etc.  More
+specifically, the parent pointer serves as the hashtable key while the
+numeric id subsequently filters hashtable queries.  Multiple shadow
+variables may attach to the same parent object, but their numeric
+identifier distinguishes between them.
+
+
+1. Brief API summary
+
+
+(See the full API usage docbook notes in livepatch/shadow.c.)
+
+A hashtable references all shadow variables.  These references are
+stored and retrieved through a  pair.
+
+* The klp_shadow variable data structure encapsulates both tracking
+meta-data and shadow-data:
+  - meta-data
+- obj - pointer to parent object
+- id - data identifier
+  - data[] - storage for shadow data
+
+  It is important to note that the klp_shadow_alloc() and
+  klp_shadow_get_or_alloc() calls, described below, store a *copy* of
+  the data that the functions are provided.
+
+* klp_shadow_get() - retrieve a shadow variable data pointer
+  - search hashtable for  pair
+
+* klp_shadow_alloc() - allocate and add a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- WARN and return NULL
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  to the global hashtable
+
+* klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_free() - detach and free a  shadow variable
+  - find and remove a  reference from global hashtable
+- if found, free shadow variable
+
+* klp_shadow_free_all() - detach and free all <*, id> shadow variables
+  - find and remove any <*, id> references from global hashtable
+- if found, free shadow variable
+
+
+2. Use cases
+
+
+(See the example shadow variable livepatch modules in samples/livepatch/
+for full working demonstrations.)
+
+For the following use-case examples, consider commit 1d147bfa6429
+("mac80211: fix AP powersave TX vs.  wakeup race"), which added a
+spinlock to net/mac80211/sta_info.h :: struct sta_info.  Each use-case
+example can be considered a stand-alone livepatch implementation of this
+fix.
+
+
+Matching parent's lifecycle
+---
+
+If parent data structures are frequently created and destroyed, it may
+be easiest

Re: [PATCH v3] livepatch: add (un)patch callbacks

2017-08-21 Thread Joe Lawrence
On Fri, Aug 18, 2017 at 03:58:16PM +0200, Petr Mladek wrote:
> On Wed 2017-08-16 15:17:04, Joe Lawrence wrote:
> > Provide livepatch modules a klp_object (un)patching notification
> > mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
> > setup or synchronize changes that would be difficult to support in only
> > patched-or-unpatched code contexts.
> > 
> > diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
> > index 194991ef9347..500dc9b2b361 100644
> > --- a/include/linux/livepatch.h
> > +++ b/include/linux/livepatch.h
> > @@ -138,6 +154,71 @@ struct klp_patch {
> >  func->old_name || func->new_func || func->old_sympos; \
> >  func++)
> >  
> > +/**
> > + * klp_is_object_loaded() - is klp_object currently loaded?
> > + * @obj:   klp_object pointer
> > + *
> > + * Return: true if klp_object is loaded (always true for vmlinux)
> > + */
> > +static inline bool klp_is_object_loaded(struct klp_object *obj)
> > +{
> > +   return !obj->name || obj->mod;
> > +}
> > +
> > +/**
> > + * klp_pre_patch_callback - execute before klp_object is patched
> > + * @obj:   invoke callback for this klp_object
> > + *
> > + * Return: status from callback
> > + *
> > + * Callers should ensure obj->patched is *not* set.
> > + */
> > +static inline int klp_pre_patch_callback(struct klp_object *obj)
> > +{
> > +   if (obj->callbacks.pre_patch)
> > +   return (*obj->callbacks.pre_patch)(obj);
> > +   return 0;
> > +}
> > +
> > +/**
> > + * klp_post_patch_callback() - execute after klp_object is patched
> > + * @obj:   invoke callback for this klp_object
> > + *
> > + * Callers should ensure obj->patched is set.
> > + */
> > +static inline void klp_post_patch_callback(struct klp_object *obj)
> > +{
> > +   if (obj->callbacks.post_patch)
> > +   (*obj->callbacks.post_patch)(obj);
> > +}
> > +
> > +/**
> > + * klp_pre_unpatch_callback() - execute before klp_object is unpatched
> > + *  and is active across all tasks
> > + * @obj:   invoke callback for this klp_object
> > + *
> > + * Callers should ensure obj->patched is set.
> > + */
> > +static inline void klp_pre_unpatch_callback(struct klp_object *obj)
> > +{
> > +   if (obj->callbacks.pre_unpatch)
> > +   (*obj->callbacks.pre_unpatch)(obj);
> > +}
> > +
> > +/**
> > + * klp_post_unpatch_callback() - execute after klp_object is unpatched,
> > + *   all code has been restored and no tasks
> > + *   are running patched code
> > + * @obj:   invoke callback for this klp_object
> > + *
> > + * Callers should ensure obj->patched is *not* set.
> > + */
> > +static inline void klp_post_unpatch_callback(struct klp_object *obj)
> > +{
> > +   if (obj->callbacks.post_unpatch)
> > +   (*obj->callbacks.post_unpatch)(obj);
> > +}
> 
> I guess that we do not want to make these function usable
> outside livepatch code. Thefore these inliners should go
> to kernel/livepatch/core.h or so.

Okay, I can stash them away in an internal header file like core.h.

> > +
> >  int klp_register_patch(struct klp_patch *);
> >  int klp_unregister_patch(struct klp_patch *);
> >  int klp_enable_patch(struct klp_patch *);
> > diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
> > index b9628e43c78f..ddb23e18a357 100644
> > --- a/kernel/livepatch/core.c
> > +++ b/kernel/livepatch/core.c
> > @@ -878,6 +890,8 @@ int klp_module_coming(struct module *mod)
> > goto err;
> > }
> >  
> > +   klp_post_patch_callback(obj);
> 
> This should be called only if (patch != klp_transition_patch).
> Otherwise, it would be called too early.

Can you elaborate a bit on this scenario?  When would the transition
patch (as I understand it, a livepatch not quite fully (un)patched) hit
the module coming/going notifier?  Is it possible to load or unload a
module like this?  I'd like to add this scenario to my test script if
possible.
 
> > +
> > break;
> > }
> > }
> > @@ -929,7 +943,10 @@ void klp_module_going(struct module *mod)
> > if (patch->enabled || patch == klp_transition_patch) {
> > pr_notice("reverting patch '%s' on unloading 
> > module

[PATCH v4 2/3] livepatch: move transition "complete" notice into klp_complete_transition()

2017-08-25 Thread Joe Lawrence
klp_complete_transition() performs a bit of housework before a
transition to KLP_PATCHED or KLP_UNPATCHED is actually completed
(including post-(un)patch callbacks).  To be consistent, move the
transition "complete" kernel log notice out of
klp_try_complete_transition() and into klp_complete_transition().

Signed-off-by: Joe Lawrence 
Suggested-by: Josh Poimboeuf 
---
 kernel/livepatch/transition.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 7bf55b7f3687..53887f0bca10 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -136,6 +136,9 @@ static void klp_complete_transition(void)
klp_post_unpatch_callback(obj);
}
 
+   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
+ klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
/*
 * See complementary comment in __klp_enable_patch() for why we
 * keep the module reference for immediate patches.
@@ -423,9 +426,6 @@ void klp_try_complete_transition(void)
}
 
 success:
-   pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
- klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
-
/* we're done, now cleanup the data structures */
klp_complete_transition();
 }
-- 
1.8.3.1



[PATCH v4 3/3] livepatch: add transition notices

2017-08-25 Thread Joe Lawrence
Log a few kernel debug messages at the beginning of the following livepatch
transition functions:

  klp_complete_transition()
  klp_cancel_transition()
  klp_init_transition()
  klp_reverse_transition()

Also update the log notice message in klp_start_transition() for similar
verbiage as the above messages.

Signed-off-by: Joe Lawrence 
Suggested-by: Josh Poimboeuf 
---
 kernel/livepatch/transition.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 53887f0bca10..3d44a3cf27be 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -82,6 +82,10 @@ static void klp_complete_transition(void)
unsigned int cpu;
bool immediate_func = false;
 
+   pr_debug("'%s': completing %s transition\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
if (klp_target_state == KLP_UNPATCHED) {
/*
 * All tasks have transitioned to KLP_UNPATCHED so we can now
@@ -163,6 +167,9 @@ void klp_cancel_transition(void)
if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED))
return;
 
+   pr_debug("'%s': canceling transition, unpatching\n",
+klp_transition_patch->mod->name);
+
klp_target_state = KLP_UNPATCHED;
klp_complete_transition();
 }
@@ -441,7 +448,8 @@ void klp_start_transition(void)
 
WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
 
-   pr_notice("'%s': %s...\n", klp_transition_patch->mod->name,
+   pr_notice("'%s': starting %s transition\n",
+ klp_transition_patch->mod->name,
  klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
 
/*
@@ -489,6 +497,9 @@ void klp_init_transition(struct klp_patch *patch, int state)
 
WARN_ON_ONCE(klp_target_state != KLP_UNDEFINED);
 
+   pr_debug("'%s': initializing %s transition\n", patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
+
klp_transition_patch = patch;
 
/*
@@ -562,6 +573,11 @@ void klp_reverse_transition(void)
unsigned int cpu;
struct task_struct *g, *task;
 
+   pr_debug("'%s': reversing transition from %s\n",
+klp_transition_patch->mod->name,
+klp_target_state == KLP_PATCHED ? "patching to unpatching" :
+  "unpatching to patching");
+
klp_transition_patch->enabled = !klp_transition_patch->enabled;
 
klp_target_state = !klp_target_state;
-- 
1.8.3.1



[PATCH v4 1/3] livepatch: add (un)patch callbacks

2017-08-25 Thread Joe Lawrence
Provide livepatch modules a klp_object (un)patching notification
mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
setup or synchronize changes that would be difficult to support in only
patched-or-unpatched code contexts.

Callbacks can be registered for target module or vmlinux klp_objects,
but each implementation is klp_object specific.

  - Pre-(un)patch callbacks run before any (un)patching transition
starts.

  - Post-(un)patch callbacks run once an object has been (un)patched and
the klp_patch fully transitioned to its target state.

Example use cases include modification of global data and registration
of newly available services/handlers.

See Documentation/livepatch/callbacks.txt for details and
samples/livepatch/ for examples.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt   | 595 
 include/linux/livepatch.h   |  18 +
 kernel/livepatch/core.c |  56 ++-
 kernel/livepatch/core.h |  78 
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  21 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-demo.c| 234 ++
 samples/livepatch/livepatch-callbacks-mod.c |  55 +++
 10 files changed, 1120 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-busymod.c
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
new file mode 100644
index ..c44825777c28
--- /dev/null
+++ b/Documentation/livepatch/callbacks.txt
@@ -0,0 +1,595 @@
+==
+(Un)patching Callbacks
+==
+
+Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
+to execute callback functions when a kernel object is (un)patched.  They
+can be considered a "power feature" that extends livepatching abilities
+to include:
+
+  - Safe updates to global data
+
+  - "Patches" to init and probe functions
+
+  - Patching otherwise unpatchable code (i.e. assembly)
+
+In most cases, (un)patch callbacks will need to be used in conjunction
+with memory barriers and kernel synchronization primitives, like
+mutexes/spinlocks, or even stop_machine(), to avoid concurrency issues.
+
+Callbacks differ from existing kernel facilities:
+
+  - Module init/exit code doesn't run when disabling and re-enabling a
+patch.
+
+  - A module notifier can't stop a to-be-patched module from loading.
+
+Callbacks are part of the klp_object structure and their implementation
+is specific to that klp_object.  Other livepatch objects may or may not
+be patched, irrespective of the target klp_object's current state.
+
+Callbacks can be registered for the following livepatch actions:
+
+  * Pre-patch- before a klp_object is patched
+
+  * Post-patch   - after a klp_object has been patched and is active
+   across all tasks
+
+  * Pre-unpatch  - before a klp_object is unpatched (ie, patched code is
+   active), used to clean up post-patch callback
+   resources
+
+  * Post-unpatch - after a klp_object has been patched, all code has
+   been restored and no tasks are running patched code,
+   used to cleanup pre-patch callback resources
+
+Each callback action is optional, omitting one does not preclude
+specifying any other.  Typical use cases however, pare a pre-patch with
+a post-unpatch handler and a post-patch with a pre-unpatch handler in
+symmetry: the patch handler acquires and configures resources and the
+unpatch handler tears down and releases those same resources.
+
+A callback is only executed if its host klp_object is loaded.  For
+in-kernel vmlinux targets, this means that callbacks will always execute
+when a livepatch is enabled/disabled.  For patch target kernel modules,
+callbacks will only execute if the target module is loaded.  When a
+module target is (un)loaded, its callbacks will execute only if the
+livepatch module is enabled.
+
+The pre-patch callback, if specified, is expected to return a status
+code (0 for success, -ERRNO on error).  An error status code indicates
+to the livepatching core that patching of the current klp_object is not
+safe and to stop the current patching request.  (When no pre-patch
+callback is provided, the transition is assumed to be safe.)  If a
+pre-patch callback returns failure, the kernel's module loader will:
+
+  - Refuse to load a livepatch, if the livepatch is loaded after
+targeted code.
+
+or:
+
+  - Refuse to load a module, if the livepatch was already succ

[PATCH v4 0/3] livepatch callbacks

2017-08-25 Thread Joe Lawrence
v4:

- Move callback helpers into core.h

- Move klp_pre_patch_callback() and klp_pre_unpatch_callback()
  invocations into __klp_enable_patch() and __klp_disable_patch()

  - klp_patch_object() and klp_unpatch_objects()
- Do not run pre-unpatch callbacks from here

- Add a pre_patch_status member to klp_object so when a pre-patch
  callback fails, the helpers can skip any post-patch, pre-unpatch,
  post-unpatch callbacks

- klp_module_coming() and klp_module_going()
  - Do not run post-patch or pre-unpatch callbacks for current
klp_transition_patch

- Documentation
  - Add various test cases and provide commentary

- Samples
  - Create two target modules: a simple one and another that invokes a
worker function that sleeps for a long time

- Added two follow-up patches:

  - livepatch: move transition "complete" notice into
klp_complete_transition() - this pushes the "patching complete" message
after the post-patch callbacks

  - livepatch: add transition notices - these were helpful during
debugging of the callback patch.  The transaction annotations were
also used in the Documentation file tese cases to illustrate the
order of operations.

  Note that these two patches could be standalone, I include them here
  in this patchset since they affect the content/ordering of kernel logs
  that were included as part of the Documentation.

Joe Lawrence (3):
  livepatch: add (un)patch callbacks
  livepatch: move transition "complete" notice into
klp_complete_transition()
  livepatch: add transition notices

 Documentation/livepatch/callbacks.txt   | 595 
 include/linux/livepatch.h   |  18 +
 kernel/livepatch/core.c |  56 ++-
 kernel/livepatch/core.h |  78 
 kernel/livepatch/patch.c|   1 +
 kernel/livepatch/transition.c   |  45 +-
 samples/livepatch/Makefile  |   3 +
 samples/livepatch/livepatch-callbacks-busymod.c |  72 +++
 samples/livepatch/livepatch-callbacks-demo.c| 234 ++
 samples/livepatch/livepatch-callbacks-mod.c |  55 +++
 10 files changed, 1140 insertions(+), 17 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-busymod.c
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

-- 
1.8.3.1



[PATCH v2 0/1] add (un)patch callbacks

2017-08-08 Thread Joe Lawrence
Hi folks,

This is v2 of the livepatch (un)patch hook/notifier/callback/etc code.

The documentation is still a little rough, but I wanted to post up the
code for feedback before getting too far in revising it.

This implements the pre and post handlers as Josh suggested.  See
summary of related changes below...

v2:
- s/hooks/callbacks/g
- implemented pre-(un)patch and post-(un)patch callbacks
  - pre-patch and pre-unpatch callbacks run from callers of
klp_patch_object() and klp_unpatch_object()
  - post-patch and post-unpatch callbacks run from
klp_complete_transition() and klp_module_coming/going()
- reduce callbacks from a list to a single per-klp_object instance
- revamp the sample callback demo
- revamp documentation

Feedback appreciated as always.

Joe Lawrence (1):
  livepatch: add (un)patch callbacks

 Documentation/livepatch/callbacks.txt|  75 +++
 include/linux/livepatch.h|  38 ++
 kernel/livepatch/core.c  |  30 -
 kernel/livepatch/patch.c |   5 +-
 kernel/livepatch/transition.c|  19 ++-
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-callbacks-demo.c | 180 +++
 samples/livepatch/livepatch-callbacks-mod.c  |  53 
 8 files changed, 393 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

-- 
1.8.3.1



[PATCH v2 1/1] livepatch: add (un)patch callbacks

2017-08-08 Thread Joe Lawrence
Provide livepatch modules a klp_object (un)patching notification
mechanism.  Pre and post-(un)patch callbacks allow livepatch modules to
setup or synchronize changes that would be difficult to support in only
patched-or-unpatched code contexts.

Callbacks can be registered for target module or vmlinux klp_objects,
but each implementation is klp_object specific.

  - Pre-(un)patch callbacks run before any (un)patching action takes
place.

  - Post-(un)patch callbacks run once an object has been (un)patched and
the klp_patch fully transitioned to its target state.

Example use cases include modification of global data and registration
of newly available services/handlers.

See Documentation/livepatch/callback.txt for details.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt|  75 +++
 include/linux/livepatch.h|  38 ++
 kernel/livepatch/core.c  |  32 -
 kernel/livepatch/patch.c |   5 +-
 kernel/livepatch/transition.c|  19 ++-
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-callbacks-demo.c | 190 +++
 samples/livepatch/livepatch-callbacks-mod.c  |  53 
 8 files changed, 405 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/livepatch/callbacks.txt
 create mode 100644 samples/livepatch/livepatch-callbacks-demo.c
 create mode 100644 samples/livepatch/livepatch-callbacks-mod.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
new file mode 100644
index ..d78f9ba9f74c
--- /dev/null
+++ b/Documentation/livepatch/callbacks.txt
@@ -0,0 +1,75 @@
+(Un)patching Callbacks
+==
+
+Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
+to execute callback functions when a kernel object is (un)patched.
+
+These callbacks differ from existing kernel facilities:
+
+  - Module init/exit code doesn't run when disabling and re-enabling a
+patch.
+
+  - A module notifier can't stop the to-be-patched module from loading.
+
+Callbacks are part of the klp_object structure and their implementation
+is specific to the given object.  Other livepatch objects may or may not
+be patched, irrespective of the target klp_object's current state.
+
+Callbacks can be registered for the following livepatch actions:
+
+  * Pre-patch- before klp_object is patched
+
+  * Post-patch   - after klp_object has been patched and is active
+   across all tasks
+
+  * Pre-unpatch  - before klp_object is unpatched, patched code is active
+
+  * Post-unpatch - after klp_object has been patched, all code has been
+  restored and no tasks are running patched code
+
+Callbacks are only executed if its host klp_object is loaded.  For
+in-kernel vmlinux targets, this means that callbacks will always execute
+when a livepatch is enabled/disabled.
+
+For kernel module targets, callbacks will only execute if the target
+module is loaded.  When a kernel module target is (un)loaded, its
+callbacks will execute only if the livepatch module is enabled.
+
+The pre-patch callback is expected to return a status code (0 for
+success, -ERRNO on error).  An error status code will indicate to the
+livepatching core that patching of the current klp_object is not safe
+and to stop the current patching request.  If the problematic klp_object
+is already loaded (i.e. a livepatch is loaded after target code), the
+kernel's module loader will refuse to load the livepatch.  On the other
+hand, if the problematic klp_object is already in place (i.e. a target
+module is loaded after a livepatch), then the module loader will refuse
+to load the target kernel module.
+
+
+Example Use-cases
+-
+
+1 - Update global data
+
+A pre-patch callback can be useful to update a global variable.  For
+example, 75ff39ccc1bd ("tcp: make challenge acks less predictable")
+changes a global sysctl, as well as patches the tcp_send_challenge_ack()
+function.
+
+In this case, if we're being super paranoid, it might make sense to
+patch the data *after* patching is complete with a post-patch callback,
+so that tcp_send_challenge_ack() could first be changed to read
+sysctl_tcp_challenge_ack_limit with READ_ONCE.
+
+
+2 - Support __init and probe function patches
+
+Although __init and probe functions are not directly livepatch-able, it
+may be possible to implement similar updates via pre/post-patch
+callbacks.
+
+48900cb6af42 ("virtio-net: drop NETIF_F_FRAGLIST") change the way that
+virtnet_probe() initialized its driver's net_device features.  A
+pre/post-patch callback could iterate over all such devices, making a
+similar change to their hw_features value.  (Client functions of the
+value may need to be updated accordingly.)
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 194991ef9347..5fb8925fc488 100644

[PATCH RFC 0/3] A few round_pipe_size() and pipe-max-size fixups

2017-09-05 Thread Joe Lawrence
While backporting Michael's "pipe: fix limit handling" [1] patchset to a
distro-kernel, Mikulas noticed that current upstream pipe limit handling
contains a few problems:

  1 - round_pipe_size() nr_pages overflow on 32bit:  this would
  subsequently try roundup_pow_of_two(0), which is undefined.

  2 - visible non-rounded pipe-max-size value: there is no mutual
  exclusion or protection between the time pipe_max_size is assigned
  a raw value from proc_dointvec_minmax() and when it is rounded.

  3 - procfs signed wrap: echo'ing a large number into
  /proc/sys/fs/pipe-max-size and then cat'ing it back out shows a
  negative value.


This RFC serves as a bug report and a contains a few possible fixes.
There may be better / more consistent ways to fix the overflows and
procfs bugs, but I figured I'd throw an RFC w/code out there for initial
conversation.  Suggestions welcome!

-- Joe


Testing
===

Patch 1 - 32bit overflow

>From userspace:

  fcntl(fd, F_SETPIPE_SZ, 0x);

- Before the fix, return value was 4096 as pipe size overflowed and
  was set to 4096

- After the fix, returns -1 and sets errno EINVAL, pipe size remains
  untouched


Patch 2 - non-rounded pipe-max-size value
-
Keep plugging in values that need to be rounded:

  while (true); do echo 1048570 > /proc/sys/fs/pipe-max-size; done

and in another terminal, loop around reading the value:

  time (while (true); do SIZE=$(cat /proc/sys/fs/pipe-max-size); [[ $(( $SIZE % 
4096 )) -ne 0 ]] && break; done; echo "$SIZE")
  1048570

  real0m46.213s
  user0m29.688s
  sys 0m20.042s

after the fix, the test loop never encountered a non-page-rounded value.


Patch 3 - procfs signed wrap

Before:

  % echo 2147483647 >/proc/sys/fs/pipe-max-size
  % cat /proc/sys/fs/pipe-max-size
  -2147483648

After:

  % echo 2147483647 >/proc/sys/fs/pipe-max-size
  % cat /proc/sys/fs/pipe-max-size
  2147483648


Joe Lawrence (3):
  pipe: avoid round_pipe_size() nr_pages overflow on 32-bit
  pipe: protect pipe_max_size access with a mutex
  pipe: match pipe_max_size data type with procfs

 fs/pipe.c   | 48 +---
 kernel/sysctl.c |  2 +-
 2 files changed, 42 insertions(+), 8 deletions(-)

-- 
1.8.3.1



[PATCH RFC 2/3] pipe: protect pipe_max_size access with a mutex

2017-09-05 Thread Joe Lawrence
pipe_max_size is assigned directly via procfs sysctl:

  static struct ctl_table fs_table[] = {
  ...
  {
  .procname   = "pipe-max-size",
  .data   = _max_size,
  .maxlen = sizeof(int),
  .mode   = 0644,
  .proc_handler   = _proc_fn,
  .extra1 = _min_size,
  },
  ...

  int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
   size_t *lenp, loff_t *ppos)
  {
  ...
  ret = proc_dointvec_minmax(table, write, buf, lenp, ppos)
  ...

and then later rounded in-place a few statements later:

  ...
  pipe_max_size = round_pipe_size(pipe_max_size);
  ...

This leaves a window of time between initial assignment and rounding
that may be visible to other threads.  (For example, one thread sets a
non-rounded value to pipe_max_size while another reads its value.)

Similar reads of pipe_max_size are potentially racey:

  pipe.c :: alloc_pipe_info()
  pipe.c :: pipe_set_size()

Protect them and the procfs sysctl assignment with a mutex.

Reported-by: Mikulas Patocka 
Signed-off-by: Joe Lawrence 
---
 fs/pipe.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index fa28910b3c59..33bb11b0d78e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -35,6 +35,11 @@
 unsigned int pipe_max_size = 1048576;
 
 /*
+ * Provide mutual exclusion around access to pipe_max_size
+ */
+static DEFINE_MUTEX(pipe_max_mutex);
+
+/*
  * Minimum pipe size, as required by POSIX
  */
 unsigned int pipe_min_size = PAGE_SIZE;
@@ -623,13 +628,18 @@ struct pipe_inode_info *alloc_pipe_info(void)
unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
struct user_struct *user = get_current_user();
unsigned long user_bufs;
+   unsigned int max_size;
 
pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
if (pipe == NULL)
goto out_free_uid;
 
-   if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
-   pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+   mutex_lock(_max_mutex);
+   max_size = pipe_max_size;
+   mutex_unlock(_max_mutex);
+
+   if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
+   pipe_bufs = max_size >> PAGE_SHIFT;
 
user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
 
@@ -1039,6 +1049,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, 
unsigned long arg)
struct pipe_buffer *bufs;
unsigned int size, nr_pages;
unsigned long user_bufs;
+   unsigned int max_size;
long ret = 0;
 
size = round_pipe_size(arg);
@@ -1056,8 +1067,11 @@ static long pipe_set_size(struct pipe_inode_info *pipe, 
unsigned long arg)
 * Decreasing the pipe capacity is always permitted, even
 * if the user is currently over a limit.
 */
+   mutex_lock(_max_mutex);
+   max_size = pipe_max_size;
+   mutex_unlock(_max_mutex);
if (nr_pages > pipe->buffers &&
-   size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
+   size > max_size && !capable(CAP_SYS_RESOURCE))
return -EPERM;
 
user_bufs = account_pipe_buffers(pipe->user, pipe->buffers, nr_pages);
@@ -1131,18 +1145,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, 
void __user *buf,
unsigned int rounded_pipe_max_size;
int ret;
 
+   mutex_lock(_max_mutex);
orig_pipe_max_size = pipe_max_size;
ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
-   if (ret < 0 || !write)
+   if (ret < 0 || !write) {
+   mutex_unlock(_max_mutex);
return ret;
+   }
 
rounded_pipe_max_size = round_pipe_size(pipe_max_size);
if (rounded_pipe_max_size == 0) {
pipe_max_size = orig_pipe_max_size;
+   mutex_unlock(_max_mutex);
return -EINVAL;
}
 
pipe_max_size = rounded_pipe_max_size;
+   mutex_unlock(_max_mutex);
+
return ret;
 }
 
-- 
1.8.3.1



[PATCH RFC 1/3] pipe: avoid round_pipe_size() nr_pages overflow on 32-bit

2017-09-05 Thread Joe Lawrence
The round_pipe_size() function contains a right-bit-shift expression
which may overflow, which would cause undefined results in a subsequent
roundup_pow_of_two() call.

  static inline unsigned int round_pipe_size(unsigned int size)
  {
  unsigned long nr_pages;

  nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
  }

PAGE_SIZE is defined as (1UL << PAGE_SHIFT), so:
  - 4 bytes wide on 32-bit (0 to 0x)
  - 8 bytes wide on 64-bit (0 to 0x)

That means that 32-bit round_pipe_size(), nr_pages may overflow to 0:

  size=0xnr_pages=0x0
  size=0x0001nr_pages=0x1
  size=0xf000nr_pages=0xf
  size=0xf001nr_pages=0x0 << !
  size=0xnr_pages=0x0 << !

This is bad because roundup_pow_of_two(n) is undefined when n == 0!

64-bit is not a problem* as the unsigned int size is 4 bytes wide
(similar to 32-bit) and the larger, 8 byte wide unsigned long, is
sufficient to handle the largest value of the bit shift expression:

  size=0xnr_pages=10

(*On 64-bit, round_pipe_size(0x) will later overflow when the
result of roundup_pow_of_two(0x10) is shifted left by PAGE_SHIFT.
This behavior is at least defined by the language, so callers can safely
sanity-check a 0 return value from round_pipe_size.)

Modify round_pipe_size() to return 0 if n == 0, reset the original
pipe_max_size value, and update callers to handle accordingly.

Reported-by: Mikulas Patocka 
Signed-off-by: Joe Lawrence 
---
 fs/pipe.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 97e5be897753..fa28910b3c59 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1017,13 +1017,16 @@ static int fifo_open(struct inode *inode, struct file 
*filp)
 
 /*
  * Currently we rely on the pipe array holding a power-of-2 number
- * of pages.
+ * of pages. Returns 0 on error.
  */
 static inline unsigned int round_pipe_size(unsigned int size)
 {
unsigned long nr_pages;
 
nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   if (nr_pages == 0)
+   return 0;
+
return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
 }
 
@@ -1039,6 +1042,8 @@ static long pipe_set_size(struct pipe_inode_info *pipe, 
unsigned long arg)
long ret = 0;
 
size = round_pipe_size(arg);
+   if (size == 0)
+   return -EINVAL;
nr_pages = size >> PAGE_SHIFT;
 
if (!nr_pages)
@@ -1122,13 +1127,22 @@ static long pipe_set_size(struct pipe_inode_info *pipe, 
unsigned long arg)
 int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
 size_t *lenp, loff_t *ppos)
 {
+   unsigned int orig_pipe_max_size;
+   unsigned int rounded_pipe_max_size;
int ret;
 
+   orig_pipe_max_size = pipe_max_size;
ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
if (ret < 0 || !write)
return ret;
 
-   pipe_max_size = round_pipe_size(pipe_max_size);
+   rounded_pipe_max_size = round_pipe_size(pipe_max_size);
+   if (rounded_pipe_max_size == 0) {
+   pipe_max_size = orig_pipe_max_size;
+   return -EINVAL;
+   }
+
+   pipe_max_size = rounded_pipe_max_size;
return ret;
 }
 
-- 
1.8.3.1



[PATCH RFC 3/3] pipe: match pipe_max_size data type with procfs

2017-09-05 Thread Joe Lawrence
pipe_max_size is defined as an unsigned int:

  unsigned int pipe_max_size = 1048576;

but its procfs/sysctl representation is an integer:

  static struct ctl_table fs_table[] = {
  ...
  {
  .procname   = "pipe-max-size",
  .data   = _max_size,
  .maxlen = sizeof(int),
  .mode   = 0644,
  .proc_handler   = _proc_fn,
  .extra1 = _min_size,
  },
  ...

that is signed:

  int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
   size_t *lenp, loff_t *ppos)
  {
  ...
  ret = proc_dointvec_minmax(table, write, buf, lenp, ppos)

This leads to signed results via procfs for large values of
pipe_max_size:

  % echo 2147483647 >/proc/sys/fs/pipe-max-size
  % cat /proc/sys/fs/pipe-max-size
  -2147483648

Use unsigned operations on this variable to avoid such negative values.

Reported-by: Mikulas Patocka 
Signed-off-by: Joe Lawrence 
---
 fs/pipe.c   | 2 +-
 kernel/sysctl.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 33bb11b0d78e..3b10d39cc5d1 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1147,7 +1147,7 @@ int pipe_proc_fn(struct ctl_table *table, int write, void 
__user *buf,
 
mutex_lock(_max_mutex);
orig_pipe_max_size = pipe_max_size;
-   ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
+   ret = proc_douintvec_minmax(table, write, buf, lenp, ppos);
if (ret < 0 || !write) {
mutex_unlock(_max_mutex);
return ret;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 6648fbbb8157..c976719bf37a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1825,7 +1825,7 @@ static int sysrq_sysctl_handler(struct ctl_table *table, 
int write,
{
.procname   = "pipe-max-size",
.data   = _max_size,
-   .maxlen = sizeof(int),
+   .maxlen = sizeof(pipe_max_size),
.mode   = 0644,
.proc_handler   = _proc_fn,
.extra1 = _min_size,
-- 
1.8.3.1



Re: [PATCH v3] livepatch: introduce shadow variable API

2017-08-14 Thread Joe Lawrence
On 08/11/2017 12:35 PM, Josh Poimboeuf wrote:
> On Fri, Jul 28, 2017 at 01:25:22PM -0400, Joe Lawrence wrote:
>> Add exported API for livepatch modules:
>>
>>   klp_shadow_get()
>>   klp_shadow_attach()
>>   klp_shadow_get_or_attach()
>>   klp_shadow_update_or_attach()
>>   klp_shadow_detach()
>>   klp_shadow_detach_all()
> 
> I like the API.
> 
>> +Matching parent's lifecycle
>> +---
>> +
>> +If parent data structures are frequently created and destroyed, it may
>> +be easiest to align its shadow variable lifetimes to the same allocation
> 
> "its shadow variable lifetimes" -> "their shadow variables' lifetimes" ?

"parent data structures" is plural, so I think you are correct.

>> +void *klp_shadow_attach(void *obj, unsigned long id, void *data,
>> +size_t size, gfp_t gfp_flags)
> 
> [ Note: some of the following comments also apply to
>   klp_shadow_get_or_attach and klp_shadow_update_or_attach. ]
> 
>> +{
>> +struct klp_shadow *new_shadow;
> 
> nit: The "new" is implied, and there's only one shadow struct used in
> the function, so maybe just call it "shadow"?

I'd like to keep the "new_" prefix convention to clearly mark that
structure as a (temporarily) allocated one.  v4 WIP modifies
klp_shadow_update_or_attach() to include both "new_shadow" and "shadow",
so there will be a convention established there.

>> +void *shadow_data;
>> +unsigned long flags;
>> +
>> +/* Take error exit path if  already exists */
>> +shadow_data = klp_shadow_get(obj, id);
>> +if (unlikely(shadow_data))
>> +goto err_exists;
> 
> The return value of klp_shadow_get() can be tested directly, no need for
> a variable.

Yup.

> 
>> +/* Allocate a new shadow variable for use inside the lock below */
>> +new_shadow = kzalloc(size + sizeof(*new_shadow), gfp_flags);
>> +if (!new_shadow)
>> +goto err;
> 
> The goto destination is just a single line return, so I think it's
> clearer to just return NULL here and get rid of the err label.

Yeah, in isolation I'd agree with you, however I chose to error on the
side of the overall pattern: klp_shadow_attach(),
klp_shadow_get_or_attach(), and klp_shadow_update_or_attach() all follow
the same structure.  It felt more consistent to maintain similar exit
patterns and bend this style rule.  Either way, the point is moot as
fixing the problems Miroslav pointed out (and below) required
refactoring these routines and their return paths.

>> +
>> +/* Look for  again under the lock */
>> +spin_lock_irqsave(_shadow_lock, flags);
>> +shadow_data = klp_shadow_get(obj, id);
>> +if (unlikely(shadow_data)) {
>> +
>> +/* Shadow variable found, throw away allocation and take
>> + * error exit path */
> 
> Multi-line comments should be in the kernel coding style:
> 
>   /*
>* Shadow variable found, throw away allocation and take
>* error exit path
>*/
> 
> Also, complete sentences preferred :-)

Looks like someone forgot to run through checkpatch.  Sorry about that.

> 
>> +spin_unlock_irqrestore(_shadow_lock, flags);
>> +kfree(shadow_data);
> 
> Shouldn't it free new_shadow instead of shadow_data?

You are correct ... will fix in v4.

>> +goto err_exists;
>> +}
>> +
>> +/* No  found, add the newly allocated one */
>> +shadow_data = data;
>> +klp_shadow_set(new_shadow, obj, id, data, size);
> 
> To avoid doing extra work with the lock held, the klp_shadow_set() can
> be done before getting the lock, after the kzalloc.

The interesting work being a potentially speculative memcpy... moving
outside the lock, after the first search-miss, makes sense.

Thanks,

-- Joe


Re: [PATCH v2 1/1] livepatch: add (un)patch callbacks

2017-08-14 Thread Joe Lawrence
On 08/11/2017 04:44 PM, Josh Poimboeuf wrote:
> On Tue, Aug 08, 2017 at 03:36:07PM -0400, Joe Lawrence wrote:
>> +++ b/Documentation/livepatch/callbacks.txt
>> @@ -0,0 +1,75 @@
>> +(Un)patching Callbacks
>> +==
>> +
>> +Livepatch (un)patch-callbacks provide a mechanism for livepatch modules
>> +to execute callback functions when a kernel object is (un)patched.
> 
> I think it would be helpful to put a little blurb here about why
> callbacks are needed and when they might be used.  Maybe steal some of
> the description from the first two bullet points here:
> 
>   https://lkml.kernel.org/r/20170720041723.35r6qk2fia7xix3t@treble

Ok -- btw, can you explain this point: "patching otherwise unpatchable
code (i.e., assembly)".  I wasn't sure if you were referring to the
actual code, or modifying the machine state as setup by some init time
assembly.

> Also, I tested stop_machine() in the callbacks and it seemed to work
> fine.  It might be worth mentioning in the docs that it's an option.

I'll file that under the "you better know what you're doing" section. :)
If your test would be a better use-case example or sample module than
what's currently in the patchset, feel free to send it over and I can
incorporate it.

>> +
>> +These callbacks differ from existing kernel facilities:
>> +
>> +  - Module init/exit code doesn't run when disabling and re-enabling a
>> +patch.
>> +
>> +  - A module notifier can't stop the to-be-patched module from loading.
>> +
>> +Callbacks are part of the klp_object structure and their implementation
>> +is specific to the given object.  Other livepatch objects may or may not
>> +be patched, irrespective of the target klp_object's current state.
>> +
>> +Callbacks can be registered for the following livepatch actions:
>> +
>> +  * Pre-patch- before klp_object is patched
>> +
>> +  * Post-patch   - after klp_object has been patched and is active
>> +   across all tasks
>> +
>> +  * Pre-unpatch  - before klp_object is unpatched, patched code is active
>> +
>> +  * Post-unpatch - after klp_object has been patched, all code has been
>> +   restored and no tasks are running patched code
>> +
>> +Callbacks are only executed if its host klp_object is loaded.  For
> 
> "Callbacks are" -> "A callback is" ?

Okay.  What about the preceding plural-case instances?

> 
>> +static inline int klp_pre_patch_callback(struct klp_object *obj)
>> +{
>> +if (!obj->patched && obj->callbacks.pre_patch)
>> +return (*obj->callbacks.pre_patch)(obj);
>> +return 0;
>> +}
>> +static inline void klp_post_patch_callback(struct klp_object *obj)
>> +{
>> +if (obj->patched && obj->callbacks.post_patch)
>> +(*obj->callbacks.post_patch)(obj);
>> +}
>> +static inline void klp_pre_unpatch_callback(struct klp_object *obj)
>> +{
>> +if (obj->patched && obj->callbacks.pre_unpatch)
>> +(*obj->callbacks.pre_unpatch)(obj);
>> +}
>> +static inline void klp_post_unpatch_callback(struct klp_object *obj)
>> +{
>> +if (!obj->patched && obj->callbacks.post_unpatch)
>> +(*obj->callbacks.post_unpatch)(obj);
>> +}
>> +
> 
> Do these need the obj->patched checks?  As far as I can tell they seem
> to be called in the right places and the checks are superfluous.

That is correct.  I can leave them (defensive coding) or take them out
and perhaps add comments above to explain their use and assumptions.

>> --- a/kernel/livepatch/transition.c
>> +++ b/kernel/livepatch/transition.c
>> @@ -109,9 +109,6 @@ static void klp_complete_transition(void)
>>  }
>>  }
>>  
>> -if (klp_target_state == KLP_UNPATCHED && !immediate_func)
>> -module_put(klp_transition_patch->mod);
>> -
>>  /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */
>>  if (klp_target_state == KLP_PATCHED)
>>  klp_synchronize_transition();
>> @@ -130,6 +127,22 @@ static void klp_complete_transition(void)
>>  }
>>  
>>  done:
>> +klp_for_each_object(klp_transition_patch, obj) {
>> +if (klp_target_state == KLP_PATCHED)
>> +klp_post_patch_callback(obj);
>> +else if (klp_target_state == KLP_PATCHED)
> 
> s/KLP_PATCHED/KLP_UNPATCHED

Ahh, I was so focused on the loadable module cases in
module_coming/going that I botched this cas

[PATCH v4] livepatch: introduce shadow variable API

2017-08-14 Thread Joe Lawrence
Add exported API for livepatch modules:

  klp_shadow_get()
  klp_shadow_attach()
  klp_shadow_get_or_attach()
  klp_shadow_update_or_attach()
  klp_shadow_detach()
  klp_shadow_detach_all()

that implement "shadow" variables, which allow callers to associate new
shadow fields to existing data structures.  This is intended to be used
by livepatch modules seeking to emulate additions to data structure
definitions.

See Documentation/livepatch/shadow-vars.txt for a summary of the new
shadow variable API, including a few common use cases.

See samples/livepatch/livepatch-shadow-* for example modules that
demonstrate shadow variables.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt   | 215 +
 include/linux/livepatch.h |  10 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 382 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 174 ++
 samples/livepatch/livepatch-shadow-fix2.c | 167 +
 samples/livepatch/livepatch-shadow-mod.c  | 224 ++
 9 files changed, 1178 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
new file mode 100644
index ..b8e918a37078
--- /dev/null
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -0,0 +1,215 @@
+
+Shadow Variables
+
+
+Shadow variables are a simple way for livepatch modules to associate
+additional "shadow" data with existing data structures.  Shadow data is
+allocated separately from parent data structures, which are left
+unmodified.  The shadow variable API described in this document is used
+to allocate/attach and detach/release shadow variables to their parents.
+
+The implementation introduces a global, in-kernel hashtable that
+associates pointers to parent objects and a numeric identifier of the
+shadow data.  The numeric identifier is a simple enumeration that may be
+used to describe shadow variable version, class or type, etc.  More
+specifically, the parent pointer serves as the hashtable key while the
+numeric id subsequently filters hashtable queries.  Multiple shadow
+variables may attach to the same parent object, but their numeric
+identifier distinguishes between them.
+
+
+1. Brief API summary
+
+
+(See the full API usage docbook notes in livepatch/shadow.c.)
+
+A hashtable references all shadow variables.  These references are
+stored and retrieved through a  pair.
+
+* The klp_shadow variable data structure encapsulates both tracking
+meta-data and shadow-data:
+  - meta-data
+- obj - pointer to parent object
+- id - data identifier
+  - data[] - storage for shadow data
+
+  It is important to note that the klp_shadow_attach(),
+  klp_shadow_get_or_attach(), and klp_shadow_update_or_attach() calls,
+  described below, store a *copy* of the data that the functions are
+  provided.
+
+* klp_shadow_get() - retrieve a shadow variable data pointer
+  - search hashtable for  pair
+
+* klp_shadow_attach() - allocate and add a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- WARN and return NULL
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  to the global hashtable
+
+* klp_shadow_get_or_attach() - get existing or attach a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_update_or_attach() - update or attach a new shadow variable
+  - search hashtable for  pair
+  - if exists
+-  update and return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_detach() - detach and free a  shadow variable
+  - find and remove a  reference from global hashtable
+- if found, free shadow variable
+
+* klp_shadow_detach_all() - detach and free all <*, id> shadow variables
+  - find and remove any <*, id> references from global hashtable
+- if found, free shadow variable
+
+
+2. Use cases
+
+
+(See the example shadow variable livepatch modules in samples/livepatch/
+for full working demonstrations.)
+
+For the following use-case examples, consider commit 

[PATCH v4] livepatch: shadow variables

2017-08-14 Thread Joe Lawrence
v4

- klp_shadow_attach(), klp_shadow_get_or_attach(), and
  klp_shadow_update_or_attach()
  - fix up return values depending on whether a new_shadow
variable was allocated, or an existing one was used
  - kfree new_shadow, not shadow_data when shadow variable is found
under the lock (2nd search try)
  - refactor away most of the exit labels
  - move klp_shadow_set() calls outside of the klp_shadow_lock
  - fix multiline comment format

- klp_shadow_attach()
  - drop unnecessary variable assignment for conditional

- s/shadow_match()/klp_shadow_match()/g

- klp_shadow_match(), klp_shadow_set(), klp_shadow_add()
  - add "caller should hold lock" comments

- Documentation
  - remove unnecessary klp_shadow_get() call in use-case
  - s/its shadow variable lifetimes/their shadow variables lifetimes/

Joe Lawrence (1):
  livepatch: introduce shadow variable API

 Documentation/livepatch/shadow-vars.txt   | 215 +
 include/linux/livepatch.h |  10 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 382 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 174 ++
 samples/livepatch/livepatch-shadow-fix2.c | 167 +
 samples/livepatch/livepatch-shadow-mod.c  | 224 ++
 9 files changed, 1178 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

-- 
1.8.3.1



Re: [PATCH v4] livepatch: introduce shadow variable API

2017-08-16 Thread Joe Lawrence
On 08/16/2017 08:43 AM, Miroslav Benes wrote:
> 
>> [ ... snip ... ]
> 
> There is a comment above about locking and we do not take the spinlock 
> here. That could surprise someone. So I'd keep only klp_shadow_add() 
> comment, because there it is strictly needed. It depends on the context in 
> all other cases.

Good catch, I think this changed in this last version when I moved some
of the work outside the lock.

> Could you also add a comment above klp_shadow_lock definition about what 
> it aims to protect?
> 

How about "klp_shadow_lock provides exclusive access to the
klp_shadow_hash and the shadow variables it references."  or were
thinking of something more detailed?

>> +/* Look for  again under the lock */
>> +spin_lock_irqsave(_shadow_lock, flags);
>> +shadow_data = klp_shadow_get(obj, id);
>> +if (unlikely(shadow_data)) {
> 
> shadow_data is not needed anywhere, so you could do the same as for the 
> first speculative search and remove shadow_data variable all together.

Ok.

>> [ ... snip ... ]
> 
> Otherwise it looks good. You can add my
> 
> Acked-by: Miroslav Benes 
> 
> with those nits fixed.

Thank you for all the suggestions and reviews!

-- Joe


[RFC] livepatch: unpatch all klp_objects if klp_module_coming fails

2017-09-13 Thread Joe Lawrence
callback: 
livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
module_init
  [   38.223966] livepatch: JL: klp_unpatch_object(c02a9128) 
patch=c02a9000 obj->name: livepatch_callbacks_mod
  [   38.224980] livepatch_callbacks_demo: post_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
module_init
  [   38.226174] livepatch_callbacks_demo2: pre_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
module_init
  [   38.227127] livepatch: JL: klp_unpatch_object(c02ae128) 
patch=c02ae000 obj->name: livepatch_callbacks_mod
  [   38.228231] livepatch_callbacks_demo2: post_unpatch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_COMING] Full formed, running 
module_init

Finally the module loader reports an error:

  [   38.242684] insmod: ERROR: could not insert module 
samples/livepatch/livepatch-callbacks-mod.ko: No such device

Clean it all up:

  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo3/enabled
  [   41.248198] livepatch_callbacks_demo3: pre_unpatch_callback: vmlinux
  [   41.248799] livepatch: 'livepatch_callbacks_demo3': starting unpatching 
transition
  [   42.719135] livepatch_callbacks_demo3: post_unpatch_callback: vmlinux
  [   42.719622] livepatch: 'livepatch_callbacks_demo3': unpatching complete
  
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  [   47.269103] livepatch_callbacks_demo2: pre_unpatch_callback: vmlinux
  [   47.269682] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
  [   48.735253] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
  [   48.735928] livepatch: 'livepatch_callbacks_demo2': unpatching complete

  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  [   53.289287] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [   53.289987] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [   54.751146] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [   54.751656] livepatch: 'livepatch_callbacks_demo': unpatching complete

  % rmmod samples/livepatch/livepatch-callbacks-demo3.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo.ko


-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--

>From b80b90cb54b498d2b1165d409ce4b0ca47610b36 Mon Sep 17 00:00:00 2001
From: Joe Lawrence 
Date: Wed, 13 Sep 2017 16:51:13 -0400
Subject: [RFC] livepatch: unpatch all klp_objects if klp_module_coming fails

When an incoming module is considered for livepatching by
klp_module_coming(), it iterates over multiple patches and multiple
kernel objects in this order:

list_for_each_entry(patch, _patches, list) {
klp_for_each_object(patch, obj) {

which means that if one of the kernel objects fail to patch for whatever
reason, klp_module_coming()'s error path should double back and unpatch
any previous kernel object that was patched for a previous patch.

Reported-by: Miroslav Benes 
Signed-off-by: Joe Lawrence 
---
 kernel/livepatch/core.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index aca62c4b8616..7f5192618cc8 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -889,6 +889,8 @@ int klp_module_coming(struct module *mod)
goto err;
}
 
+pr_err("JL: klp_patch_object(%p) patch=%p obj->name: %s\n", obj, patch, 
obj->name);
+
ret = klp_patch_object(obj);
if (ret) {
pr_warn("failed to apply patch '%s' to module 
'%s' (%d)\n",
@@ -919,7 +921,33 @@ int klp_module_coming(struct module *mod)
pr_warn("patch '%s' failed for module '%s', refusing to load module 
'%s'\n",
patch->mod->name, obj->mod->name, obj->mod->name);
mod->klp_alive = false;
-   klp_free_object_loaded(obj);
+
+   /*
+* Run back through the patch list and unpatch any klp_object that
+* was patched before hitting an error above.
+*/
+
+   list_for_each_entry(patch, _patches, list) {
+
+   if (!patch->enabled || patch == klp_transition_patch)
+   continue;
+
+   klp_for_each_object(patch, obj) {
+
+   if (!obj->patched || !klp_is_module(obj) ||
+   strcmp(obj->name, mod->name))
+   continue;
+
+   klp_pre_unpatch_callback(obj);
+pr_err("JL: klp_unpatch_object(%p) patch=%p obj->name: %s\n", obj, patch, 
obj->name);
+   klp_unpatch_object(obj);
+   klp_post_unpatch_ca

Re: [PATCH RFC 0/3] A few round_pipe_size() and pipe-max-size fixups

2017-09-14 Thread Joe Lawrence
On 09/14/2017 12:57 PM, Randy Dunlap wrote:
> On 09/14/17 06:26, Michael Kerrisk (man-pages) wrote:
>> Hello Joe,
>>
>> On 5 September 2017 at 16:44, Joe Lawrence  wrote:
>>> While backporting Michael's "pipe: fix limit handling" [1] patchset to a
>>> distro-kernel, Mikulas noticed that current upstream pipe limit handling
>>> contains a few problems:
>>>
>>>   1 - round_pipe_size() nr_pages overflow on 32bit:  this would
>>>   subsequently try roundup_pow_of_two(0), which is undefined.
> 
> Hi,
> Sorry I missed the initial posting of this.
> 
> The man page for F_SETPIPE_SZ 
> (http://man7.org/linux/man-pages/man2/fcntl.2.html)
> says:
> "Attempts to set the pipe capacity below the page size are
> silently rounded up to the page size."
> 
> That implies to me that setting pipe size to 0 would round up to PAGE_SIZE.
> Doesn't patch 1/3 change that to return -EINVAL?

Good catch.  How about something like this:

/*
 * Minimum pipe size, as required by POSIX
 */
unsigned int pipe_min_size = PAGE_SIZE;

...

static inline unsigned int round_pipe_size(unsigned int size)
 {
unsigned long nr_pages;

+   if (size < pipe_min_size)
+   size = pipe_min_size;
+
nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (nr_pages == 0)
return 0;

> 
> Otherwise all 3 patches look good to me.

If the above is good, I can fold this into patch 1 and respin the set.

Thanks,

-- Joe


Re: [PATCH RFC 2/3] pipe: protect pipe_max_size access with a mutex

2017-09-15 Thread Joe Lawrence
On 09/14/2017 07:09 PM, Mikulas Patocka wrote:
> On Tue, 5 Sep 2017, Joe Lawrence wrote:
>> pipe_max_size is assigned directly via procfs sysctl:
>>
>>   static struct ctl_table fs_table[] = {
>>   ...
>>   {
>>   .procname   = "pipe-max-size",
>>   .data   = _max_size,
>>   .maxlen = sizeof(int),
>>   .mode   = 0644,
>>   .proc_handler   = _proc_fn,
>>   .extra1 = _min_size,
>>   },
>>   ...
>>
>>   int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
>>size_t *lenp, loff_t *ppos)
>>   {
>>   ...
>>   ret = proc_dointvec_minmax(table, write, buf, lenp, ppos)
>>   ...
>>
>> and then later rounded in-place a few statements later:
>>
>>   ...
>>   pipe_max_size = round_pipe_size(pipe_max_size);
>>   ...
>>
>> This leaves a window of time between initial assignment and rounding
>> that may be visible to other threads.  (For example, one thread sets a
>> non-rounded value to pipe_max_size while another reads its value.)
>>
>> Similar reads of pipe_max_size are potentially racey:
>>
>>   pipe.c :: alloc_pipe_info()
>>   pipe.c :: pipe_set_size()
>>
>> Protect them and the procfs sysctl assignment with a mutex.
>>
>> Reported-by: Mikulas Patocka 
>> Signed-off-by: Joe Lawrence 
>> ---
>>  fs/pipe.c | 28 
>>  1 file changed, 24 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/pipe.c b/fs/pipe.c
>> index fa28910b3c59..33bb11b0d78e 100644
>> --- a/fs/pipe.c
>> +++ b/fs/pipe.c
>> @@ -35,6 +35,11 @@
>>  unsigned int pipe_max_size = 1048576;
>>  
>>  /*
>> + * Provide mutual exclusion around access to pipe_max_size
>> + */
>> +static DEFINE_MUTEX(pipe_max_mutex);
>> +
>> +/*
>>   * Minimum pipe size, as required by POSIX
>>   */
>>  unsigned int pipe_min_size = PAGE_SIZE;
>> @@ -623,13 +628,18 @@ struct pipe_inode_info *alloc_pipe_info(void)
>>  unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
>>  struct user_struct *user = get_current_user();
>>  unsigned long user_bufs;
>> +unsigned int max_size;
>>  
>>  pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
>>  if (pipe == NULL)
>>  goto out_free_uid;
>>  
>> -if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
>> -pipe_bufs = pipe_max_size >> PAGE_SHIFT;
>> +mutex_lock(_max_mutex);
>> +max_size = pipe_max_size;
>> +mutex_unlock(_max_mutex);
>> +
>> +if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
>> +pipe_bufs = max_size >> PAGE_SHIFT;
>>  
>>  user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
>>  
>> @@ -1039,6 +1049,7 @@ static long pipe_set_size(struct pipe_inode_info 
>> *pipe, unsigned long arg)
>>  struct pipe_buffer *bufs;
>>  unsigned int size, nr_pages;
>>  unsigned long user_bufs;
>> +unsigned int max_size;
>>  long ret = 0;
>>  
>>  size = round_pipe_size(arg);
>> @@ -1056,8 +1067,11 @@ static long pipe_set_size(struct pipe_inode_info 
>> *pipe, unsigned long arg)
>>   * Decreasing the pipe capacity is always permitted, even
>>   * if the user is currently over a limit.
>>   */
>> +mutex_lock(_max_mutex);
>> +max_size = pipe_max_size;
>> +mutex_unlock(_max_mutex);
>>  if (nr_pages > pipe->buffers &&
>> -size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
>> +size > max_size && !capable(CAP_SYS_RESOURCE))
>>  return -EPERM;
>>  
>>  user_bufs = account_pipe_buffers(pipe->user, pipe->buffers, nr_pages);
>> @@ -1131,18 +1145,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, 
>> void __user *buf,
>>  unsigned int rounded_pipe_max_size;
>>  int ret;
>>  
>> +mutex_lock(_max_mutex);
>>  orig_pipe_max_size = pipe_max_size;
>>  ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
>> -if (ret < 0 || !write)
>> +if (ret < 0 || !write) {
>> +mutex_unlock(_max_mutex);
>>  return ret;
>> +   

Re: [PATCH] livepatch: __klp_shadow_get_or_alloc() is local to shadow.c

2017-09-15 Thread Joe Lawrence
On Thu, Sep 14, 2017 at 02:15:36PM -0700, Jiri Kosina wrote:
> From: Jiri Kosina 
> 
> ... therefore make it static.
> 
> Fixes: 439e7271dc2 ("livepatch: introduce shadow variable API")
> Signed-off-by: Jiri Kosina 
> ---
> 
> Sorry for not having spotted this before pushing out.
> 
>  kernel/livepatch/shadow.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/livepatch/shadow.c b/kernel/livepatch/shadow.c
> index 67e4360..fdac275 100644
> --- a/kernel/livepatch/shadow.c
> +++ b/kernel/livepatch/shadow.c
> @@ -113,7 +113,7 @@ void *klp_shadow_get(void *obj, unsigned long id)
>  }
>  EXPORT_SYMBOL_GPL(klp_shadow_get);
>  
> -void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
> +static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void 
> *data,
>  size_t size, gfp_t gfp_flags, bool warn_on_exist)
>  {
>   struct klp_shadow *new_shadow;
> -- 
> 1.8.5.6

Acked-by: Joe Lawrence 

Thanks for cleaning this up, Jiri.

Also thanks to Miroslav, Petr, Nicolai and Josh for the patchset
reviews!

-- Joe


Re: [PATCH] livepatch: add (un)patch hooks

2017-07-27 Thread Joe Lawrence
On 07/20/2017 12:17 AM, Josh Poimboeuf wrote:
> - The pre-patch and pre-unpatch hooks can be run before the
>   patching/unpatching process begins.

Hi Josh,

By "(un)patching process" are you referring to the klp_patch at large or
each klp_object?  ie, would all klp_objects execute their hooks before
anything is (un)patched?  Just trying to clarify.

> - The post-patch and post-unpatch hooks will need to be run from either
>   klp_complete_transition() or klp_module_coming/going(), depending on
>   whether the to-be-patched module is already loaded or is being
>   loaded/unloaded.

You're suggesting that post-(un)patch-hooks:

  1 - Notify klp_objects when a KLP_(UN)PATCHED transition completes

and for subsequently loaded klp_objects (ie modules):

  2 - On load - notify it with current KLP_(UN)PATCHED state,
  Steady state - same as (1) above.

Thanks,

-- Joe


[PATCH v3] livepatch: shadow variables

2017-07-28 Thread Joe Lawrence
Hi all,

This is v3 of the livepatch shadow variable API.  v2 collected a bunch
of great feedback on terminology, use cases and concurrency notes which
I've tried to incorporate here.

Here's a high-level sketch of v2 changes:

- Overall
  
  - Squash into a one patch, makes for finding terms and code across
docs/implementation/example easier
  
  - Variable naming:
- obj, original data -> obj, parent object
- num, numerical description of new data -> id, data identifier
- new_data -> data
- new_size -> size
  
- Documentation
  
  - API summary: s/klp_shadow_detach/klp_shadow_detach_all
  - describe uses for the data id (versions, class/type, etc)
  - clarify that shadow data is a copy
  - fix use-cases - use one upstream commit and steal Petr's example for
klp_shadow_get_or_attach()
  
- Implementation
  
  - Modify klp_shadow_get_or_attach() to WARN and return NULL if shadow
variable already exists
  
  - Add klp_shadow_update_or_attach() to update if shadow variable already
exists
  
  
- Sample modules
  
  - s/_thread/_work_func
  - use system workqueue, DECLARE_DELAYED_WORK
  - use XXX_PERIOD constants
  - overhaul usage/comments, drop the verbose dmesg logs

Joe Lawrence (1):
  livepatch: introduce shadow variable API

 Documentation/livepatch/shadow-vars.txt   | 217 +
 include/linux/livepatch.h |  10 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 383 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-mod.c  | 222 +
 samples/livepatch/livepatch-shadow-fix1.c | 174 ++
 samples/livepatch/livepatch-shadow-fix2.c | 167 +
 9 files changed, 1179 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c

-- 
1.8.3.1



[PATCH v3] livepatch: introduce shadow variable API

2017-07-28 Thread Joe Lawrence
Add exported API for livepatch modules:

  klp_shadow_get()
  klp_shadow_attach()
  klp_shadow_get_or_attach()
  klp_shadow_update_or_attach()
  klp_shadow_detach()
  klp_shadow_detach_all()

that implement "shadow" variables, which allow callers to associate new
shadow fields to existing data structures.  This is intended to be used
by livepatch modules seeking to emulate additions to data structure
definitions.

See Documentation/livepatch/shadow-vars.txt for a summary of the new
shadow variable API, including a few common use cases.

See samples/livepatch/livepatch-shadow-* for exmaple modules that
demonstrate shadow variables.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt   | 217 +
 include/linux/livepatch.h |  10 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 383 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-mod.c  | 222 +
 samples/livepatch/livepatch-shadow-fix1.c | 174 ++
 samples/livepatch/livepatch-shadow-fix2.c | 167 +
 9 files changed, 1179 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
new file mode 100644
index ..0dc2eb848615
--- /dev/null
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -0,0 +1,217 @@
+
+Shadow Variables
+
+
+Shadow variables are a simple way for livepatch modules to associate
+additional "shadow" data with existing data structures.  Shadow data is
+allocated separately from parent data structures, which are left
+unmodified.  The shadow variable API described in this document is used
+to allocate/attach and detach/release shadow variables to their parents.
+
+The implementation introduces a global, in-kernel hashtable that
+associates pointers to parent objects and a numeric identifier of the
+shadow data.  The numeric identifier is a simple enumeration that may be
+used to describe shadow variable version, class or type, etc.  More
+specifically, the parent pointer serves as the hashtable key while the
+numeric id subsequently filters hashtable queries.  Multiple shadow
+variables may attach to the same parent object, but their numeric
+identifier distinguishes between them.
+
+
+1. Brief API summary
+
+
+(See the full API usage docbook notes in livepatch/shadow.c.)
+
+A hashtable references all shadow variables.  These references are
+stored and retrieved through a  pair.
+
+* The klp_shadow variable data structure encapsulates both tracking
+meta-data and shadow-data:
+  - meta-data
+- obj - pointer to parent object
+- id - data identifier
+  - data[] - storage for shadow data
+
+  It is important to note that the klp_shadow_attach(),
+  klp_shadow_get_or_attach(), and klp_shadow_update_or_attach() calls,
+  described below, store a *copy* of the data that the functions are
+  provided.
+
+* klp_shadow_get() - retrieve a shadow variable data pointer
+  - search hashtable for  pair
+
+* klp_shadow_attach() - allocate and add a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- WARN and return NULL
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  to the global hashtable
+
+* klp_shadow_get_or_attach() - get existing or attach a new shadow variable
+  - search hashtable for  pair
+  - if exists
+- return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_update_or_attach() - update or attach a new shadow variable
+  - search hashtable for  pair
+  - if exists
+-  update and return existing shadow variable
+  - if  doesn't already exist
+- allocate a new shadow variable
+- copy data into the new shadow variable
+- add  pair to the global hashtable
+
+* klp_shadow_detach() - detach and free a  shadow variable
+  - find and remove a  reference from global hashtable
+- if found, free shadow variable
+
+* klp_shadow_detach_all() - detach and free all <*, id> shadow variables
+  - find and remove any <*, id> references from global hashtable
+- if found, free shadow variable
+
+
+2. Use cases
+
+
+(See the example shadow variable livepatch modules in samples/livepatch/
+for full working demonstrations.)
+
+For the following use-case examples, consider commit 

Re: [PATCH] livepatch: add (un)patch hooks

2017-07-28 Thread Joe Lawrence
On 07/27/2017 05:36 PM, Josh Poimboeuf wrote:
> On Thu, Jul 27, 2017 at 04:43:58PM -0400, Joe Lawrence wrote:
>> On 07/20/2017 12:17 AM, Josh Poimboeuf wrote:
>>> - The post-patch and post-unpatch hooks will need to be run from either
>>>   klp_complete_transition() or klp_module_coming/going(), depending on
>>>   whether the to-be-patched module is already loaded or is being
>>>   loaded/unloaded.
>>
>> You're suggesting that post-(un)patch-hooks:
>>
>>   1 - Notify klp_objects when a KLP_(UN)PATCHED transition completes
> 
> Right. (From klp_complete_transition())

We should be careful to only call hooks for those klp_objects that were
actually (un)patched.  I don't think there is such state that makes it
all the way out to klp_complete_transition(), but since both the
completion and module_coming/going code both operate under the
klp_mutex, perhaps klp_is_object_loaded() is a sufficient check?

>> and for subsequently loaded klp_objects (ie modules):
>>
>>   2 - On load - notify it with current KLP_(UN)PATCHED state,
>>   Steady state - same as (1) above.
> 
> Right. (From klp_module_coming/going())
> 

At least this should be easier to implement since we know what the story
is for the klp_object in hand.

-- Joe


[PATCH v3] selftests/livepatch: introduce tests

2018-04-12 Thread Joe Lawrence
Add a few livepatch modules and simple target modules that the included
regression suite can run tests against.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt  | 487 -
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  15 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 +
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 lib/livepatch/test_klp_shadow_vars.c   | 236 
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/README   |  43 ++
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 196 +++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++
 .../selftests/livepatch/test-shadow-vars.sh|  60 ++
 19 files changed, 1788 insertions(+), 487 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/README
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
index c9776f48e458..6ca2801a6bb9 100644
--- a/Documentation/livepatch/callbacks.txt
+++ b/Documentation/livepatch/callbacks.txt
@@ -116,490 +116,3 @@ virtnet_probe() initialized its driver's net_device 
features.  A
 pre/post-patch callback could iterate over all such devices, making a
 similar change to their hw_features value.  (Client functions of the
 value may need to be updated accordingly.)
-
-
-Test cases
-==
-
-What follows is not an exhaustive test suite of every possible livepatch
-pre/post-(un)patch combination, but a selection that demonstrates a few
-important concepts.  Each test case uses the kernel modules located in
-the samples/livepatch/ and assumes that no livepatches are loaded at the
-beginning of the test.
-
-
-Test 1
---
-
-Test a combination of loading a kernel module and a livepatch that
-patches a function in the first module.  (Un)load the target module
-before the livepatch module:
-
-- load target module
-- load livepatch
-- disable livepatch
-- unload target module
-- unload livepatch
-
-First load a target module:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   34.475708] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-On livepatch enable, before the livepatch transition starts, pre-patch
-callbacks are executed for vmlinux and livepatch_callbacks_mod (those
-klp_objects currently loaded).  After klp_objects are patched according
-to the klp_patch, their post-patch callbacks run and the transition
-completes:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   36.503719] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   36.504213] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
-  [   36.504238] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   36.504721] livepatch_callbacks_demo: pre_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   36.505849] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
-  [   37.727133] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
-  [   37.727232] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   37.727860] livepatch_callbacks_demo: post_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   37.728792] livepatch: 'livepatch_callbacks_demo': patching complete
-
-Similarly, on livepatch disable, pre-patch callbacks run before the
-unpatching transition starts.  klp_objects are reverted, post-patch
-callbacks execute and the transition com

[PATCH v3] Add livepatch kselftests

2018-04-12 Thread Joe Lawrence
Tests run on top of Petr's v11 atomic replace feature and v2 of the shadow
variable enhancement patchsets:

  [PATCH 0/8] livepatch: Atomic replace feature
  https://lkml.kernel.org/r/20180323120028.31451-1-pmla...@suse.com

  [PATCH v2 0/2] livepatch: Allocate and free shadow variables more safely
  https://lkml.kernel.org/r/20180405122315.29065-1-pmla...@suse.com

which have been combined into a git tree, then branched:

  https://github.com/joe-lawrence/linux/tree/klp_kselftest_base
  https://github.com/joe-lawrence/linux/tree/klp_kselftest_v3

so that the kbuild test robot could verify:

  Subject: [joe-lawrence:klp_kselftest_v3] BUILD SUCCESS 
73f12d67f681e3517a8cdc12ceec07b05543d269
  From: kbuild test robot 
  To: Joe Lawrence 

  tree/branch: https://github.com/joe-lawrence/linux  klp_kselftest_v3
  branch HEAD: 73f12d67f681e3517a8cdc12ceec07b05543d269  selftests/livepatch: 
introduce tests

  elapsed time: 95m

  configs tested: 202

  [ ... snip ... ]

If anyone knows how to indicate an external git tree base to the bot in
the commit message or header letter, let me know.  Otherwise I'll have
to keep pushing up to github and ignoring its misfires as reported to
the list :(


changes from v2:

- fix module_exit(test_klp_shadow_vars_exit) in test_klp_shadow_vars.c
- silence kbuild test robot's "XXX can be static" and "Using plain
  integer as NULL pointer" complaints
- re-run tests with CONFIG_LOCKDEP=y and CONFIG_PROVE_LOCKING=y
- use GFP_ATOMIC in test_klp_shadow_vars.c constructor code

changes from v1:
- Only add $(CC_FLAGS_FTRACE) for target modules
- Remove between test delay
- Reduce RETRY_INTERVAL to .1 sec
- Reduce test_callback_mod's busymod_work_func delay from 60 to 10 sec
- s/PASS/ok and s/FAIL/not ok for test output
- Move test descriptions from Documentation/livepatch/callbacks.txt
  into tools/testing/selftests/livepatch/test-callbacks.sh
- Add a shadow variable test script and module
- Add a short tools/testing/selftests/livepatch/README
- to += linux-kselft...@vger.kernel.org
- cc += Libor, Nicolai, Artem

change from rfc:
- SPDX-License-Identifiers
- Moved livepatch test modules into lib/livepatch
- Renamed livepatch.sh (filename suffix)
- Reduced between-test delay time
- Split off common functions.sh file
- Split into separate livepatch, callbacks, and shadow-vars scrips
- Gave the tests short descriptions instead of TEST1, TEST2, etc.

Joe Lawrence (1):
  selftests/livepatch: introduce tests

 Documentation/livepatch/callbacks.txt  | 487 -
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  15 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 +
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 lib/livepatch/test_klp_shadow_vars.c   | 236 
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/README   |  43 ++
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 196 +++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++
 .../selftests/livepatch/test-shadow-vars.sh|  60 ++
 19 files changed, 1788 insertions(+), 487 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/README
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

--
1.8.3.1



Re: [PATCH v3] selftests/livepatch: introduce tests

2018-04-13 Thread Joe Lawrence
On 04/13/2018 07:20 AM, Miroslav Benes wrote:
> Hi,
> 
> On Thu, 12 Apr 2018, Joe Lawrence wrote:
> 
>> Add a few livepatch modules and simple target modules that the included
>> regression suite can run tests against.
> 
> Could you include a brief description which features are tested?

I can add this to the commit msg:

  - basic livepatching (multiple patches, atomic replace)
  - pre/post (un)patch callbacks
  - shadow variable API

Or do you prefer a little more detail?

>  
>> Signed-off-by: Joe Lawrence 
>> ---
> 
>> diff --git a/lib/livepatch/test_klp_shadow_vars.c 
>> b/lib/livepatch/test_klp_shadow_vars.c
>> new file mode 100644
>> index ..18c75b21cb9e
>> --- /dev/null
>> +++ b/lib/livepatch/test_klp_shadow_vars.c
>>
>> +/*
>> + * Shadow variable wrapper functions that echo the function and arguments
>> + * to the kernel log for testing verification.  Don't display raw pointers,
>> + * but use the ptr_id() value instead.
>> + */
>> +void *shadow_get(void *obj, unsigned long id)
>> +{
>> +void *ret = klp_shadow_get(obj, id);
>> +
>> +pr_info("klp_%s(obj=PTR%d, id=0x%lx) = PTR%d\n",
>> +__func__, ptr_id(obj), id, ptr_id(ret));
>> +
>> +return ret;
>> +}
> 
>> +void shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
>> +{
>> +klp_shadow_free(obj, id, dtor);
>> +pr_info("klp_%s(obj=PTR%d, id=0x%lx, dtor=PTR%d)\n",
>> +__func__, ptr_id(obj), id, ptr_id(dtor));
>> +}
> 
> Sparse (make C=1) would be happier with those two being static.

Ah right. I wonder why the kbuild test robot didn't complain about
those, too.  Easy enough to fix up, thanks.

> Otherwise it works as expected. Good job!

Thanks for reviewing.  I'll hold off on posting v4 until Petr (and
others) get a chance to comment.  Perhaps there are other tests that
would be helpful?

-- Joe


[PATCH v2] Add livepatch kselftests

2018-04-10 Thread Joe Lawrence
Round two cleans up a few misc script and build items, adds a shadow
variable test, and reduces the total livepatch kselftest runtime to ~45
seconds.

The tests run on top of Petr's v11 atomic replace feature and v2 of the
shadow variable enhancement patchsets:

  [PATCH 0/8] livepatch: Atomic replace feature
  https://lkml.kernel.org/r/20180323120028.31451-1-pmla...@suse.com

  [PATCH v2 0/2] livepatch: Allocate and free shadow variables more safely
  https://lkml.kernel.org/r/20180405122315.29065-1-pmla...@suse.com

Questions for v3:

  - Should we split off the atomic replace and shadow variable update
tests so that the this patchset could be merged before the ones
listed above?

  - I didn't remove any of the sample modules.  If anyone thinks any of
them should go, let me know.  They serve as nice, simple examples so
I thought they should all stay.

  - Module naming convention: to make the test script easier to grep
module names and filenames, I broke with livepatch convention and
used underscores instead of dashes.  I didn't think it worth the
regex foo to flip back and forth in the test script.

  - More tests from Libor and Nicolai would be welcome!
-- Maybe we separate quicktests (like these) from longer tests if
   needed?

Here's a sample output from a successful test run:

  % time make -C tools/testing/selftests TARGETS=livepatch run_tests
  make: Entering directory `/root/linux/tools/testing/selftests'
  make[1]: Entering directory `/root/linux/tools/testing/selftests/livepatch'
  make[1]: Nothing to be done for `all'.
  make[1]: Leaving directory `/root/linux/tools/testing/selftests/livepatch'
  make[1]: Entering directory `/root/linux/tools/testing/selftests/livepatch'
  TAP version 13
  selftests: test-livepatch.sh
  
  TEST: basic function patching ... ok
  TEST: multiple livepatches ... ok
  TEST: atomic replace livepatch ... ok
  ok 1..1 selftests: test-livepatch.sh [PASS]
  selftests: test-callbacks.sh
  
  TEST: target module before livepatch ... ok
  TEST: module_coming notifier ... ok
  TEST: module_going notifier ... ok
  TEST: module_coming and module_going notifiers ... ok
  TEST: target module not present ... ok
  TEST: pre-patch callback -ENODEV ... ok
  TEST: module_coming + pre-patch callback -ENODEV ... ok
  TEST: multiple target modules ... ok
  TEST: busy target module ... ok
  TEST: multiple livepatches ... ok
  TEST: atomic replace ... ok
  ok 1..2 selftests: test-callbacks.sh [PASS]
  selftests: test-shadow-vars.sh
  
  TEST: basic shadow variable API ... ok
  ok 1..3 selftests: test-shadow-vars.sh [PASS]
  make[1]: Leaving directory `/root/linux/tools/testing/selftests/livepatch'
  make: Leaving directory `/root/linux/tools/testing/selftests'

  real0m46.166s
  user0m0.436s
  sys 0m1.244s


changes from v1:
- Only add $(CC_FLAGS_FTRACE) for target modules
- Remove between test delay
- Reduce RETRY_INTERVAL to .1 sec
- Reduce test_callback_mod's busymod_work_func delay from 60 to 10 sec
- s/PASS/ok and s/FAIL/not ok for test output
- Move test descriptions from Documentation/livepatch/callbacks.txt
  into tools/testing/selftests/livepatch/test-callbacks.sh
- Add a shadow variable test script and module
- Add a short tools/testing/selftests/livepatch/README
- to += linux-kselft...@vger.kernel.org
- cc += Libor, Nicolai, Artem

change from rfc:
- SPDX-License-Identifiers
- Moved livepatch test modules into lib/livepatch
- Renamed livepatch.sh (filename suffix)
- Reduced between-test delay time
- Split off common functions.sh file
- Split into separate livepatch, callbacks, and shadow-vars scrips
- Gave the tests short descriptions instead of TEST1, TEST2, etc.

Joe Lawrence (1):
  selftests/livepatch: introduce tests

 Documentation/livepatch/callbacks.txt  | 487 -
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  15 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 +
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 lib/livepatch/test_klp_shadow_vars.c   | 235 
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 196 +++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++
 .../selftests

[PATCH v2] selftests/livepatch: introduce tests

2018-04-10 Thread Joe Lawrence
Add a few livepatch modules and simple target modules that the included
regression suite can run tests against.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt  | 487 -
 lib/Kconfig.debug  |  12 +
 lib/Makefile   |   2 +
 lib/livepatch/Makefile |  15 +
 lib/livepatch/test_klp_atomic_replace.c|  69 +++
 lib/livepatch/test_klp_callbacks_busy.c|  43 ++
 lib/livepatch/test_klp_callbacks_demo.c| 132 +
 lib/livepatch/test_klp_callbacks_demo2.c   | 104 
 lib/livepatch/test_klp_callbacks_mod.c |  24 +
 lib/livepatch/test_klp_livepatch.c |  62 +++
 lib/livepatch/test_klp_shadow_vars.c   | 235 
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/livepatch/Makefile |   8 +
 tools/testing/selftests/livepatch/config   |   1 +
 tools/testing/selftests/livepatch/functions.sh | 196 +++
 .../testing/selftests/livepatch/test-callbacks.sh  | 607 +
 .../testing/selftests/livepatch/test-livepatch.sh  | 173 ++
 .../selftests/livepatch/test-shadow-vars.sh|  60 ++
 18 files changed, 1744 insertions(+), 487 deletions(-)
 create mode 100644 lib/livepatch/Makefile
 create mode 100644 lib/livepatch/test_klp_atomic_replace.c
 create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
 create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
 create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
 create mode 100644 lib/livepatch/test_klp_livepatch.c
 create mode 100644 lib/livepatch/test_klp_shadow_vars.c
 create mode 100644 tools/testing/selftests/livepatch/Makefile
 create mode 100644 tools/testing/selftests/livepatch/config
 create mode 100644 tools/testing/selftests/livepatch/functions.sh
 create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
 create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
 create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
index c9776f48e458..6ca2801a6bb9 100644
--- a/Documentation/livepatch/callbacks.txt
+++ b/Documentation/livepatch/callbacks.txt
@@ -116,490 +116,3 @@ virtnet_probe() initialized its driver's net_device 
features.  A
 pre/post-patch callback could iterate over all such devices, making a
 similar change to their hw_features value.  (Client functions of the
 value may need to be updated accordingly.)
-
-
-Test cases
-==
-
-What follows is not an exhaustive test suite of every possible livepatch
-pre/post-(un)patch combination, but a selection that demonstrates a few
-important concepts.  Each test case uses the kernel modules located in
-the samples/livepatch/ and assumes that no livepatches are loaded at the
-beginning of the test.
-
-
-Test 1
---
-
-Test a combination of loading a kernel module and a livepatch that
-patches a function in the first module.  (Un)load the target module
-before the livepatch module:
-
-- load target module
-- load livepatch
-- disable livepatch
-- unload target module
-- unload livepatch
-
-First load a target module:
-
-  % insmod samples/livepatch/livepatch-callbacks-mod.ko
-  [   34.475708] livepatch_callbacks_mod: livepatch_callbacks_mod_init
-
-On livepatch enable, before the livepatch transition starts, pre-patch
-callbacks are executed for vmlinux and livepatch_callbacks_mod (those
-klp_objects currently loaded).  After klp_objects are patched according
-to the klp_patch, their post-patch callbacks run and the transition
-completes:
-
-  % insmod samples/livepatch/livepatch-callbacks-demo.ko
-  [   36.503719] livepatch: enabling patch 'livepatch_callbacks_demo'
-  [   36.504213] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
-  [   36.504238] livepatch_callbacks_demo: pre_patch_callback: vmlinux
-  [   36.504721] livepatch_callbacks_demo: pre_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   36.505849] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
-  [   37.727133] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
-  [   37.727232] livepatch_callbacks_demo: post_patch_callback: vmlinux
-  [   37.727860] livepatch_callbacks_demo: post_patch_callback: 
livepatch_callbacks_mod -> [MODULE_STATE_LIVE] Normal state
-  [   37.728792] livepatch: 'livepatch_callbacks_demo': patching complete
-
-Similarly, on livepatch disable, pre-patch callbacks run before the
-unpatching transition starts.  klp_objects are reverted, post-patch
-callbacks execute and the transition completes:
-
-  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
-  [   38.510209] livepatch: 'livepatch_callb

Re: [PATCH v2] selftests/livepatch: introduce tests

2018-04-10 Thread Joe Lawrence
On 04/10/2018 04:00 PM, Josh Poimboeuf wrote:
> On Tue, Apr 10, 2018 at 11:15:54AM -0400, Joe Lawrence wrote:
>> +static void test_klp_shadow_vars_exit(void)
>> +{
>> +}
>> +
>> +module_init(test_klp_shadow_vars_init);
>> +module_init(test_klp_shadow_vars_exit);
> 
> For this last line, s/module_init/module_exit/, though I think the exit
> function can just be removed altogether?

D'oh workspace / git user error, I posted an older version :(

But the exit function seems to be required if an init function is
provided.  Here I omitted the exit function:

  % modprobe test_klp_shadow_vars
  % lsmod | grep test_klp_shadow_vars
  test_klp_shadow_vars16384  0
  % rmmod test_klp_shadow_vars
  rmmod: ERROR: could not remove 'test_klp_shadow_vars': Device or
resource busy
  rmmod: ERROR: could not remove module test_klp_shadow_vars: Device or
resource busy

and from kernel/module.c

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
...
/* If it has an init func, it must have an exit func to unload*/
if (mod->init && !mod->exit) {
forced = try_force_unload(flags);
if (!forced) {
/* This module can't be removed */
ret = -EBUSY;
goto out;
}
}
...

> 
> Also I get the following bug (run on latest Linus master + Petr's two
> patch sets):
> 
> [  106.302072] % modprobe test_klp_shadow_vars
> [  106.311165] test_klp_shadow_vars: klp_shadow_get(obj=PTR5, id=0x1234) = 
> PTR0
> [  106.313080] test_klp_shadow_vars:   got expected NULL result
> [  106.314811] BUG: sleeping function called from invalid context at 
> mm/slab.h:421
> [  106.316518] in_atomic(): 1, irqs_disabled(): 1, pid: 2254, name: modprobe
> [  106.318107] 1 lock held by modprobe/2254:
> [  106.319332]  #0: d0851080 (klp_shadow_lock){}, at: 
> __klp_shadow_get_or_alloc+0x88/0x1b0
> [  106.321220] irq event stamp: 4408
> [  106.322176] hardirqs last  enabled at (4407): [] 
> console_unlock+0x44e/0x680
> [  106.323598] hardirqs last disabled at (4408): [] 
> _raw_spin_lock_irqsave+0x27/0x90
> [  106.325041] softirqs last  enabled at (4404): [] 
> __do_softirq+0x39b/0x4fc
> [  106.326469] softirqs last disabled at (4367): [] 
> irq_exit+0xe0/0xf0
> [  106.327901] Preemption disabled at:
> [  106.327905] [] __klp_shadow_get_or_alloc+0x88/0x1b0
> [  106.330117] CPU: 7 PID: 2254 Comm: modprobe Tainted: G  K  
> 4.16.0+ #60
> [  106.331565] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> 1.10.2-2.fc27 04/01/2014
> [  106.333143] Call Trace:
> [  106.334011]  dump_stack+0x8e/0xd5
> [  106.334962]  ___might_sleep+0x185/0x260
> [  106.335997]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
> [  106.337170]  __might_sleep+0x4a/0x80
> [  106.338137]  kmem_cache_alloc_trace+0x20b/0x300
> [  106.339183]  ? ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
> [  106.340341]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
> [  106.341506]  ptr_id+0x5c/0xd0 [test_klp_shadow_vars]
> [  106.342725]  shadow_ctor+0x20/0x40 [test_klp_shadow_vars]
> [  106.343998]  __klp_shadow_get_or_alloc+0xc4/0x1b0
> [  106.345184]  ? shadow_dtor+0x40/0x40 [test_klp_shadow_vars]
> [  106.346494]  klp_shadow_alloc+0x10/0x20
> [  106.347583]  shadow_alloc+0x28/0xa0 [test_klp_shadow_vars]
> [  106.348871]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
> [  106.350200]  test_klp_shadow_vars_init+0x96/0x400 [test_klp_shadow_vars]
> [  106.351646]  ? shadow_free_all+0x40/0x40 [test_klp_shadow_vars]
> [  106.352949]  do_one_initcall+0x61/0x37f
> [  106.353963]  ? rcu_read_lock_sched_held+0x79/0x80
> [  106.355040]  ? kmem_cache_alloc_trace+0x29d/0x300
> [  106.356098]  ? do_init_module+0x27/0x213
> [  106.357090]  do_init_module+0x5f/0x213
> [  106.358047]  load_module+0x2815/0x2e70
> [  106.358992]  ? vfs_read+0x12d/0x150
> [  106.359920]  SYSC_finit_module+0xfc/0x120
> [  106.360870]  ? SYSC_finit_module+0xfc/0x120
> [  106.361839]  SyS_finit_module+0xe/0x10
> [  106.362753]  do_syscall_64+0x7e/0x240
> [  106.363645]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
> [  106.364711] RIP: 0033:0x7f26d0d40b19
> [  106.365799] RSP: 002b:7ffee1de19a8 EFLAGS: 0246 ORIG_RAX: 
> 0139
> [  106.367306] RAX: ffda RBX: 5636550d54b0 RCX: 
> 7f26d0d40b19
> [  106.368573] RDX:  RSI: 563654134186 RDI: 
> 0003
> [  106.369950] RBP: 563654134186 R08:  R09: 
> 5636550d4270
> [  106.371164] R10: 0003 R11: 0246 R12: 
> 
> [  106.372422] R13: 5636550d53b0 R14: 0004 R15: 
&g

Re: [PATCH v3] selftests/livepatch: introduce tests

2018-04-17 Thread Joe Lawrence
On 04/17/2018 04:06 AM, Miroslav Benes wrote:
> On Mon, 16 Apr 2018, Petr Mladek wrote:
> 
>> On Mon 2018-04-16 13:33:55, Miroslav Benes wrote:
>>> On Fri, 13 Apr 2018, Joe Lawrence wrote:
>>>> Thanks for reviewing.  I'll hold off on posting v4 until Petr (and
>>>> others) get a chance to comment.  Perhaps there are other tests that
>>>> would be helpful?
>>
>>> I think it would be useful to have tests for a stack checking and a 
>>> consistency. Nicolai has written some lately for our internal testing, but 
>>> it would take some time to transform them appropriately, I think.
>>
>> The future of the stack handling is not clear at the moment. We should
>> wait how the discussion goes before spending time on test cases for
>> the current behavior.

Roger that on the patch stack discussion.  Once we figure out where that
is heading, we can create tests to verify that we're accurately
following the new rules.

> 
> You're talking about something different. We have to check stacks of all 
> tasks while patching in order to achieve consistency. Tests for that would 
> be useful.

FWIW there is the "busy target module" test in this patch.  It's main
purpose is to verify the behavior of the callbacks in a situation where
one livepatch target holds up the transition (aka the "busy mod").

If Nicolai has created test(s) that specifically target the stack
safeness, even better for future inclusion.

-- Joe


Re: [PATCH v3] selftests/livepatch: introduce tests

2018-04-23 Thread Joe Lawrence
On Fri, Apr 20, 2018 at 02:56:05PM +0200, Libor Pechacek wrote:
> Hi Joe,
> 
> I know I am late to the party, yet have some questions about the code.

Hi Libor,

I'm planning another version, so you're comments are not too late!

> On Thu 12-04-18 10:54:31, Joe Lawrence wrote:
> > Add a few livepatch modules and simple target modules that the included
> > regression suite can run tests against.
> > 
> > Signed-off-by: Joe Lawrence 
> > ---
> [...]
> > diff --git a/tools/testing/selftests/livepatch/functions.sh 
> > b/tools/testing/selftests/livepatch/functions.sh
> > new file mode 100644
> > index ..7aaef80e9edb
> > --- /dev/null
> > +++ b/tools/testing/selftests/livepatch/functions.sh
> > @@ -0,0 +1,196 @@
> > +#!/bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (C) 2018 Joe Lawrence 
> > +
> > +# Shell functions for the rest of the scripts.
> > +
> > +MAX_RETRIES=600
> > +RETRY_INTERVAL=".1"# seconds
> > +
> > +# die(msg) - game over, man
> > +#  msg - dying words
> > +function die() {
> > +   echo "ERROR: $1" >&2
> > +   exit 1
> > +}
> > +
> > +# set_dynamic_debug() - setup kernel dynamic debug
> > +#  TODO - push and pop this config?
> > +function set_dynamic_debug() {
> > +   cat << EOF > /sys/kernel/debug/dynamic_debug/control
> > +file kernel/livepatch/* +p
> > +func klp_try_switch_task -p
> > +EOF
> > +}
> > +
> > +# wait_for_transition(modname)
> > +#  modname - livepatch module name
> > +wait_for_transition() {
> > +   local mod="$1"; shift
> 
> Why is the function waiting for a concrete module to finish the transition?
> Wouldn't checking all modules, and therefore watching the global transition
> state, be equally efficient without the need to provide module name?
> 

This code was thrown together to originally test the callback
implementation.  My thinking was that I'd usually load a livepatch and
then wait for it to finish transitioning before moving onto the next
step...

> > +
> > +   # Wait for livepatch transition  ...
> > +   local i=0
> > +   while [[ $(cat /sys/kernel/livepatch/"$mod"/transition) != "0" ]]; do
> > +   i=$((i+1))
> > +   if [[ $i -eq $MAX_RETRIES ]]; then
> > +   die "failed to complete transition for module $mod"
> 
> FWIW, qa_test_klp tests dump blocking processes' stacks at this place for more
> efficient information exchange between tester and developer.
> (klp_dump_blocking_processes() in https://github.com/lpechacek/qa_test_klp,
> file klp_tc_functions.sh)
> 

... If I read the klp_dump_blocking_processes() code correctly and
understand your comment, you are suggesting that reading (any)
/sys/kernel/livepatch/*/transition would be simpler?  No module
parameter needed as only one should ever be transitioning at a given
time?

> > +# load_mod(modname, params) - load a kernel module
> > +#  modname - module name to load
> > +#   params  - module parameters to pass to modprobe
> > +function load_mod() {
> > +   local mod="$1"; shift
> > +   local args="$*"
> > +
> > +   local msg="% modprobe $mod $args"
> > +   echo "${msg%% }" > /dev/kmsg
> > +   ret=$(modprobe "$mod" "$args" 2>&1)
> > +   if [[ "$ret" != "" ]]; then
> > +   echo "$ret" > /dev/kmsg
> > +   die "$ret"
> > +   fi
> > +
> > +   # Wait for module in sysfs ...
> > +   local i=0
> > +   while [ ! -e /sys/module/"$mod" ]; do
> > +   i=$((i+1))
> > +   if [[ $i -eq $MAX_RETRIES ]]; then
> > +   die "failed to load module $mod"
> > +   fi
> > +   sleep $RETRY_INTERVAL
> > +   done
> > +
> > +   # Wait for livepatch ...
> > +   if [[ $(modinfo "$mod" | awk '/^livepatch:/{print $NF}') == "Y" ]]; then
> > +
> > +   # Wait for livepatch in sysfs ...
> > +   local i=0
> > +   while [ ! -e /sys/kernel/livepatch/"$mod" ]; do
> 
> Hmmm! Good test! Never came to my mind...
> 

I ran into all kinds of weird sysfs timing races, so I got really
paranoid :)

> > +# load_failing_mod(modname, params) - load a kernel module, expect to fail
> > +#  modname - module name to load
> > +#   params  - module parameters to pass to modprobe
> > +function load_failing_mod() {
&g

Re: [PATCH v3] selftests/livepatch: introduce tests

2018-04-24 Thread Joe Lawrence
On 04/23/2018 10:43 AM, Joe Lawrence wrote:
> On Fri, Apr 20, 2018 at 02:56:05PM +0200, Libor Pechacek wrote:
>> On Thu 12-04-18 10:54:31, Joe Lawrence wrote:
>>> +   fi
>>> +   echo "$ret" > /dev/kmsg
>>> +}
>>> +
>>> +# unload_mod(modname) - unload a kernel module
>>> +#  modname - module name to unload
>>> +function unload_mod() {
>>> +   local mod="$1"
>>> +
>>> +   # Wait for module reference count to clear ...
>>> +   local i=0
>>> +   while [[ $(cat /sys/module/"$mod"/refcnt) != "0" ]]; do
>>> +   i=$((i+1))
>>> +   if [[ $i -eq $MAX_RETRIES ]]; then
>>> +   die "failed to unload module $mod (refcnt)"
>>> +   fi
>>> +   sleep $RETRY_INTERVAL
>>> +   done
>>
>> The repeating pattern of "while ; do ; if > retries>; then ..." seems to ask for encapsulation.
>>
> 
> Yeah I definitely agree.  I think at some point I had acquired
> bash-fatigue;  I wasn't sure how to cleanly wrap  around that
> extra logic.  In C, I could do something clever with macros or a
> callback function.  My bash scripting isn't great, so I copied and
> pasted my way through it.  Suggestions welcome.
> 

Okay, here's what I came up with... first off, do you prefer this kind
of transition check vs. looking only at a specific module?

  # check_transition() - verify that no livepatch transition in effect
  function check_transition() {
grep -q '^1$' /sys/kernel/livepatch/*/transition 2>/dev/null
  }

then wrap the retry/timeout logic like:

  # retry_cmd(cmd) - loop a command until it is successful or
  #$MAX_RETRIES, sleeping $RETRY_INTERVAL in
  #between tries
  # cmd - command and its arguments to run
  function retry_cmd() {
local cmd="$*"
local i=0
while eval "$cmd"; do
i=$((i+1))
[[ $i -eq $MAX_RETRIES ]] && return 1
sleep $RETRY_INTERVAL
done
return 0
  }

and the callers to something like:

  # wait_for_transition() - wait until all livepatch transitions clear
  function wait_for_transition() {
retry_cmd check_transition ||
die "failed to complete transition"
  }


I can create similar check() functions to eval for sysfs file existence,
file content, reference count, etc. to remove all the other
retry/timeout loops.

Regards,

-- Joe


Re: [PATCH] selftests/livepatch: introduce tests

2018-04-08 Thread Joe Lawrence
On Fri, Apr 06, 2018 at 09:36:46PM -0500, Josh Poimboeuf wrote:
> On Wed, Mar 28, 2018 at 03:49:48PM -0400, Joe Lawrence wrote:
> > Add a few livepatch modules and simple target modules that the included
> > regression suite can run tests against.
> > 
> > Signed-off-by: Joe Lawrence 
> > ---
> >  lib/Kconfig.debug  |  12 +
> >  lib/Makefile   |   2 +
> >  lib/livepatch/Makefile |  18 +
> >  lib/livepatch/test_klp_atomic_replace.c|  69 +++
> >  lib/livepatch/test_klp_callbacks_busy.c|  43 ++
> >  lib/livepatch/test_klp_callbacks_demo.c| 132 ++
> >  lib/livepatch/test_klp_callbacks_demo2.c   | 104 
> >  lib/livepatch/test_klp_callbacks_mod.c |  24 +
> >  lib/livepatch/test_klp_livepatch.c |  62 +++
> >  tools/testing/selftests/Makefile   |   1 +
> >  tools/testing/selftests/livepatch/Makefile |   8 +
> >  tools/testing/selftests/livepatch/config   |   1 +
> >  tools/testing/selftests/livepatch/functions.sh | 202 
> >  .../testing/selftests/livepatch/test-callbacks.sh  | 526 
> > +
> >  .../testing/selftests/livepatch/test-livepatch.sh  | 177 +++
> >  .../selftests/livepatch/test-shadow-vars.sh|  13 +
> >  16 files changed, 1394 insertions(+)
> >  create mode 100644 lib/livepatch/Makefile
> >  create mode 100644 lib/livepatch/test_klp_atomic_replace.c
> >  create mode 100644 lib/livepatch/test_klp_callbacks_busy.c
> >  create mode 100644 lib/livepatch/test_klp_callbacks_demo.c
> >  create mode 100644 lib/livepatch/test_klp_callbacks_demo2.c
> >  create mode 100644 lib/livepatch/test_klp_callbacks_mod.c
> >  create mode 100644 lib/livepatch/test_klp_livepatch.c
> >  create mode 100644 tools/testing/selftests/livepatch/Makefile
> >  create mode 100644 tools/testing/selftests/livepatch/config
> >  create mode 100644 tools/testing/selftests/livepatch/functions.sh
> >  create mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh
> >  create mode 100755 tools/testing/selftests/livepatch/test-livepatch.sh
> >  create mode 100755 tools/testing/selftests/livepatch/test-shadow-vars.sh
> 
> I love this.  Nice work!
> 
> As you and Petr discussed, it would be nice to get rid of some of the
> delays, and also the callback tests will be very important.

I've got v2 WIP that minimizes the delays, cleans up build flags, and
adds a basic shadow variable test.

Since these tests are based on top of Petr's current patchsets for
atomic replace and shadow variables, it probably makes sense for those
to merge first.  I can post test results to his patchsets if that helps.

These tests are basically a mash up of some of the tedious callback
Documentation and shadow variable sample livepatches.  Since there will
be a lot of duplication, should we just remove redundant doc/samples in
favor of these tests?

-- Joe



[PATCH 2/2] sched/debug: adjust newlines for better alignment

2018-03-19 Thread Joe Lawrence
Scheduler debug stats include newlines that display out of alignment
when prefixed by timestamps.  For example, the dmesg utility:

  % echo t > /proc/sysrq-trigger
  % dmesg
  ...
  [   83.124251]
  runnable tasks:
   S   task   PID tree-key  switches  prio wait-time
  sum-execsum-sleep
  
---

At the same time, some syslog utilities (like rsyslog by default) don't
like the additional newlines control characters, saving lines like this
to /var/log/messages:

  Mar 16 16:02:29 localhost kernel: #012runnable tasks:#012 S   task   
PID tree-key ...
   
Clean these up by moving newline characters to their own SEQ_printf
invocation.  This leaves the /proc/sched_debug unchanged, but brings the
entire output into alignment when prefixed:

  % echo t > /proc/sysrq-trigger
  % dmesg
  ...
  [   62.410368] runnable tasks:
  [   62.410368]  S   task   PID tree-key  switches  prio 
wait-time sum-execsum-sleep
  [   62.410369] 
---
  [   62.410369]  I  kworker/u12:0 5  1932.215593   332   120   
  0.00 3.621252 0.00 0 0 /

and no escaped control characters from rsyslog in /var/log/messages:

  Mar 16 16:15:06 localhost kernel: runnable tasks:
  Mar 16 16:15:06 localhost kernel: S   task   PID tree-key  ...

Signed-off-by: Joe Lawrence 
---
 kernel/sched/debug.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 50026aa2d81e..72c401b3b15c 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -501,12 +501,12 @@ static void print_rq(struct seq_file *m, struct rq *rq, 
int rq_cpu)
 {
struct task_struct *g, *p;
 
-   SEQ_printf(m,
-   "\nrunnable tasks:\n"
-   " S   task   PID tree-key  switches  prio"
-   " wait-time sum-execsum-sleep\n"
-   "---"
-   "\n");
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "runnable tasks:\n");
+   SEQ_printf(m, " S   task   PID tree-key  switches  prio"
+  " wait-time sum-execsum-sleep\n");
+   SEQ_printf(m, "---"
+  "\n");
 
rcu_read_lock();
for_each_process_thread(g, p) {
@@ -527,9 +527,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct 
cfs_rq *cfs_rq)
unsigned long flags;
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-   SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "cfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
 #else
-   SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "cfs_rq[%d]:\n", cpu);
 #endif
SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", "exec_clock",
SPLIT_NS(cfs_rq->exec_clock));
@@ -595,9 +597,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct 
cfs_rq *cfs_rq)
 void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
 {
 #ifdef CONFIG_RT_GROUP_SCHED
-   SEQ_printf(m, "\nrt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "rt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
 #else
-   SEQ_printf(m, "\nrt_rq[%d]:\n", cpu);
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "rt_rq[%d]:\n", cpu);
 #endif
 
 #define P(x) \
@@ -624,7 +628,8 @@ void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq 
*dl_rq)
 {
struct dl_bw *dl_bw;
 
-   SEQ_printf(m, "\ndl_rq[%d]:\n", cpu);
+   SEQ_printf(m, "\n");
+   SEQ_printf(m, "dl_rq[%d]:\n", cpu);
 
 #define PU(x) \
SEQ_printf(m, "  .%-30s: %lu\n", #x, (unsigned long)(dl_rq->x))
-- 
1.8.3.1



[PATCH 0/2] small scheduler debug stat fixups

2018-03-19 Thread Joe Lawrence
A customer noticed some misalignment issues in the scheduler debug stats
caused by line break/continuations.  While the kernel isn't responsible
for log rendering, these trivial changes can help clean up the stats
display with default settings for dmesg/rsyslog/etc.  

Note that /proc/sched_debug didn't suffer from these issues and its
output remains unchanged by this patchset.

Joe Lawrence (2):
  sched/debug: fix per-task line continuation for console
  sched/debug: adjust newlines for better alignment

 kernel/sched/debug.c | 29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

-- 
1.8.3.1



[PATCH 1/2] sched/debug: fix per-task line continuation for console

2018-03-19 Thread Joe Lawrence
When the SEQ_printf() macro prints to the console, it runs a simple
printk() without KERN_CONT "continued" line printing.  The result of
this is oddly wrapped task info, for example:

  % echo t > /proc/sysrq-trigger
  % dmesg
  ...
  runnable tasks:
  ...
  [   29.608611]  I
  [   29.608613]   rcu_sched 8  3252.013846  4087   120
  [   29.608614] 0.0029.090111 0.00
  [   29.608615]  0 0
  [   29.608616]  /

Modify SEQ_printf to use pr_cont() for expected one-line results:

  % echo t > /proc/sysrq-trigger
  % dmesg
  ...
  runnable tasks:
  ...
  [  106.716329]  Scpuhp/537  2006.31502614   120   
  0.00 0.496893 0.00 0 0 /

Signed-off-by: Joe Lawrence 
---
 kernel/sched/debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 1ca0130ed4f9..50026aa2d81e 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -32,7 +32,7 @@
if (m)  \
seq_printf(m, x);   \
else\
-   printk(x);  \
+   pr_cont(x); \
  } while (0)
 
 /*
-- 
1.8.3.1



Re: [PATCH 1/2] sched/debug: fix per-task line continuation for console

2018-03-19 Thread Joe Lawrence
On 03/19/2018 04:17 PM, Peter Zijlstra wrote:
> On Mon, Mar 19, 2018 at 02:35:54PM -0400, Joe Lawrence wrote:
>> When the SEQ_printf() macro prints to the console, it runs a simple
>> printk() without KERN_CONT "continued" line printing.  The result of
>> this is oddly wrapped task info, for example:
>>
>>   % echo t > /proc/sysrq-trigger
>>   % dmesg
>>   ...
>>   runnable tasks:
>>   ...
>>   [   29.608611]  I
>>   [   29.608613]   rcu_sched 8  3252.013846  4087   120
>>   [   29.608614] 0.0029.090111 0.00
>>   [   29.608615]  0 0
>>   [   29.608616]  /
>>
>> Modify SEQ_printf to use pr_cont() for expected one-line results:
>>
>>   % echo t > /proc/sysrq-trigger
>>   % dmesg
>>   ...
>>   runnable tasks:
>>   ...
>>   [  106.716329]  Scpuhp/537  2006.31502614   120
>>  0.00 0.496893 0.00 0 0 /
>>
>> Signed-off-by: Joe Lawrence 
>> ---
>>  kernel/sched/debug.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
>> index 1ca0130ed4f9..50026aa2d81e 100644
>> --- a/kernel/sched/debug.c
>> +++ b/kernel/sched/debug.c
>> @@ -32,7 +32,7 @@
>>  if (m)  \
>>  seq_printf(m, x);   \
>>  else\
>> -printk(x);  \
>> +pr_cont(x); \
> 
> That used to work I think.. I think someone changed how printk() behaves
> somewhere along the lines.
> 

Hi Peter,

This code:

printk("printk one");
printk("printk two\n");

pr_cont("\n");
pr_cont("pr_cont one");
pr_cont("pr_cont two\n");

pr_cont("pr_cont first line\n");
pr_cont("\n");
pr_cont("\n");
pr_cont("pr_cont next line");

Creates this output:

%  uname -r
4.16.0-rc5+

% dmesg
[  575.221280] printk one
[  575.221281] printk two
[  575.221282] pr_cont onepr_cont two
[  575.221283] pr_cont first line

I don't have the commit offhand that changed the printk behavior, but
from observation:

  1 - printk implies a trailing newline:
  https://lwn.net/Articles/732420/

  2 - pr_cont seems to eat redundant newlines

> Does pr_cont("\n") DTRT? it seems like something weird.
> 

Yeah, pr_cont() is kind of a hack.  It will terminate a line if that's
the first newline, but as demonstrated above, I don't think it likes
extra newline chars.

A better fix would be to marshal the text into temp buffer then dump it
out.  Dunno if you prefer that kind of churn for these stats.

-- Joe


Re: [PATCH v10 00/10] livepatch: Atomic replace feature

2018-03-07 Thread Joe Lawrence
On 03/07/2018 03:20 AM, Petr Mladek wrote:
> The atomic replace allows to create cumulative patches. They
> are useful when you maintain many livepatches and want to remove
> one that is lower on the stack. In addition it is very useful when
> more patches touch the same function and there are dependencies
> between them.
> 
> 
> Changes against v9:
> 
>   + Fixed check of valid NOPs for already loaded objects,
> regression introduced in v9 [Joe, Mirek]
>   + Allow to replace even disabled patches [Evgenii]
> 
> Changes against v8:
> 
>   + Fixed handling of statically defined struct klp_object
> with empty array of functions [Joe, Mirek]
>   + Removed redundant func->new_func assignment for NOPs [Mirek]
>   + Improved some wording [Mirek]
>
> [ ... snip ... ]

Hi Petr,

I tried updating the test cases I was adding in "[PATCH v0 0/3]
additional cumulative livepatch doc/samples" and although one of the
cases is better than before, I'm running into a new issue:  an expected
pre-unpatch callback is not executed (its obj->patched is false).

Here's the updated test case:

Test 11
---

- load livepatch
- load second livepatch (atomic replace) <- callbacks ok
- disable second livepatch   <- pre-unpatch skipped
- unload livepatch
- unload second livepatch

  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  [ 2306.806046] livepatch: enabling patch 'livepatch_callbacks_demo'
  [ 2306.806048] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
  [ 2306.806083] livepatch_callbacks_demo: pre_patch_callback: vmlinux
  [ 2306.806083] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
  [ 2307.743170] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
  [ 2307.743317] livepatch_callbacks_demo: post_patch_callback: vmlinux
  [ 2307.743319] livepatch: 'livepatch_callbacks_demo': patching complet

  % insmod samples/livepatch/livepatch-callbacks-demo2.ko replace=1
  [ 2316.161804] livepatch: enabling patch 'livepatch_callbacks_demo2'
  [ 2316.161807] livepatch: 'livepatch_callbacks_demo2': initializing patching 
transition
  [ 2316.161842] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
  [ 2316.161843] livepatch: 'livepatch_callbacks_demo2': starting patching 
transition
  [ 2317.727141] livepatch: 'livepatch_callbacks_demo2': completing patching 
transition
  [ 2317.727254] livepatch_callbacks_demo2: post_patch_callback: vmlinux
  [ 2317.727255] livepatch: 'livepatch_callbacks_demo2': patching complete

  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  [ 2328.995854] livepatch: 'livepatch_callbacks_demo2': initializing 
unpatching transition
  [ 2328.995898] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
  [ 2330.719234] livepatch: 'livepatch_callbacks_demo2': completing unpatching 
transition
  [ 2330.719597] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
  [ 2330.719599] livepatch: 'livepatch_callbacks_demo2': unpatching complete

  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo.ko

Running against v10, callbacks seem to be good up until I disable an
atomic replace patch.  My understanding is that the original patch's
unpatch callbacks should be skipped (as they were).  I was surprised to
see that atomic replacement patch only ran it's post-unpatch callback.

Unfortunately I'm running out of time to further debug today, but
thought I would share these results.  I can dig in more tomorrow.

Regards,

-- Joe


Re: [PATCH v8 8/8] livepatch: Atomic replace and cumulative patches documentation

2018-02-23 Thread Joe Lawrence
On 02/23/2018 05:41 AM, Miroslav Benes wrote:
> On Wed, 21 Feb 2018, Petr Mladek wrote:
> 
>> User documentation for the atomic replace feature. It makes it easier
>> to maintain livepatches using so-called cumulative patches.
>>
>> Signed-off-by: Petr Mladek 
> 
> Acked-by: Miroslav Benes 
> 
> Joe, are you planning to extend shadow vars documentation you mentioned 
> before (v7), or do you want Petr to do it?

I created a sample cumulative patch for testing (I can post later),
but I had a quick question regarding the callbacks...

>From v8 of the patch:

  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
executed. Any callbacks from the replaced patches are ignored.

maybe I'm not testing this as intended, but I'm not seeing this
behavior with the latest version of the patch.  See below.


Init


Setup dynamic debug messages:

  % echo "file kernel/livepatch/* +p" > /sys/kernel/debug/dynamic_debug/control
  % echo "func klp_try_switch_task -p" >> 
/sys/kernel/debug/dynamic_debug/control


Test 1
==

Copy the original callbacks demo, leave the atomic .replace feature off:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:38:08.372557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = false,
 };
 
 static int livepatch_callbacks_demo_init(void)


Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
  % rmmod samples/livepatch/livepatch-callbacks-demo.ko

All callbacks are called for both livepatch modules (expected):

  % dmesg
  [ 5755.608999] livepatch: enabling patch 'livepatch_callbacks_demo'
  [ 5755.609014] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
> [ 5755.609054] livepatch_callbacks_demo: pre_patch_callback: vmlinux
  [ 5755.609055] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
  [ 5756.704163] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
> [ 5756.704259] livepatch_callbacks_demo: post_patch_callback: vmlinux
  [ 5756.704260] livepatch: 'livepatch_callbacks_demo': patching complete
  [ 5760.231035] livepatch: enabling patch 'livepatch_callbacks_demo2'
  [ 5760.231038] livepatch: 'livepatch_callbacks_demo2': initializing patching 
transition
> [ 5760.231077] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
  [ 5760.231078] livepatch: 'livepatch_callbacks_demo2': starting patching 
transition
  [ 5761.696067] livepatch: 'livepatch_callbacks_demo2': completing patching 
transition
> [ 5761.696166] livepatch_callbacks_demo2: post_patch_callback: vmlinux
  [ 5761.696166] livepatch: 'livepatch_callbacks_demo2': patching complete
  [ 5765.738278] livepatch: 'livepatch_callbacks_demo2': initializing 
unpatching transition
> [ 5765.738319] livepatch_callbacks_demo2: pre_unpatch_callback: vmlinux
  [ 5765.738319] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
  [ 5767.712143] livepatch: 'livepatch_callbacks_demo2': completing unpatching 
transition
> [ 5767.712502] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
  [ 5767.712503] livepatch: 'livepatch_callbacks_demo2': unpatching complete
  [ 5770.909701] livepatch: 'livepatch_callbacks_demo': initializing unpatching 
transition
> [ 5770.909743] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
  [ 5770.909743] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
  [ 5772.704108] livepatch: 'livepatch_callbacks_demo': completing unpatching 
transition
> [ 5772.704215] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
  [ 5772.704216] livepatch: 'livepatch_callbacks_demo': unpatching complete


Test 2
==

Make the second livepatch a cumulative one:

diff -upr samples/livepatch/livepatch-callbacks-{demo.c,demo2.c}
--- samples/livepatch/livepatch-callbacks-demo.c2018-02-23 
09:42:10.370223095 -0500
+++ samples/livepatch/livepatch-callbacks-demo2.c   2018-02-23 
11:16:20.557557153 -0500
@@ -191,6 +191,7 @@ static struct klp_object objs[] = {
 static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
+   .replace = true,
 };
 
 static int livepatch_callbacks_demo_init(void)

Load the two modules, disable and unload:

  % dmesg -C
  % insmod samples/livepatch/livepatch-callbacks-demo.ko
  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
  % rmmod 

[PATCH v0 2/3] livepatch: update documentation/samples for callbacks

2018-02-23 Thread Joe Lawrence
Update livepatch callback documentation and samples with respect to new
atomic replace / cumulative patch functionality.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/callbacks.txt | 102 
 samples/livepatch/Makefile|   1 +
 samples/livepatch/livepatch-callbacks-demo2.c | 162 ++
 3 files changed, 265 insertions(+)
 create mode 100644 samples/livepatch/livepatch-callbacks-demo2.c

diff --git a/Documentation/livepatch/callbacks.txt 
b/Documentation/livepatch/callbacks.txt
index c9776f48e458..b5e67975c5a9 100644
--- a/Documentation/livepatch/callbacks.txt
+++ b/Documentation/livepatch/callbacks.txt
@@ -86,6 +86,13 @@ If the object did successfully patch, but the patch 
transition never
 started for some reason (e.g., if another object failed to patch),
 only the post-unpatch callback will be called.
 
+If a livepatch is replaced by a cumulative patch, then only the
+callbacks belonging to the cumulative patch will be executed.  This
+simplifies the livepatching core for it is the responsibility of the
+cumulative patch to safely revert whatever needs to be reverted.  See
+Documentation/livepatch/cumulative.txt for more information on such
+patches.
+
 
 Example Use-cases
 =
@@ -603,3 +610,98 @@ pre-unpatch callbacks are skipped:
   % rmmod samples/livepatch/livepatch-callbacks-busymod.ko
   [  141.279111] livepatch_callbacks_busymod: busymod_work_func exit
   [  141.279760] livepatch_callbacks_busymod: livepatch_callbacks_mod_exit
+
+
+Test 10
+---
+
+Test loading multiple livepatch modules containing callback routines.
+The livepatching core executes callbacks for all modules.
+
+- load livepatch
+- load second livepatch
+- disable livepatch
+- disable second livepatch
+- unload livepatch
+- unload second livepatch
+
+  % insmod samples/livepatch/livepatch-callbacks-demo.ko
+  [  216.448208] livepatch: enabling patch 'livepatch_callbacks_demo'
+  [  216.448211] livepatch: 'livepatch_callbacks_demo': initializing patching 
transition
+  [  216.448330] livepatch_callbacks_demo: pre_patch_callback: vmlinux
+  [  216.448341] livepatch: 'livepatch_callbacks_demo': starting patching 
transition
+  [  218.720099] livepatch: 'livepatch_callbacks_demo': completing patching 
transition
+  [  218.720179] livepatch_callbacks_demo: post_patch_callback: vmlinux
+  [  218.720180] livepatch: 'livepatch_callbacks_demo': patching complete
+
+  % insmod samples/livepatch/livepatch-callbacks-demo2.ko
+  [  220.126552] livepatch: enabling patch 'livepatch_callbacks_demo2'
+  [  220.126554] livepatch: 'livepatch_callbacks_demo2': initializing patching 
transition
+  [  220.126592] livepatch_callbacks_demo2: pre_patch_callback: vmlinux
+  [  220.126593] livepatch: 'livepatch_callbacks_demo2': starting patching 
transition
+  [  221.728091] livepatch: 'livepatch_callbacks_demo2': completing patching 
transition
+  [  221.728254] livepatch_callbacks_demo2: post_patch_callback: vmlinux
+  [  221.728255] livepatch: 'livepatch_callbacks_demo2': patching complete
+
+  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo2/enabled
+  [  223.434556] livepatch: 'livepatch_callbacks_demo2': initializing 
unpatching transition
+  [  223.434616] livepatch_callbacks_demo2: pre_unpatch_callback: vmlinux
+  [  223.434617] livepatch: 'livepatch_callbacks_demo2': starting unpatching 
transition
+  [  224.736159] livepatch: 'livepatch_callbacks_demo2': completing unpatching 
transition
+  [  224.736660] livepatch_callbacks_demo2: post_unpatch_callback: vmlinux
+  [  224.736662] livepatch: 'livepatch_callbacks_demo2': unpatching complete
+
+  % echo 0 > /sys/kernel/livepatch/livepatch_callbacks_demo/enabled
+  [  227.284070] livepatch: 'livepatch_callbacks_demo': initializing 
unpatching transition
+  [  227.284111] livepatch_callbacks_demo: pre_unpatch_callback: vmlinux
+  [  227.284112] livepatch: 'livepatch_callbacks_demo': starting unpatching 
transition
+  [  228.704142] livepatch: 'livepatch_callbacks_demo': completing unpatching 
transition
+  [  228.704215] livepatch_callbacks_demo: post_unpatch_callback: vmlinux
+  [  228.704216] livepatch: 'livepatch_callbacks_demo': unpatching complete
+
+  % rmmod samples/livepatch/livepatch-callbacks-demo2.ko
+  % rmmod samples/livepatch/livepatch-callbacks-demo.ko
+
+
+Test 11
+---
+
+A similar test as the previous one, except this time load the second
+callback demo module as a cumulative (ie, replacement) patch.  The
+livepatching core will only execute klp_object callbacks for the latest
+cumulative patch on the patch stack.
+
+- load livepatch
+- load second livepatch (atomic replace)
+- disable livepatch
+- disable second livepatch
+- unload livepatch
+- unload second livepatch
+
+  % insmod samples/livepatch/livepatch-callbacks-demo.ko
+  [16435.711175] livepatch: enabling patch 'livepatch_callbacks_demo'
+  [16435.711185] livepatch: 'livepatch_callbacks_demo': initializing pa

[PATCH v0 1/3] livepatch: add sample cumulative patch

2018-02-23 Thread Joe Lawrence
Add a simple atomic replace / cumulative livepatch example.

Signed-off-by: Joe Lawrence 
---
 samples/livepatch/Makefile   |   1 +
 samples/livepatch/livepatch-cumulative.c | 216 +++
 2 files changed, 217 insertions(+)
 create mode 100644 samples/livepatch/livepatch-cumulative.c

diff --git a/samples/livepatch/Makefile b/samples/livepatch/Makefile
index 2472ce39a18d..dd0e2a8af1af 100644
--- a/samples/livepatch/Makefile
+++ b/samples/livepatch/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-shadow-fix2.o
 obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-callbacks-demo.o
 obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-callbacks-mod.o
 obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-callbacks-busymod.o
+obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-cumulative.o
diff --git a/samples/livepatch/livepatch-cumulative.c 
b/samples/livepatch/livepatch-cumulative.c
new file mode 100644
index ..ab036439e08c
--- /dev/null
+++ b/samples/livepatch/livepatch-cumulative.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2018 Joe Lawrence 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * livepatch-callbacks-cumulative.c - atomic replace / cumulative livepatch 
demo
+ *
+ *
+ * Purpose
+ * ---
+ *
+ * Demonstration of atomic replace / cumulative livepatching.
+ *
+ *
+ * Usage
+ * -
+ *
+ * Step 1 - Load the sample livepatch demo
+ *
+ *   insmod samples/livepatch/livepatch-sample.ko
+ *
+ * Notice that /proc/cmdline was modified by the patch.  For the moment,
+ * /proc/meminfo remains unmodified.
+ *
+ *   head /proc/cmdline /proc/meminfo
+ *   ==> /proc/cmdline <==
+ *   this has been live patched
+ *
+ *   ==> /proc/meminfo <==
+ *   MemTotal:4041368 kB
+ *   MemFree: 3323504 kB
+ *   MemAvailable:3619968 kB
+ *   Buffers:2108 kB
+ *   Cached:   484696 kB
+ *   SwapCached:0 kB
+ *   Active:   297960 kB
+ *   Inactive: 262964 kB
+ *   Active(anon):  74296 kB
+ *   Inactive(anon): 8300 kB
+ *
+ *
+ * Step 2 - Load a second patch (on top of sample)
+ *
+ *   insmod samples/livepatch/livepatch-cumulative.ko replace=0
+ *
+ * The second livepatch adds a modification to meminfo_proc_show(),
+ * changing the output of /proc/meminfo.  In this case, the second
+ * livepatch *supplements* the features of the first:
+ *
+ *   head /proc/cmdline /proc/meminfo
+ *   ==> /proc/cmdline <==
+ *   this has been live patched
+ *
+ *   ==> /proc/meminfo <==
+ *   this has been live patched
+ *
+ * and module references and livepatch enable counts reflect both
+ * livepatches accordingly:
+ *
+ *   lsmod | grep livepatch
+ *   livepatch_cumulative16384  1
+ *   livepatch_sample   16384  1
+ *
+ *   head /sys/kernel/livepatch/livepatch_{cumulative,sample}/enabled
+ *   ==> /sys/kernel/livepatch/livepatch_cumulative/enabled <==
+ *   1
+ *
+ *   ==> /sys/kernel/livepatch/livepatch_sample/enabled <==
+ *   1
+ *
+ *
+ * Step 3 - Remove the second patch
+ *
+ *   echo 0 > /sys/kernel/livepatch/livepatch_cumulative/enabled
+ *   rmmod livepatch-cumulative
+ *
+ *
+ * Step 4 - Load a second patch in atomic replace mode
+ *
+ *   insmod samples/livepatch/livepatch-cumulative.ko replace=1
+ *
+ * This time, notice that the second patch has *replaced* the features of
+ * the first place:
+ *
+ *   head /proc/cmdline /proc/meminfo
+ *   ==> /proc/cmdline <==
+ *   BOOT_IMAGE=/vmlinuz-4.16.0-rc2+ root=/dev/mapper/centos-root ro 
console=tty0 console=ttyS0,115200 rd_NO_PLYMOUTH crashkernel=auto 
rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
+ *
+ *   ==> /proc/meminfo <==
+ *   this has been live patched
+ *
+ * The first patch is automatically disabled:
+ *
+ *   lsmod | grep livepatch
+ *   livepatch_cumulative16384  1
+ *   livepatch_sample   16384  0
+ *
+ *   head /sys/kernel/livepatch/livepatch_{cumulative,sample}/enabled
+ *   ==> /sys/kernel/livepatch/livepatch_cumulative/enabled <==
+ *   1
+ *
+ *   ==> /sys/kernel/livepatch/livepatch_sample/enabled <==
+ *   0
+ *
+ *
+ * Step 5 - Clean up
+ *
+ * Since the first patch was replaced, it is already disabled and its
+ * module may be removed:
+ *
+ *   rmmod livepatch_sample
+ *   echo 0 > /sys/kernel/livepatch/livepatch_cumulati

[PATCH v0 3/3] livepatch: update documentation for shadow variables

2018-02-23 Thread Joe Lawrence
Update livepatch shadow variable documentation with respect to new
atomic replace / cumulative patch functionality.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt | 24 
 1 file changed, 24 insertions(+)

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
index 89c66634d600..9a2754cf551c 100644
--- a/Documentation/livepatch/shadow-vars.txt
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -179,6 +179,30 @@ doesn't matter what data value the shadow variable holds, 
its existence
 suggests how to handle the parent object.
 
 
+Use in cumulative patches
+-
+
+Cumulative livepatches provide a "one-stop" module containing all active
+livepatch code.  A cumulative patch disables and replaces any previously
+loaded livepatch.  Shadow variable lifetimes should be carefully
+considered when loading cumulative livepatches:
+
+- If shadow variables lifetimes are specific to livepatch module
+  versions, it may make sense to free them when the corresponding
+  livepatch module is unloaded.
+
+- If shadow variable instances may be safely handled across cumulative
+  livepatch module versions, then it may make sense to free them from
+  unpatch callbacks.  When a cumulative patch replaces an existing
+  livepatch, only the cumulative patch's callbacks will be executed.
+  This means that new cumulative livepatches may be loaded while
+  deprecated / disabled livepatches may be unloaded without clearing
+  existing shadow variables.
+
+See Documentation/livepatch/callbacks.txt and cumulative.txt for more
+information on these subjects.
+
+
 3. References
 =
 
-- 
1.8.3.1



[PATCH v0 0/3] additional cumulative livepatch doc/samples

2018-02-23 Thread Joe Lawrence
Hi Miroslav,

This is a follow up to my comment on "Re: [PATCH v8 8/8] livepatch:
Atomic replace and cumulative patches documentation".

Here's what I was working on today, I can update for v9 and squash into
a single patch or two if that fits into the patchset better.  (Or Petr,
feel free to grab these and run with them if you prefer.)

I definitely agree that the complexity of the scenarios and cornercases
is starting to get out of hand, at least in keeping it all in my brain
for any period of time :)

I like the idea of transforming the growing sample set into a testsuite
of some kind.  Having regression tests would ease the burden of
reviewing patches and accounting for all these use cases!

Hope these help, let me know if you'd like any modification or other
tests.

Joe Lawrence (3):
  livepatch: add sample cumulative patch
  livepatch: update documentation/samples for callbacks
  livepatch: update documentation for shadow variables

 Documentation/livepatch/callbacks.txt | 102 
 Documentation/livepatch/shadow-vars.txt   |  24 +++
 samples/livepatch/Makefile|   2 +
 samples/livepatch/livepatch-callbacks-demo2.c | 162 +++
 samples/livepatch/livepatch-cumulative.c  | 216 ++
 5 files changed, 506 insertions(+)
 create mode 100644 samples/livepatch/livepatch-callbacks-demo2.c
 create mode 100644 samples/livepatch/livepatch-cumulative.c

-- 
1.8.3.1



Re: [PATCH v8 7/8] livepatch: Correctly handle atomic replace for not yet loaded modules

2018-03-02 Thread Joe Lawrence
On 03/01/2018 05:28 AM, Petr Mladek wrote:
> On Thu 2018-02-22 22:00:28, Miroslav Benes wrote:
>> On Wed, 21 Feb 2018, Petr Mladek wrote:
>>> This patch allows the late initialization.
>>>
>>> diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
>>> index ad508a86b2f9..da1438d47d83 100644
>>> --- a/kernel/livepatch/core.c
>>> +++ b/kernel/livepatch/core.c
>>> @@ -984,7 +988,12 @@ static void klp_free_patch(struct klp_patch *patch)
>>>  
>>>  static int klp_init_func(struct klp_object *obj, struct klp_func *func)
>>>  {
>>> -   if (!func->old_name || !func->new_func)
>>> +   if (!func->old_name)
>>> +   return -EINVAL;
>>> +
>>> +   /* NOPs do not know the address until the patched module is loaded. */
>>> +   if (!func->new_func &&
>>> +   (!klp_is_func_type(func, KLP_FUNC_NOP) || 
>>> klp_is_object_loaded(obj)))
>>> return -EINVAL;
>>
>> If we changed the order of klp_init_func() and klp_init_object_loaded() 
>> calls in klp_init_object(), the hunk would not be needed. Is that correct? 
> 
> Not really. klp_init_object_loaded() would set func->new_func only
> when the object was loaded. But we want to proceed here and create
> the kobject for NOPs even when it was not loaded.
> 
> 
>>> INIT_LIST_HEAD(>stack_node);
>>> @@ -1039,6 +1048,9 @@ static int klp_init_object_loaded(struct klp_patch 
>>> *patch,
>>> return -ENOENT;
>>> }
>>>  
>>> +   if (klp_is_func_type(func, KLP_FUNC_NOP))
>>> +   func->new_func = (void *)func->old_addr;
>>
>> Is there a reason why you left the same assignment in 
>> klp_alloc_func_nop()? This one is enough, no?
> 
> Good point! I am going to replace the obsolete assignment
> with a comment in v8.

Hi Petr, Miroslav,

I don't think the assignment in klp_alloc_func_nop() was necessarily
redundant.  It was removed in v9 and that breaks my atomic replace
sample module when I try to load it.  (Perhaps the sample patch has
issues, but here are my debug notes):

To recap:

  patch 1 - modifies cmdline_proc_show()
  patch 2 - modifies only meminfo_proc_show()

when I load patch 2 with .replace=1, klp_add_nops() is called and this
adds a nop function to patch 2 so it reverts cmdline_proc_show():

klp_init_patch()
  if (patch->replace)
klp_add_nops()
  list_for_each_entry(old_patch, _patches, list) {
klp_for_each_object(old_patch, old_obj) {
  klp_add_object_nops()
klp_add_func_nop()
  klp_alloc_func_nop()

the patch continues initialization and I hit the second -EINVAL
condition on that nop function in klp_init_func():

  klp_init_object
klp_init_func

(from added debug):
[   48.456980] livepatch: func->old_name=cmdline_proc_show
[   48.457620] livepatch: func->new_func=  (null)
[   48.458042] livepatch: klp_is_func_type(func, KLP_FUNC_NOP)=1
[   48.458573] livepatch: klp_is_object_loaded(obj)=1

If I restore the assignment of func->new_func to klp_alloc_func_nop()
then the replacement patch properly loads.  (Reordering the code may
have similar effect?)

I think this problem is contained to only replacement patches that need
the nop-revert feature... if the replacement patch provides a new
function definition, then it shouldn't be affected.

Man, we need a regression test suite for all these cases :)

-- Joe


Re: [PATCH v0 2/3] livepatch: update documentation/samples for callbacks

2018-03-02 Thread Joe Lawrence
On 03/02/2018 06:11 AM, Petr Mladek wrote:
> On Tue 2018-02-27 09:58:40, Joe Lawrence wrote:
>> In my mind, atomic replace is the mechanism that forces patching to be
>> cumulative.  Perhaps this is too strict?  Are there other use-cases for
>> atomic-replace?
> 
> Jason talked about using the atomic replace to get rid of any
> existing livepatches and adding another changes instead. The changes
> in the old and the new patch might be unrelated. They simply do
> not want to mind what was there before. The term "atomic replace"
> fits perfectly for this usecase.
> 
> My understanding is that cumulative patches do similar thing.
> But the old and new patches should be related. In particular,
> any new patch should include most changes from the older one.
> The only exception is when an old change was wrong and we do
> not want it anymore.

Yes, I can see the semantic difference between these cases.  In my mind,
I am tainted by an understanding of the implementation... so I lazily
optimized both cases under a common terminology.

That said, you're right about potential confusion, so I'll update the
example and docs to remove references to "cumulative" and just call it
"atomic-replace" :)

> PS: I did not added these patches to v9 of the atomic replace
> patchset. It was already big enough. And I hope that v9 might
> be final. In addition, there are no conflicts on the touched
> files side.

I can continue to update as a separate patchset if that helps the the
other patchset reach a quicker conclusion.

As far as licensing, I don't mind modifying for SPDX tags if that's the
way we want to go.

Thanks,

-- Joe


Re: [PATCH v0 2/3] livepatch: update documentation/samples for callbacks

2018-02-27 Thread Joe Lawrence
On 02/27/2018 07:36 AM, Miroslav Benes wrote:
> On Fri, 23 Feb 2018, Joe Lawrence wrote:
> 
>> [ ... snip ... ]
>>  
>> +If a livepatch is replaced by a cumulative patch, then only the
>> +callbacks belonging to the cumulative patch will be executed.  This
>> +simplifies the livepatching core for it is the responsibility of the
>> +cumulative patch to safely revert whatever needs to be reverted.  See
>> +Documentation/livepatch/cumulative.txt for more information on such
>> +patches.
> 
> s/cumulative/atomic replace/ almost everywhere?
> 
> 'Documentation/livepatch/cumulative.txt' should be 
> 'Documentation/livepatch/cumulative-patches.txt' and we may rename it 
> atomic-replace-patches.txt. I don't know. Cumulative patches forms a 
> subset of atomic replace patches in my understanding. The feature itself 
> is more general. Even if practically used for cumulative patches only. But 
> it is for you and Petr to decide.

Hi Miroslav,

Thanks for reviewing!

I guess I'm a little confused about the distinction here.

I understood a "cumulative-patch" to mean that it would contain the sum
of all changes.  So instead of this:

  patch 1 = A
+ patch 2 = B
+ patch 3 = C
---
  net = A + B + C

We can group all of the changes together into a single cumulative-patch
for the same net effect:

  patch 1 = A   -replaced by-
  patch 2 = A + B -replaced by-
  patch 3 = A + B + C

I assumed this would also mean to include any reverted changes as well.
So in the example above, if change C needed to be reverted, then:

  patch 4 = A + B

and that would still be considered a "cumulative-patch".

In my mind, atomic replace is the mechanism that forces patching to be
cumulative.  Perhaps this is too strict?  Are there other use-cases for
atomic-replace?

>>  Example Use-cases
>>  =
>>
>> [ ... snip ... ]
>>
>> +Test 11
>> +---
>> +
>> +A similar test as the previous one, except this time load the second
>> +callback demo module as a cumulative (ie, replacement) patch.  The
>> +livepatching core will only execute klp_object callbacks for the latest
>> +cumulative patch on the patch stack.
>> +
>> +- load livepatch
>> +- load second livepatch (atomic replace)
>> +- disable livepatch
> 
> Not needed.

Good catch.

-- Joe


Re: [PATCH v5 0/2] kprobes: improve error handling when arming/disarming kprobes

2018-02-13 Thread Joe Lawrence
Was this patch ever picked up in the tip tree?  (Maybe I'm not looking
in the right branch?)

Thanks,

-- Joe


On 01/19/2018 02:06 AM, Masami Hiramatsu wrote:
> Hi Ingo,
> 
> Could you pick this to tip tree?
> 
> Thank you,
> 
> On Wed, 10 Jan 2018 00:51:22 +0100
> Jessica Yu  wrote:
> 
>> Hi,
>>
>> This patchset attempts to improve error handling when arming or disarming
>> ftrace-based kprobes. The current behavior is to simply WARN when ftrace
>> (un-)registration fails, without propagating the error code. This can lead
>> to confusing situations where, for example, register_kprobe()/enable_kprobe()
>> would return 0 indicating success even if arming via ftrace had failed. In
>> this scenario we'd end up with a non-functioning kprobe even though kprobe
>> registration (or enablement) returned success. In this patchset, we take
>> errors from ftrace into account and propagate the error when we cannot arm
>> or disarm a kprobe.
>>
>> Below is an example that illustrates the problem using livepatch and
>> systemtap (which uses kprobes underneath). Both livepatch and kprobes use
>> ftrace ops with the IPMODIFY flag set, so registration at the same
>> function entry is limited to only one ftrace user. 
>>
>> Before
>> --
>> # modprobe livepatch-sample  # patches cmdline_proc_show, ftrace ops has 
>> IPMODIFY set
>> # stap -e 'probe kernel.function("cmdline_proc_show").call { printf 
>> ("cmdline_proc_show\n"); }'
>>
>>.. (nothing prints after reading /proc/cmdline) ..
>>
>> The systemtap handler doesn't execute due to a kprobe arming failure caused
>> by a ftrace IPMODIFY conflict with livepatch, and there isn't an obvious
>> indication of error from systemtap (because register_kprobe() returned
>> success) unless the user inspects dmesg.
>>
>> After
>> -
>> # modprobe livepatch-sample 
>> # stap -e 'probe kernel.function("cmdline_proc_show").call { printf 
>> ("cmdline_proc_show\n"); }'
>> WARNING: probe 
>> kernel.function("cmdline_proc_show@/home/jeyu/work/linux-next/fs/proc/cmdline.c:6").call
>>  (address 0xa82fe910) registration error (rc -16)
>>
>> Although the systemtap handler doesn't execute (as it shouldn't), the
>> ftrace error is propagated and now systemtap prints a visible error message
>> stating that (kprobe) registration had failed (because register_kprobe()
>> returned an error), along with the propagated error code.
>>
>> This patchset was based on Petr Mladek's original patchset (patches 2 and 3)
>> back in 2015, which improved kprobes error handling, found here:
>>
>>https://lkml.org/lkml/2015/2/26/452
>>
>> However, further work on this had been paused since then and the patches
>> were not upstreamed.
>>
>> This patchset has been lightly sanity-tested (on linux-next) with kprobes,
>> kretprobes, and optimized kprobes. It passes the kprobes smoke test, but
>> more testing is greatly appreciated.
>>
>> Changes from v4:
>>  - Switch from WARN() to pr_debug() in arm_kprobe_ftrace() so the stack
>>dumps don't pollute dmesg, as IPMODIFY conflicts can occur in normal usage
>>  - Added Masami's ack to the first patch
>>
>> Changes from v3:
>>  - Have (dis)arm_kprobe_ftrace() return -ENODEV instead of 0 in case of
>>!CONFIG_KPROBES_ON_FTRACE
>>  - Add total count of all probes tried in (dis)arm_all_kprobes()
>>
>> Changes from v2:
>>  - Add missing synchronize rcu in register_aggr_kprobe()
>>  - s/kprobes/probes/ on error message in (dis)arm_all_kprobes()
>>
>> Changes from v1:
>> - Don't arm the kprobe before adding it to the kprobe table, otherwise
>>   we'll temporarily see a stray breakpoint.
>> - Remove kprobe from the kprobe_table and call synchronize_sched() if
>>   arming during register_kprobe() fails.
>> - add Masami's ack on the 2nd patch (unchanged from v1)
>>
>> ---
>> Jessica Yu (2):
>>   kprobes: propagate error from arm_kprobe_ftrace()
>>   kprobes: propagate error from disarm_kprobe_ftrace()
>>
>>  kernel/kprobes.c | 178 
>> +++
>>  1 file changed, 128 insertions(+), 50 deletions(-)
>>
>> -- 
>> 2.13.6
>>
> 
> 



Re: [PATCH v7 7/7] livepatch: Atomic replace and cumulative patches documentation

2018-02-06 Thread Joe Lawrence
On Tue, Feb 06, 2018 at 11:34:24AM +0100, Petr Mladek wrote:
> User documentation for the atomic replace feature. It makes it easier
> to maintain livepatches using so-called cumulative patches.

Thanks for adding this doc.  A few minor wording suggestions and typos
below...

> 
> Signed-off-by: Petr Mladek 
> ---
>  Documentation/livepatch/cumulative-patches.txt | 76 
> ++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/livepatch/cumulative-patches.txt
> 
> diff --git a/Documentation/livepatch/cumulative-patches.txt 
> b/Documentation/livepatch/cumulative-patches.txt
> new file mode 100644
> index ..5f1f3760b840
> --- /dev/null
> +++ b/Documentation/livepatch/cumulative-patches.txt
> @@ -0,0 +1,76 @@
> +===
> +Atomic Replace & Cumulative Patches
> +===
> +
> +There are dependencies between livepatches when more patches modify the same

s/more/multiple

> +function(s). Then any newer livepatch must include changes from the older 
> ones.

If the new patch wants to maintain the original change that is.
(Perhaps that's implied here.)  

Also this might be a good place to formally introduce the "cumulative
patch" as a recurring term.

> +Also the patches must be registered in the right order.
> +
> +This might become a maintenance nightmare. Especially if anyone would want
> +to remove a patch that is in the middle of the stack.
> +
> +An elegant solution comes with the feature called "Atomic Replace". It allows
> +to create cumulative patches that completely replace all older livepatches.
> +
> +
> +Usage
> +-
> +
> +The atomic replace can be enabled by setting "replace" flag in struct 
> klp_patch,
> +for example:
> +
> + static struct klp_patch patch = {
> + .mod = THIS_MODULE,
> + .objs = objs,
> + .replace = true,
> + };
> +
> +Such a patch is added on top of the livepatch stack when registered. It might
> +be enabled even when some earlier patches have not been enabled yet.

"It can be enabled" reads a little more naturally I think.

> +
> +All processes are then migrated to use the code only from the new patch.
> +Once the transition is finished, all older patches are removed from the stack
> +of patches.

Even the older not-enabled patches mentioned above.

> +
> +Ftrace handlers are transparently removed from functions that are not
> +longer modified by the new cumulative patch.
> +

s/not longer/no longer

> +As a result, the livepatch author might maintain sources only for one
> +cumulative patch. It helps to keep the patch consistent while adding or
> +removing various fixes or features.
> +
> +
> +Limitations:
> +
> +
> +  + Replaced patches can not longer be enabled. But if the transition

s/not longer/no longer

and "the transition" refers to the older patch transition, right?  (Not
the cumulative patching transition.)

> +was not forced, the older patches might be unregistered, removed
> +and eventually used again.
> +
> +
> +  + Only the (un)patching callbacks from the _new_ cumulative livepatch are
> +proceed. Any callbacks from the replaced patches are ignored.

s/proceed/executed

> +
> +By other words, the cumulative patch is responsible for doing any actions
> +that are necessary to properly replace any older patch.
> +
> +As a result, it might be dangerous to replace newer cumulative patches by
> +older ones. The old livepatches might not provide the necessary 
> callbacks.
> +
> +This might be seen as a limitation in some scenarios. But it makes the 
> life
> +easier in many others. Only the new cumulative livepatch knows what
> +fixes/features are added/removed and what special actions are necessary
> +for a smooth transition.
> +
> +In each case, it would be a nightmare to think about the order of
> +the various callbacks and their interactions if the callbacks from all
> +enabled patches were called.

I wonder if this deserves comment or an example in the callbacks
document, even if its a simple, contrived callback.  (I'll think on
this.)

> +
> +
> +  + There is no special handling of shadow variables. Livepatch authors
> +must create their own rules how to pass them from one cumulative
> +patch to the other. Especially they should not blindly remove them
> +in module_exit() functions.
> +
> +A good practice might be to remove shadow variables in the post-unpatch
> +callback. It is called only when the livepatch is properly disabled.

Same here.

-- Joe


[PATCH] livepatch hooks, revisted

2017-07-12 Thread Joe Lawrence
Hi all,

This patch revists the effort that Chris Argus made last year to port
kpatch-style "load hooks" to livepatch:

  https://lkml.org/lkml/2016/8/26/434

Since that discussion, the consistency model has been merged.

This patch locates the hooks in a slightly different place, providing
callbacks to a livepatch module whenever a klp_object is being patched
or unpatched.

A pointer to the current klp_object undergoing (un)patching is also
passed to the hook callback -- with that in hand, the hook
implementation can make decisions based on the current module state
(live, coming, going).

A new Documentation/ file is provided as well as a contrived sample
module and livepatch demo to demonstrate the callbacks.  The example is
about as simple as possible, but could be further embellished to
resemble a real-world livepatch fix if desired.

Thanks,

Joe Lawrence (1):
  livepatch: add (un)patch hooks

 Documentation/livepatch/hooks.txt|  98 +
 include/linux/livepatch.h|  32 
 kernel/livepatch/core.c  |   5 --
 kernel/livepatch/patch.c |  35 +
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-hooks-demo.c | 122 +++
 samples/livepatch/livepatch-hooks-mod.c  |  38 ++
 7 files changed, 327 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/livepatch/hooks.txt
 create mode 100644 samples/livepatch/livepatch-hooks-demo.c
 create mode 100644 samples/livepatch/livepatch-hooks-mod.c

-- 
1.8.3.1



[PATCH] livepatch: add (un)patch hooks

2017-07-12 Thread Joe Lawrence
When the livepatch core executes klp_(un)patch_object, call out to a
livepatch-module specified array of callback hooks.  These hooks provide
a notification mechanism for livepatch modules when klp_objects are
(un)patching. This may be most interesting when another kernel module
is a klp_object target and the livepatch module needs to execute code
after the target is loaded, but before its module_init code is run.

The patch-hook executes right before patching objects and the
unpatch-hook executes right after unpatching objects.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/hooks.txt|  98 +
 include/linux/livepatch.h|  32 
 kernel/livepatch/core.c  |   5 --
 kernel/livepatch/patch.c |  35 +
 samples/livepatch/Makefile   |   2 +
 samples/livepatch/livepatch-hooks-demo.c | 122 +++
 samples/livepatch/livepatch-hooks-mod.c  |  38 ++
 7 files changed, 327 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/livepatch/hooks.txt
 create mode 100644 samples/livepatch/livepatch-hooks-demo.c
 create mode 100644 samples/livepatch/livepatch-hooks-mod.c

diff --git a/Documentation/livepatch/hooks.txt 
b/Documentation/livepatch/hooks.txt
new file mode 100644
index ..ef18101a3b90
--- /dev/null
+++ b/Documentation/livepatch/hooks.txt
@@ -0,0 +1,98 @@
+(Un)patching Hooks
+==
+
+Livepatching (un)patch-hooks provide a mechanism to register and execute
+a set of callback functions when the kernel's livepatching core performs
+an (un)patching operation on a given kernel object.
+
+The hooks are provided and registered by a livepatch module as part of
+klp_objects that make up its klp_patch structure.  Both patch and
+unpatch-hook function signatures accept a pointer to a klp_object
+argument and return an integer status, ie:
+
+  static int patch_hook(struct klp_object *obj)
+  {
+   /* ... */
+  }
+  static int unpatch_hook(struct klp_object *obj)
+  {
+   /* ... */
+  }
+
+  static struct klp_hook patch_hooks[] = {
+   {
+   .hook = patch_hook,
+   }, { }
+  };
+  static struct klp_hook unpatch_hooks[] = {
+   {
+   .hook = unpatch_hook,
+   }, { }
+  };
+
+  static struct klp_object objs[] = {
+   {
+   /* ... */
+   .patch_hooks = patch_hooks,
+   .unpatch_hooks = unpatch_hooks,
+   }, { }
+  };
+
+  static struct klp_patch patch = {
+   .mod = THIS_MODULE,
+   .objs = objs,
+  };
+
+If a hook returns non-zero status, the livepatching core will log a
+hook failure warning message.
+
+Multiple (un)patch-hooks may be registered per klp_object.  Each hook
+will execute regardless of any previously executed hook's non-zero
+return status.
+
+Hooks are optional.  The livepatching core will not execute any
+callbacks for an empty klp_hook.hook array or a NULL klp_hook.hook
+value.
+
+
+For module targets
+--
+
+In the case of kernel module objects, patch-hooks provide a livepatch
+module opportunity to defer execution until a target module is loaded.
+Similarly, unpatch-hooks only call back into a livepatch module after a
+target module has itself cleaned up.  In these cases, the order of
+execution looks like:
+
+  load kernel module
+  execute all patch_hooks[] for this kernel object
+  livepatch kernel object
+  execute module_init function
+
+  ...
+
+  unload kernel module
+  execute module_exit function
+  livepatch restore kernel object
+  execute all unpatch_hooks[] for this kernel object
+
+On the other hand, if a target kernel module is already present when a
+livepatch is loading, then the corresponding patch hook(s) will execute
+as soon as the livepatching kernel core enables the livepatch.
+
+It may be useful for hooks to inspect the module state of the klp_object
+it is passed (i.e. obj->mod->state).  Patch hooks can expect to see
+modules in MODULE_STATE_LIVE and MODULE_STATE_COMING states.  Unpatch
+hooks can expect modules in MODULE_STATE_LIVE and MODULE_STATE_GOING
+states.
+
+
+For vmlinux target
+--
+
+As the kernel is always loaded, patch-hooks for vmlinux will execute as
+soon as the livepatch core enables the livepatch.  Patch-hooks will also
+run if the livepatch is disabled and then re-enabled.
+
+Unpatch-hooks for vmlinux will only execute when the livepatch is
+disabled.
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index 194991ef9347..d95050386ac7 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -87,10 +87,23 @@ struct klp_func {
bool transition;
 };
 
+struct klp_object;
+
+/**
+ * struct klp_hook - hook structure for live patching
+ * @hook:  function to be executed on hook
+ *
+ */
+struct klp_hook {
+   int (*hook)(struct klp_object *obj);
+};
+
 /**
  * struct klp_object - kernel object structure fo

Re: [PATCH] livepatch: add (un)patch hooks

2017-07-14 Thread Joe Lawrence
On Thu, Jul 13, 2017 at 08:46:40PM -0500, Josh Poimboeuf wrote:
> Date: Thu, 13 Jul 2017 20:46:40 -0500
> From: Josh Poimboeuf 
> To: Joe Lawrence 
> Cc: live-patch...@vger.kernel.org, linux-kernel@vger.kernel.org, Jessica Yu
>  , Jiri Kosina , Miroslav Benes
>  , Petr Mladek , Chris J Arges
>  
> Subject: Re: [PATCH] livepatch: add (un)patch hooks
> User-Agent: Mutt/1.6.0.1 (2016-04-01)
> 
> On Wed, Jul 12, 2017 at 10:10:00AM -0400, Joe Lawrence wrote:
> > When the livepatch core executes klp_(un)patch_object, call out to a
> > livepatch-module specified array of callback hooks.  These hooks provide
> > a notification mechanism for livepatch modules when klp_objects are
> > (un)patching. This may be most interesting when another kernel module
> > is a klp_object target and the livepatch module needs to execute code
> > after the target is loaded, but before its module_init code is run.
> 
> And it's also useful for vmlinux.  Patch module load/unload is separate
> from enable/disable, so the module init/exit functions can't be used for
> patch-specific changes (e.g., global data changes).
> 
> > The patch-hook executes right before patching objects and the
> > unpatch-hook executes right after unpatching objects.
> > 
> > Signed-off-by: Joe Lawrence 
> 
> Thanks for posting it.  We found this to be a useful feature in the
> past, not quite as useful as shadow data, but still good to have for
> certain cases.
> 
> Instead of "load hooks" I think it would be more accurate to call them
> "enable/disable hooks".  (Maybe "callbacks" would be better than
> "hooks"?  Not sure...)

Hi Josh,

I hesitataed in calling them "enable/disable" hooks as I associated
those terms at the patch level -- a livepatch might be enabled, but
callbacks for a module may not occur until its actually loaded.  (I'm
fine with whatever is most intuitive to the livepatching collective :)

"Callbacks" vs. "hooks" is a good point though, as the latter has
negative connotations, especially when callers of this facility will be
mostly out of tree.

> Even better, we might want to be specific: "pre enable hooks" and "post
> disable hooks".  (Or "pre patch hooks" and "post unpatch hooks"?)
> Because we might eventually decide we need the corresponding "post
> enable hooks" and "pre disable hooks" as well.

"Pre-patch" and "post-unpatch" are a bit wordy, but a good description.
I already felt it was important enough to document the order of
operations in the doc file and commit msg, so I like this idea. 

> For the enable case, I think it would be a nice feature if we checked
> the return code and aborted the patching operation on error.  I think
> that should be easy enough.

Yeah, that should be easy.  To be specific, you're only talking about
the patching operation on the associated klp_object, not the entire
klp_patch right?

> For the unload case, it's too late to do anything, so I'd say a void
> return code would be better.  Otherwise it implies that we actually do
> something about it.  Maybe in that case we can leave it up to the user
> to decide whether to print an error or WARN() or whatever.

Good point.  I can change that in v2.

Thanks,

-- Joe


Re: [PATCH v2 1/2] livepatch: introduce shadow variable API

2017-07-07 Thread Joe Lawrence
On Fri, Jun 30, 2017 at 09:49:46PM +0800, kbuild test robot wrote:
> Date: Fri, 30 Jun 2017 21:49:46 +0800
> From: kbuild test robot 
> To: Joe Lawrence 
> Cc: kbuild-...@01.org, live-patch...@vger.kernel.org,
>  linux-kernel@vger.kernel.org, Josh Poimboeuf ,
>  Jessica Yu , Jiri Kosina , Miroslav
>  Benes , Petr Mladek 
> Subject: Re: [PATCH v2 1/2] livepatch: introduce shadow variable API
> User-Agent: Mutt/1.5.23 (2014-03-12)
> 
> Hi Joe,
> 
> [auto build test WARNING on jikos-livepatching/for-next]
> [also build test WARNING on v4.12-rc7 next-20170630]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Joe-Lawrence/livepatch-introduce-shadow-variable-API/20170630-061942
> base:   
> https://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git 
> for-next
> config: s390-performance_defconfig (attached as .config)
> compiler: s390x-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> wget 
> https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=s390 
> 
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
> 
> All warnings (new ones prefixed by >>):
> 
>In file included from include/linux/irqflags.h:15:0,
> from arch/s390/include/asm/processor.h:35,
> from arch/s390/include/asm/thread_info.h:24,
> from include/linux/thread_info.h:37,
> from arch/s390/include/asm/preempt.h:5,
> from include/linux/preempt.h:80,
> from include/linux/spinlock.h:50,
> from include/linux/rcupdate.h:38,
> from include/linux/rculist.h:10,
> from include/linux/hashtable.h:13,
> from kernel/livepatch/shadow.c:49:
>kernel/livepatch/shadow.c: In function '_klp_shadow_attach':
> >> arch/s390/include/asm/irqflags.h:63:12: warning: 'flags' may be used 
> >> uninitialized in this function [-Wmaybe-uninitialized]
>  if (flags & ARCH_IRQ_ENABLED)
>^
>kernel/livepatch/shadow.c:135:16: note: 'flags' was declared here
>  unsigned long flags;
>^
> --
>In file included from include/linux/irqflags.h:15:0,
> from arch/s390/include/asm/processor.h:35,
> from arch/s390/include/asm/thread_info.h:24,
> from include/linux/thread_info.h:37,
> from arch/s390/include/asm/preempt.h:5,
> from include/linux/preempt.h:80,
> from include/linux/spinlock.h:50,
> from include/linux/rcupdate.h:38,
> from include/linux/rculist.h:10,
> from include/linux/hashtable.h:13,
> from kernel//livepatch/shadow.c:49:
>kernel//livepatch/shadow.c: In function '_klp_shadow_attach':
> >> arch/s390/include/asm/irqflags.h:63:12: warning: 'flags' may be used 
> >> uninitialized in this function [-Wmaybe-uninitialized]
>  if (flags & ARCH_IRQ_ENABLED)
>^
>kernel//livepatch/shadow.c:135:16: note: 'flags' was declared here
>  unsigned long flags;
>^
> 
> vim +/flags +63 arch/s390/include/asm/irqflags.h
> 
> 94c12cc7d include/asm-s390/irqflags.h  Martin Schwidefsky2006-09-28  
> 47  }
> 94c12cc7d include/asm-s390/irqflags.h  Martin Schwidefsky2006-09-28  
> 48  
> f433c4aec arch/s390/include/asm/irqflags.h Steven Rostedt2011-07-24  
> 49  static inline notrace void arch_local_irq_disable(void)
> df9ee2927 arch/s390/include/asm/irqflags.h David Howells 2010-10-07  
> 50  {
> df9ee2927 arch/s390/include/asm/irqflags.h David Howells 2010-10-07  
> 51   arch_local_irq_save();
> df9ee2927 arch/s390/include/asm/irqflags.h David Howells 2010-10-07  
> 52  }
> 1f194a4c3 include/asm-s390/irqflags.h  Heiko Carstens2006-07-03  
> 53  
> f433c4aec arch/s390/include/asm/irqflags.h Steven Rostedt2011-07-24  
> 54  static inline notrace void arch_local_irq_enable(void)
> 94c12cc7d include/asm-s390/irqflags.h  Martin Schwidefsky2006-09-28  
> 55  {
> df9ee2927 arch/s390/include/asm/irqflags.h David Howells 2010-10-07  
> 56   __arch_local_irq_stosm(0x03);
> 94c12cc7d include/asm-s390/irqflags.h 

[PATCH v2 0/2] livepatch: add shadow variable API

2017-06-28 Thread Joe Lawrence
This is v2 of the shadow variable implementation patchset, incorporating
much of the feedback from the first version:

v2:
  - squashed the Documentation patch with the API implementation patch

  - converted API parameter/return documentation to docbook style comments
in the .c implementation

  - converted the klp_shadow string descriptor to an unsigned long

  - combined shadow data and klp_shadow structure to one allocation

  - adopted kfree_rcu() suggestion

  - added klp_shadow_get_or_create() to the API to help avoid racing
klp_shadow_get + klp_shadow_attach() instances

  - added klp_shadow_detach_all() to the API to cleanup a set of
<*, num> shadow variables

  - created a new set of sample modules to demonstrate the API:
- a buggy module
- fix 1 to plug a memory leak in newly allocate data structures
- fix 2 to add functionality to in-flight data structures

The sample modules are contrived to demonstrate the shadow variable API.
Instead of patching already in-tree code, I created a simple module to
avoid any kallsyms workarounds.  That said, the description and
demonstration debug printing could stand further refinement.  IMHO, the
code is easier to follow than the periodic kernel messages logged.
Suggestions welcome.

Joe Lawrence (2):
  livepatch: introduce shadow variable API
  livepatch: add shadow variable sample programs

 Documentation/livepatch/shadow-vars.txt   | 156 +
 include/linux/livepatch.h |   8 +
 kernel/livepatch/Makefile |   2 +-
 kernel/livepatch/shadow.c | 257 ++
 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 160 ++
 samples/livepatch/livepatch-shadow-fix2.c | 157 +
 samples/livepatch/livepatch-shadow-mod.c  | 353 ++
 9 files changed, 1097 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

-- 
1.8.3.1



[PATCH v2 1/2] livepatch: introduce shadow variable API

2017-06-28 Thread Joe Lawrence
Add exported API for livepatch modules:

  klp_shadow_get()
  klp_shadow_attach()
  klp_shadow_get_or_attach()
  klp_shadow_detach()
  klp_shadow_detach_all()

that implement "shadow" variables, which allow callers to associate new
shadow fields to existing data structures.  This is intended to be used
by livepatch modules seeking to emulate additions to data structure
definitions.

See Documentation/livepatch/shadow-vars.txt for a summary of the new
shadow variable API, including a few common use cases.

Signed-off-by: Joe Lawrence 
---
 Documentation/livepatch/shadow-vars.txt | 156 +++
 include/linux/livepatch.h   |   8 +
 kernel/livepatch/Makefile   |   2 +-
 kernel/livepatch/shadow.c   | 257 
 4 files changed, 422 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/livepatch/shadow-vars.txt
 create mode 100644 kernel/livepatch/shadow.c

diff --git a/Documentation/livepatch/shadow-vars.txt 
b/Documentation/livepatch/shadow-vars.txt
new file mode 100644
index ..7f28982e6b1c
--- /dev/null
+++ b/Documentation/livepatch/shadow-vars.txt
@@ -0,0 +1,156 @@
+Shadow Variables
+
+
+Shadow variables are a simple way for livepatch modules to associate new
+"shadow" data to existing data structures.  Original data structures
+(both their definition and storage) are left unmodified and "new" data
+is allocated separately.  A shadow variable hashtable associates a
+string key, enumeration pair with a pointer to the new data.
+
+
+Brief API summary
+-
+
+See the full API usage docbook notes in the livepatch/shadow.c
+implementation.
+
+An in-kernel hashtable references all of the shadow variables.  These
+references are stored/retrieved through a  key pair.
+
+* The klp_shadow variable data structure encapsulates both tracking
+meta-data and shadow-data:
+  - meta-data
+- obj - pointer to original data
+- num - numerical description of new data
+  - new_data[] - storage for shadow data
+
+* klp_shadow_attach() - allocate and add a new shadow variable:
+  - allocate a new shadow variable
+  - push a  key pair into hashtable
+
+* klp_shadow_get() - retrieve a shadow variable new_data pointer
+  - search hashtable for  key pair
+
+* klp_shadow_get_or_attach() - get existing or attach a new shadow variable
+  - search hashtable for  key pair
+  - if not found, call klp_shadow_attach()
+
+* klp_shadow_detach() - detach and free a  shadow variable
+  - find and remove any  references from hashtable
+- if found, release shadow variable
+
+* klp_shadow_detach() - detach and free all <*, num> shadow variables
+  - find and remove any <*, num> references from hashtable
+- if found, release shadow variable
+
+
+Use cases
+-
+
+See the example shadow variable livepatch modules in samples/livepatch
+for full working demonstrations.
+
+Example 1: Commit 1d147bfa6429 ("mac80211: fix AP powersave TX vs.
+wakeup race") added a spinlock to net/mac80211/sta_info.h :: struct
+sta_info.  Implementing this change with a shadow variable is
+straightforward.
+
+Allocation - when a host sta_info structure is allocated, attach a
+shadow variable copy of the ps_lock:
+
+#define PS_LOCK 1
+struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
+   const u8 *addr, gfp_t gfp)
+{
+   struct sta_info *sta;
+   spinlock_t *ps_lock;
+   ...
+   sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
+   ...
+   ps_lock = klp_shadow_attach(sta, PS_LOCK, NULL, sizeof(*ps_lock), gfp);
+   if (!ps_lock)
+   goto shadow_fail;
+   spin_lock_init(ps_lock);
+   ...
+
+Usage - when using the shadow spinlock, query the shadow variable API to
+retrieve it:
+
+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+{
+   spinlock_t *ps_lock;
+   ...
+   /* sync with ieee80211_tx_h_unicast_ps_buf */
+   ps_lock = klp_shadow_get(sta, "ps_lock");
+   if (ps_lock)
+   spin_lock(ps_lock);
+   ...
+   if (ps_lock)
+   spin_unlock(ps_lock);
+   ...
+
+Release - when the host sta_info structure is freed, first detach the
+shadow variable and then free the shadow spinlock:
+
+void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
+{
+   spinlock_t *ps_lock;
+   ...
+   ps_lock = klp_shadow_get(sta, "ps_lock");
+   if (ps_lock)
+   klp_shadow_detach(sta, "ps_lock");
+
+   kfree(sta);
+
+
+Example 2: Commit 82486aa6f1b9 ("ipv4: restore rt->fi for reference
+counting") added a struct fib_info pointer to include/net/route.h ::
+struct rtable. A shadow variable can be used to implement the new
+pointer.
+
+This implementation diverges from the original commit, as it can attach
+the shadow variable when the code actually 

[PATCH v2 2/2] livepatch: add shadow variable sample programs

2017-06-28 Thread Joe Lawrence
Add sample livepatch modules to demonstrate the shadow variable API.

Signed-off-by: Joe Lawrence 
---

Reviewers -- it's probably easier to grok reading livepatch-shadow-mod.c
 *before* the two livepatch modules, livepatch-shadow-fix1.c
 and livepatch-shadow-fix2.c.

 samples/Kconfig   |   5 +-
 samples/livepatch/Makefile|   3 +
 samples/livepatch/livepatch-shadow-fix1.c | 160 ++
 samples/livepatch/livepatch-shadow-fix2.c | 157 +
 samples/livepatch/livepatch-shadow-mod.c  | 353 ++
 5 files changed, 675 insertions(+), 3 deletions(-)
 create mode 100644 samples/livepatch/livepatch-shadow-fix1.c
 create mode 100644 samples/livepatch/livepatch-shadow-fix2.c
 create mode 100644 samples/livepatch/livepatch-shadow-mod.c

diff --git a/samples/Kconfig b/samples/Kconfig
index 9cb63188d3ef..c332a3b9de05 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -71,11 +71,10 @@ config SAMPLE_RPMSG_CLIENT
  the rpmsg bus.
 
 config SAMPLE_LIVEPATCH
-   tristate "Build live patching sample -- loadable modules only"
+   tristate "Build live patching samples -- loadable modules only"
depends on LIVEPATCH && m
help
- Builds a sample live patch that replaces the procfs handler
- for /proc/cmdline to print "this has been live patched".
+ Build sample live patch demonstrations.
 
 config SAMPLE_CONFIGFS
tristate "Build configfs patching sample -- loadable modules only"
diff --git a/samples/livepatch/Makefile b/samples/livepatch/Makefile
index 10319d7ea0b1..539e81d433cd 100644
--- a/samples/livepatch/Makefile
+++ b/samples/livepatch/Makefile
@@ -1 +1,4 @@
 obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-sample.o
+obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-shadow-mod.o
+obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-shadow-fix1.o
+obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-shadow-fix2.o
diff --git a/samples/livepatch/livepatch-shadow-fix1.c 
b/samples/livepatch/livepatch-shadow-fix1.c
new file mode 100644
index ..2e1d9cb89fad
--- /dev/null
+++ b/samples/livepatch/livepatch-shadow-fix1.c
@@ -0,0 +1,160 @@
+/*
+ * livepatch-shadow-fix1.c - Shadow variables, livepatch demo
+ *
+ * Copyright (C) 2017 Joe Lawrence 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+/* Shadow variable enums */
+#define SV_LEAK1
+
+#define T1_PERIOD 1/* allocator thread */
+#define T2_PERIOD (3 * T1_PERIOD)  /* cleanup thread */
+
+struct dummy {
+   struct list_head list;
+   unsigned long jiffies_expire;
+};
+
+struct dummy *livepatch_fix1_dummy_alloc(void)
+{
+   struct dummy *d;
+   void *leak;
+   void **shadow_leak;
+
+   d = kzalloc(sizeof(*d), GFP_KERNEL);
+   if (!d)
+   return NULL;
+
+   /* Dummies live long enough to see a few t2 instances */
+   d->jiffies_expire = jiffies + 1000 * 4 * T2_PERIOD;
+
+   /*
+* 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(int), GFP_KERNEL);
+   shadow_leak =
+   klp_shadow_attach(d, SV_LEAK, , sizeof(leak), GFP_KERNEL);
+
+   pr_info("%s: dummy @ %p, expires @ %lx\n",
+   __func__, d, d->jiffies_expire);
+
+   return d;
+}
+
+void livepatch_fix1_dummy_free(struct dummy *d)
+{
+   void **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_detach(d, SV_LEAK);
+

Re: [PATCH v2 2/2] livepatch: add shadow variable sample programs

2017-07-18 Thread Joe Lawrence
On Tue, Jul 18, 2017 at 04:47:45PM +0200, Petr Mladek wrote:
> Date:   Tue, 18 Jul 2017 16:47:45 +0200
> From: Petr Mladek 
> To: Joe Lawrence 
> Cc: live-patch...@vger.kernel.org, linux-kernel@vger.kernel.org, Josh
>  Poimboeuf , Jessica Yu , Jiri Kosina
>  , Miroslav Benes 
> Subject: Re: [PATCH v2 2/2] livepatch: add shadow variable sample programs
> User-Agent: Mutt/1.5.21 (2010-09-15)
> 
> On Wed 2017-06-28 11:37:27, Joe Lawrence wrote:
> > diff --git a/samples/livepatch/livepatch-shadow-mod.c 
> > b/samples/livepatch/livepatch-shadow-mod.c
> > new file mode 100644
> > index ..423f4b7b0adb
> > --- /dev/null
> > +++ b/samples/livepatch/livepatch-shadow-mod.c
> > + * Usage
> > + * -
> > + *
> > + * Fix the memory leak
> > + * ---
> > + *
> > + * Extend functionality
> > + * 
> 
> When I made first quick look, I had troubles to understand that
> these two sections were still part of the Usage section.

I could double underline "Usage" and keep the single underlines for "Fix
the memory leak' and "Extend functionality" sections if that helps.

>  Also
> the commands how to enable the modules were hidden deep in the
> expected output analyze.

Yeah, v2's examples were hard to summarize and describe through
comments.  The code is pretty simple, but the devil is in the timing
details and log output seemed the best way to illustrate the fixes.

Do you think the log entries are worth copying into these comments?  I
could simply describe the effect and let the reader generate their own
if they so desired.

> I wonder if it would make sense to move most of the information
> into the respective module sources. 

Are you suggesting that it would be clearer to distribute the
log + comments to each individual livepatch-shadow-*.c module file?

> I actually missed some
> more info in that modules. The few lines were hard to spot
> after the long copyright/license blob.

Would a heading like this help separate the legalese from the patch
description?

/* [ ... GPL, copyrights, etc ... ]
 *
 * Module Description
 * ======
 * [...]
 */
 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Joe Lawrence ");
> > +MODULE_DESCRIPTION("Buggy module for shadow variable demo");
> > +
> > +#define T1_PERIOD 1/* allocator thread */
> > +#define T2_PERIOD (3 * T1_PERIOD)  /* cleanup thread */
> > +
> > +LIST_HEAD(dummy_list);
> > +DEFINE_MUTEX(dummy_list_mutex);
> > +
> > +struct dummy {
> > +   struct list_head list;
> > +   unsigned long jiffies_expire;
> > +};
> > +
> > +noinline struct dummy *dummy_alloc(void)
> > +{
> > +   struct dummy *d;
> > +   void *leak;
> > +
> > +   d = kzalloc(sizeof(*d), GFP_KERNEL);
> > +   if (!d)
> > +   return NULL;
> > +
> > +   /* Dummies live long enough to see a few t2 instances */
> > +   d->jiffies_expire = jiffies + 1000 * 4 * T2_PERIOD;
> > +
> > +   /* Oops, forgot to save leak! */
> > +   leak = kzalloc(sizeof(int), GFP_KERNEL);
> > +
> > +   pr_info("%s: dummy @ %p, expires @ %lx\n",
> > +   __func__, d, d->jiffies_expire);
> > +
> > +   return d;
> > +}
> > +
> > +noinline void dummy_free(struct dummy *d)
> > +{
> > +   pr_info("%s: dummy @ %p, expired = %lx\n",
> > +   __func__, d, d->jiffies_expire);
> > +
> > +   kfree(d);
> > +}
> > +
> > +noinline bool dummy_check(struct dummy *d, unsigned long jiffies)
> > +{
> > +   return time_after(jiffies, d->jiffies_expire);
> > +}
> > +
> > +/*
> > + * T1: alloc_thread allocates new dummy structures, allocates additional
> > + * memory, aptly named "leak", but doesn't keep permanent record of it.
> > + */
> > +struct workqueue_struct *alloc_wq;
> 
> A custom workqueue is needed only for special purposes.
> IMHO, the standard system workqueue is perfectly fine
> in our case. AFAIK, it is able to spawn/run about
> 256 worker threads and process this number of different
> works in parallel.

No problem.  This example executes infrequently and obviously isn't high
priority or anything.

> > +struct delayed_work alloc_dwork;
> > +static void alloc_thread(struct work_struct *work)
> 

Re: [PATCH v2 1/2] livepatch: introduce shadow variable API

2017-07-18 Thread Joe Lawrence
On Tue, Jul 18, 2017 at 03:00:47PM +0200, Petr Mladek wrote:
> Date:   Tue, 18 Jul 2017 15:00:47 +0200
> From: Petr Mladek 
> To: Miroslav Benes 
> Cc: Josh Poimboeuf , Joe Lawrence
>  , live-patch...@vger.kernel.org,
>  linux-kernel@vger.kernel.org, Jessica Yu , Jiri Kosina
>  
> Subject: Re: [PATCH v2 1/2] livepatch: introduce shadow variable API
> User-Agent: Mutt/1.5.21 (2010-09-15)
> 
> On Mon 2017-07-17 17:35:38, Miroslav Benes wrote:
> > On Thu, 13 Jul 2017, Josh Poimboeuf wrote:
> > 
> > > On Wed, Jun 28, 2017 at 11:37:26AM -0400, Joe Lawrence wrote:
> > > 
> > > > +Brief API summary
> > > > +-
> > > > +
> > > > +See the full API usage docbook notes in the livepatch/shadow.c
> > > > +implementation.
> > > > +
> > > > +An in-kernel hashtable references all of the shadow variables.  These
> > > > +references are stored/retrieved through a  key pair.
> > > 
> > > "num" is rather vague, how about "key"?
> 
> As Mirek said in the previous version. "obj" is the key for the hash
> table.
> 
> Anyway, I agree that "num" is vague and even confusing. I would
> suggest to use "id".
> 
> > > (And note, this and some of the other comments also apply to the code as
> > > well)
> > > 
> > > > +* The klp_shadow variable data structure encapsulates both tracking
> > > > +meta-data and shadow-data:
> > > > +  - meta-data
> > > > +- obj - pointer to original data
> > > 
> > > Instead of "original data", how about calling it the "parent object"?
> > > That describes it better to me at least.  "Original data" sounds like
> > > some of the data might be replaced.
> > 
> > I agree that "original data" does not sound right. However, we use "parent 
> > object" for vmlinux or a module in our code. But I don't have a better 
> > name and "parent object" sounds good.
> 
> What about "primary object"? I took inspiration from
> https://en.wikipedia.org/wiki/Shadow_table
> 
> > > > +- num - numerical description of new data
> > > 
> > > "numerical description of new data" sounds a little confusing, how about
> > > "unique identifier for new data"?
> 
> Here we come to the "id" ;-)
> 
> I wonder if each patch should register its own IDs and the size of the
> data. The API could shout when anyone wants to use a not yet
> registered ID or when the same ID with another size is being
> registered. It might increase security. But I am not sure
> if it is worth it.
> 
> 
> > > I'm also not sure about the phrase "new data".  Maybe something like
> > > "new data field" would be more descriptive?  Or just "new field"?  I
> > > view it kind of like adding a field to a struct.  Not a big deal either
> > > way.
> > >
> > > > +void *klp_shadow_attach(void *obj, unsigned long num, void *new_data,
> > > > +   size_t new_size, gfp_t gfp_flags);
> > > 
> > > It could be just me, but the "new_" prefixes threw me off a little bit.
> > > The new is implied anyway.  How about just "data" and "size"?
> > > 
> > > And the same comment for the klp_shadow struct.
> > 
> > I agree with Josh on all of this.
> 
> You persuaded me that "data" and "size" make sense after all ;-)
> new_obj would mean that we replace/copy the entire object.

Who knew naming things was so difficult :)

There's been a bunch of feedback on terminology, so I'll just issue a
collective reply to Petr's last msg on the topic.  These were my
thoughts on naming clarification:

  v1,v2 v3
  --
  obj, original dataobj, parent object
  num, numerical description of new dataid, data identifier
  new_data  data
  new_size  data_size

Miroslav also suggested additional text explaining the id / data
identifier field.  How about something like this:

---


Shadow Variables


...

A global, in-kernel hashtable associates parent pointers and a numeric
identifier with shadow variable data.  Specifically, the parent pointer
serves as the hashtable key, while the numeric id further filters
hashtable queries.  The numeric identifier is a simple enumeration that
may be used to describe shadow variable versions (for stacking
livepatches), class or type (for multiple shadow variables per parent),
etc.  Multiple shadow variables may attach to the same parent object,
but their numeric identifier distinguises between them.

---

Thanks for the review suggestions, let me know if I missed any other
terms flagged in one of the other legs of the discussion thread.

-- Joe



Re: [PATCH v2 1/2] livepatch: introduce shadow variable API

2017-07-18 Thread Joe Lawrence
On Mon, Jul 17, 2017 at 05:29:41PM +0200, Miroslav Benes wrote:
>
> On Wed, 28 Jun 2017, Joe Lawrence wrote:
> 
> > +Brief API summary
> > +-
> > + [ ... snip ...]
> > +* klp_shadow_detach() - detach and free all <*, num> shadow variables
> > +  - find and remove any <*, num> references from hashtable
> > +- if found, release shadow variable
> 
> I think that the second one should be klp_shadow_detach_all(), shouldn't 
> it?

Good catch, I'll fixup in v3.

> > +static DEFINE_HASHTABLE(klp_shadow_hash, 12);
> 
> Is there a reason, why you pick 12? I'm just curious.

The hashtable bit-size was inherited from the kpatch implementation.
Perhaps Josh knows why this value was picked?

Aside: we could have per-livepatch hashtables if that was desired, this
value could be then adjusted accordingly.  We haven't needed them for
kpatch, so I didn't see good reason to complicate things.

> > +static DEFINE_SPINLOCK(klp_shadow_lock);
> > +
> > +/**
> > + * struct klp_shadow - shadow variable structure
> > + * @node:  klp_shadow_hash hash table node
> > + * @rcu_head:  RCU is used to safely free this structure
> > + * @obj:   pointer to original data
> > + * @num:   numerical description of new data
> 
> Josh proposed better description. Could we also have a note somewhere in 
> the documentation what this member is practically for? I mean versioning 
> and ability to attach new members to a data structure if live patches are 
> stacked.

That's a good idea and I posted a sample doc-blurb in my other reply to
Petr about terminology.

> > + * @new_data:  new data area
> > + */
> > +struct klp_shadow {
> > +   struct hlist_node node;
> > +   struct rcu_head rcu_head;
> > +   void *obj;
> > +   unsigned long num;
> > +   char new_data[];
> > +};
> 
> What is the reason to change 'void *new_data' to 'char new_data[]'? I 
> assume it is related to API changes below...
> 
> [...]
> 
> > +/**
> > + * _klp_shadow_attach() - allocate and add a new shadow variable
> > + * @obj:   pointer to original data
> > + * @num:   numerical description of new data
> > + * @new_data:  pointer to new data
> > + * @new_size:  size of new data
> > + * @gfp_flags: GFP mask for allocation
> > + * @lock:  take klp_shadow_lock during klp_shadow_hash operations
> 
> I am not sure about lock argument. Do we need it? Common practice is to 
> have function foo() which takes a lock, and function __foo() which does 
> not.
> 
> In klp_shadow_get_or_attach(), you use it as I'd expect. You take the 
> spinlock, call this function and release the spinlock. Is it possible 
> to do the same in klp_shadow_attach() and have __klp_shadow_attach() 
> without lock argument?

Yes, this would be possible, though it would restrict
klp_shadow_attach() from accepting gfp_flags that might allow for
sleeping.  More on that below ...
 
> > + *
> > + * Note: allocates @new_size space for shadow variable data and copies
> > + * @new_size bytes from @new_data into the shadow varaible's own @new_data
> > + * space.  If @new_data is NULL, @new_size is still allocated, but no
> > + * copy is performed.
> 
> I must say I'm not entirely happy with this. I don't know if this is what 
> Petr had in mind (I'm sure he'll get to the patch set soon). Calling 
> memcpy instead of a simple assignment in v1 seems worse. 

This change was a bit of a experiment on my part in reaction to
adding klp_shadow_get_or_attach().

I like the simplicity of v1's pointer assignment -- in fact, moving all
allocation responsiblity (klp_shadow meta-data and data[] area) out to
the caller is doable, though implementing klp_shadow_get_or_attach() and
and klp_shadow_detach_all() complicates matters, for example, adding an
alloc/release callback.  I originally attempted this for v2, but turned
back when the API and implementation grew complicated.  If the memcpy
and gfp_flag restrictions are too ugly, I can try revisting that
approach.  Ideas welcome :)

Regards,

-- Joe


Re: [PATCH] livepatch: add (un)patch hooks

2017-07-19 Thread Joe Lawrence
On 07/17/2017 11:51 AM, Petr Mladek wrote:
> On Wed 2017-07-12 10:10:00, Joe Lawrence wrote:
>> When the livepatch core executes klp_(un)patch_object, call out to a
>> livepatch-module specified array of callback hooks.  These hooks provide
>> a notification mechanism for livepatch modules when klp_objects are
>> (un)patching. This may be most interesting when another kernel module
>> is a klp_object target and the livepatch module needs to execute code
>> after the target is loaded, but before its module_init code is run.
>>
>> The patch-hook executes right before patching objects and the
>> unpatch-hook executes right after unpatching objects.
>>
>> diff --git a/Documentation/livepatch/hooks.txt 
>> b/Documentation/livepatch/hooks.txt
>> new file mode 100644
>> index ..ef18101a3b90
>> --- /dev/null
>> +++ b/Documentation/livepatch/hooks.txt
>> @@ -0,0 +1,98 @@
>> +(Un)patching Hooks
>> +==
>> +
>> +Livepatching (un)patch-hooks provide a mechanism to register and execute
>> +a set of callback functions when the kernel's livepatching core performs
>> +an (un)patching operation on a given kernel object.
> 
> The above is correct but it is a bit hard to understand what it really
> means. Josh's discussion about the naming suggests that I am not the only
> one who is confused ;-)
> 
> We need to make it clear that there are 4 basic situations
> where these hooks are called:
> 
>   + patch hook is called when:
> 
>   1. livepatch is being enabled and object is loaded
>   2. livepatch is enabled and object is being loaded
> 
>   + unpatch hook is called when
> 
>   3. livepatch is enabled and object is being removed
>   4. livepatch is being disabled and object is loaded
> 
> Note that this document mostly talks only about the two situations
> when the livepatch is enabled and the patched object is being
> loaded or removed.
> 
> But it is still quite tricky to understand what can be modified
> a safe way. We need to be careful about different things
> in the different situations.

Indeed, this is tricky.

> If the patched object is beeing added/removed, we know that its
> code is not being used but the code from the rest of the patch
> is already in use. The module is not yet or not longer properly
> initialized. Therefore it might be too early or too late to
> register or unregister any of its services in the rest of
> the system. Basically it limits the changes only to
> to the object (module) itself.
> 
> If the patch is being enabled, it is another story. The object
> is already initialized and its old code is used but the new
> code from the patch is not yet or not longer used. It suggests
> that it might be safe to do some changes related to the
> new code in the patch. But we need to be careful because
> the system is using the old code.
> 
> 
> But there are actually 4 more situations. If we use the consistency
> model, different parts of the system might use different code.
> I mean that:
> 
>   + patch hook is called also when:
> 
>  + livepatch is being enabled and object is being loaded
>  + livepatch is being disabled and object is being loaded
> 
>   + unpatch hook is called when:
> 
>  + livepatch is being enabled and object is being removed
>  + livepatch is being disabled and object is being removed
> 
> 
> It is a bit easier if you run the hook for vmlinux
> because it is always running.
> 
> I am sorry for the long mail. But I have really troubles to
> understand and describe what can be done with these hooks
> a safe way.

If you look at it from the inside out, the concept can be boiled down to
"kernel object patching notifiers".  Essentially whenever a klp_object
is being patched or unpatched, the callbacks are executed.

In this implementation, the patch-hook provides the callback a context
of "your object's patched code is loaded, but not active yet".
Likewise, the unpatch-hook would be "your patched code is no longer
active, but not unloaded (yet)".

I agree that explaining the patch-at-large context quickly gets
complicated.  IMHO, I think some of that discussion belongs in
Documentation/livepatch/livepatch.txt, in a section that answers, "just
when does code get patched?".  In my mind, these notifiers build on top
of the answer to that question.

That said, some kind of guidance about the various contexts in which
these hooks are executed is definitely warranted.  Perhaps some kind of
table or list can summarize things, let me think more on that.

> It might help if you share some real-life examples.

Well, kpatch utilizes "load hooks" and their appli

Re: [PATCH v2 1/2] livepatch: introduce shadow variable API

2017-07-20 Thread Joe Lawrence
On 07/20/2017 10:45 AM, Miroslav Benes wrote:
> 
> + *
> + * Note: allocates @new_size space for shadow variable data and copies
> + * @new_size bytes from @new_data into the shadow varaible's own 
> @new_data
> + * space.  If @new_data is NULL, @new_size is still allocated, but no
> + * copy is performed.

 I must say I'm not entirely happy with this. I don't know if this is what 
 Petr had in mind (I'm sure he'll get to the patch set soon). Calling 
 memcpy instead of a simple assignment in v1 seems worse. 
>>>
>>> This change was a bit of a experiment on my part in reaction to
>>> adding klp_shadow_get_or_attach().
>>>
>>> I like the simplicity of v1's pointer assignment -- in fact, moving all
>>> allocation responsiblity (klp_shadow meta-data and data[] area) out to
>>> the caller is doable, though implementing klp_shadow_get_or_attach() and
>>> and klp_shadow_detach_all() complicates matters, for example, adding an
>>> alloc/release callback.  I originally attempted this for v2, but turned
>>> back when the API and implementation grew complicated.  If the memcpy
>>> and gfp_flag restrictions are too ugly, I can try revisting that
>>> approach.  Ideas welcome :)
>>
>> Well, I didn't like callbacks either :). And no, I do not have a better 
>> idea. I still need to think about it.
> 
> Done and I agree that memcpy approach is not so bad after all :). So I'm 
> fine with it.

I looked at it again this morning and a "pass-your-own" allocation API
always comes back to adding callbacks and other complications :(  In the
end, most callers will be shadowing pointers and not entire structures,
so I think the copy isn't too bad.

On a related note, if we keep the allocations and memcpy, how about I
shift around the attach/get calls like so:

  __klp_shadow_attach
set shadow variable member values
memcpy
add to hash

  klp_shadow_attach
alloc new shadow var
lock
call __klp_shadow_attach with new alloc
unlock

  klp_shadow_get_or_attach
be optimistic, call klp_shadow_get (if found, return it)
be pessimistic, alloc new shadow var
lock
  call klp_shadow_get again
  if unlikely found
kfree unneeded alloc
  else
call __klp_shadow_attach with new alloc
unlock
return whichever shadow var we used

This way both calls can accept gfp_flags that may sleep, with the only
downside that klp_shadow_get_or_attach may allocate an unnecessary
shadow variable in the unlikely case that it's found on the second
klp_shadow_get attempt (under the lock).  No more clunky "bool lock"
flag either. :)

-- Joe


Re: [PATCH v2 1/2] livepatch: introduce shadow variable API

2017-07-20 Thread Joe Lawrence
On 07/18/2017 08:45 AM, Petr Mladek wrote:
> On Wed 2017-06-28 11:37:26, Joe Lawrence wrote:
>> diff --git a/Documentation/livepatch/shadow-vars.txt 
>> b/Documentation/livepatch/shadow-vars.txt
>> new file mode 100644
>> index ..7f28982e6b1c
>> --- /dev/null
>> +++ b/Documentation/livepatch/shadow-vars.txt
>> +Use cases
>> +-
>> +
>> +See the example shadow variable livepatch modules in samples/livepatch
>> +for full working demonstrations.
>> +
>> +Example 1: Commit 1d147bfa6429 ("mac80211: fix AP powersave TX vs.
>> +wakeup race") added a spinlock to net/mac80211/sta_info.h :: struct
>> +sta_info.  Implementing this change with a shadow variable is
>> +straightforward.
>> +
>> +Allocation - when a host sta_info structure is allocated, attach a
>> +shadow variable copy of the ps_lock:
>> +
>> +#define PS_LOCK 1
>> +struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
>> +const u8 *addr, gfp_t gfp)
>> +{
>> +struct sta_info *sta;
>> +spinlock_t *ps_lock;
>> +...
>> +sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
> 
> klp_shadow_attach() does the allocation as well now.
> Note that we could pass already initialized spin_lock.
> 
>> +...
>> +ps_lock = klp_shadow_attach(sta, PS_LOCK, NULL, sizeof(*ps_lock), gfp);
>> +if (!ps_lock)
>> +goto shadow_fail;
>> +spin_lock_init(ps_lock);
>> +...
>> +
>> +Usage - when using the shadow spinlock, query the shadow variable API to
>> +retrieve it:
>> +
>> +void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
>> +{
>> +spinlock_t *ps_lock;
>> +...
>> +/* sync with ieee80211_tx_h_unicast_ps_buf */
>> +ps_lock = klp_shadow_get(sta, "ps_lock");
> 
> s/"ps_lock"/PS_LOCK/
> 
> The same problem is repeated many times below (also in the 2nd
> example).
> 
> Also this is a nice example, where klp_shadow_get_or_attach()
> would be useful. It would fix even already existing instances.
> 
> So, the code might look like:
> 
>   void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
>   {
>   DEFINE_SPINLOCK(ps_lock_fallback)
>   spinlock_t *ps_lock;
>   ...
>   /* sync with ieee80211_tx_h_unicast_ps_buf */
>   ps_lock = klp_shadow_get_or_attach(sta, PS_LOCK,
>   _lock_fallback, sizeof(ps_lock_fallback),
>   GFP_ATOMIC);
> 
> It is a bit ugly that we always initialize ps_lock_fallback
> even when it is not used. But it helps to avoid a custom
> callback that would create the fallback variable. I think
> that it is an acceptable deal.

Yup, it's a tradeoff for the caller.  If they want a shadow variable
added and considered "live", they better have previously initialized it :)

> 
>> +if (ps_lock)
>> +spin_lock(ps_lock);
>> +...
>> +if (ps_lock)
>> +spin_unlock(ps_lock);
>> +...
>> +
>> +Release - when the host sta_info structure is freed, first detach the
>> +shadow variable and then free the shadow spinlock:
>> +
>> +void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
>> +{
>> +spinlock_t *ps_lock;
>> +...
>> +ps_lock = klp_shadow_get(sta, "ps_lock");
>> +if (ps_lock)
>> +klp_shadow_detach(sta, "ps_lock");
> 
> Isn't klp_shadow_detach() enough? If it an optimization, 
> klp_shadow_detach() might get optimized the same way.
> But I am not sure if it is worth it.

Let me go back and review these inline examples for v3... I didn't
update them carefully enough when drafting v2.

>> +kfree(sta);
>> +
>> +
> 
> 
>> diff --git a/kernel/livepatch/shadow.c b/kernel/livepatch/shadow.c
>> new file mode 100644
>> index ..d37a61c57e72
>> --- /dev/null
>> +++ b/kernel/livepatch/shadow.c
>> +/**
>> + * _klp_shadow_attach() - allocate and add a new shadow variable
>> + * @obj:pointer to original data
>> + * @num:numerical description of new data
>> + * @new_data:   pointer to new data
>> + * @new_size:   size of new data
>> + * @gfp_flags:  GFP mask for allocation
>> + * @lock:   take klp_shadow_lock during klp_shadow_hash operations
>> + *
>> + * Note: allocates @new_size space for shadow variable data and copies
>> + * @new_size bytes from @new_data into the shadow varaible's own @new_data
>> + * space.  If

<    1   2   3   4   5   6   7   >