]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Nov 2020 11:57:22 +0000 (12:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Nov 2020 11:57:22 +0000 (12:57 +0100)
added patches:
perf-core-fix-race-in-the-perf_mmap_close-function.patch
perf-scripting-python-avoid-declaring-function-pointers-with-a-visibility-attribute.patch

queue-5.4/perf-core-fix-race-in-the-perf_mmap_close-function.patch [new file with mode: 0644]
queue-5.4/perf-scripting-python-avoid-declaring-function-pointers-with-a-visibility-attribute.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/perf-core-fix-race-in-the-perf_mmap_close-function.patch b/queue-5.4/perf-core-fix-race-in-the-perf_mmap_close-function.patch
new file mode 100644 (file)
index 0000000..39b9b9e
--- /dev/null
@@ -0,0 +1,100 @@
+From f91072ed1b7283b13ca57fcfbece5a3b92726143 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Wed, 16 Sep 2020 13:53:11 +0200
+Subject: perf/core: Fix race in the perf_mmap_close() function
+
+From: Jiri Olsa <jolsa@redhat.com>
+
+commit f91072ed1b7283b13ca57fcfbece5a3b92726143 upstream.
+
+There's a possible race in perf_mmap_close() when checking ring buffer's
+mmap_count refcount value. The problem is that the mmap_count check is
+not atomic because we call atomic_dec() and atomic_read() separately.
+
+  perf_mmap_close:
+  ...
+   atomic_dec(&rb->mmap_count);
+   ...
+   if (atomic_read(&rb->mmap_count))
+      goto out_put;
+
+   <ring buffer detach>
+   free_uid
+
+out_put:
+  ring_buffer_put(rb); /* could be last */
+
+The race can happen when we have two (or more) events sharing same ring
+buffer and they go through atomic_dec() and then they both see 0 as refcount
+value later in atomic_read(). Then both will go on and execute code which
+is meant to be run just once.
+
+The code that detaches ring buffer is probably fine to be executed more
+than once, but the problem is in calling free_uid(), which will later on
+demonstrate in related crashes and refcount warnings, like:
+
+  refcount_t: addition on 0; use-after-free.
+  ...
+  RIP: 0010:refcount_warn_saturate+0x6d/0xf
+  ...
+  Call Trace:
+  prepare_creds+0x190/0x1e0
+  copy_creds+0x35/0x172
+  copy_process+0x471/0x1a80
+  _do_fork+0x83/0x3a0
+  __do_sys_wait4+0x83/0x90
+  __do_sys_clone+0x85/0xa0
+  do_syscall_64+0x5b/0x1e0
+  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Using atomic decrease and check instead of separated calls.
+
+Tested-by: Michael Petlan <mpetlan@redhat.com>
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Wade Mealing <wmealing@redhat.com>
+Fixes: 9bb5d40cd93c ("perf: Fix mmap() accounting hole");
+Link: https://lore.kernel.org/r/20200916115311.GE2301783@krava
+[sudip: used ring_buffer]
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/events/core.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5596,11 +5596,11 @@ static void perf_pmu_output_stop(struct
+ static void perf_mmap_close(struct vm_area_struct *vma)
+ {
+       struct perf_event *event = vma->vm_file->private_data;
+-
+       struct ring_buffer *rb = ring_buffer_get(event);
+       struct user_struct *mmap_user = rb->mmap_user;
+       int mmap_locked = rb->mmap_locked;
+       unsigned long size = perf_data_size(rb);
++      bool detach_rest = false;
+       if (event->pmu->event_unmapped)
+               event->pmu->event_unmapped(event, vma->vm_mm);
+@@ -5631,7 +5631,8 @@ static void perf_mmap_close(struct vm_ar
+               mutex_unlock(&event->mmap_mutex);
+       }
+-      atomic_dec(&rb->mmap_count);
++      if (atomic_dec_and_test(&rb->mmap_count))
++              detach_rest = true;
+       if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex))
+               goto out_put;
+@@ -5640,7 +5641,7 @@ static void perf_mmap_close(struct vm_ar
+       mutex_unlock(&event->mmap_mutex);
+       /* If there's still other mmap()s of this buffer, we're done. */
+-      if (atomic_read(&rb->mmap_count))
++      if (!detach_rest)
+               goto out_put;
+       /*
diff --git a/queue-5.4/perf-scripting-python-avoid-declaring-function-pointers-with-a-visibility-attribute.patch b/queue-5.4/perf-scripting-python-avoid-declaring-function-pointers-with-a-visibility-attribute.patch
new file mode 100644 (file)
index 0000000..aa6454c
--- /dev/null
@@ -0,0 +1,79 @@
+From d0e7b0c71fbb653de90a7163ef46912a96f0bdaf Mon Sep 17 00:00:00 2001
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Fri, 30 Oct 2020 08:24:38 -0300
+Subject: perf scripting python: Avoid declaring function pointers with a visibility attribute
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+commit d0e7b0c71fbb653de90a7163ef46912a96f0bdaf upstream.
+
+To avoid this:
+
+  util/scripting-engines/trace-event-python.c: In function 'python_start_script':
+  util/scripting-engines/trace-event-python.c:1595:2: error: 'visibility' attribute ignored [-Werror=attributes]
+   1595 |  PyMODINIT_FUNC (*initfunc)(void);
+        |  ^~~~~~~~~~~~~~
+
+That started breaking when building with PYTHON=python3 and these gcc
+versions (I haven't checked with the clang ones, maybe it breaks there
+as well):
+
+  # export PERF_TARBALL=http://192.168.86.5/perf/perf-5.9.0.tar.xz
+  # dm  fedora:33 fedora:rawhide
+     1   107.80 fedora:33         : Ok   gcc (GCC) 10.2.1 20201005 (Red Hat 10.2.1-5), clang version 11.0.0 (Fedora 11.0.0-1.fc33)
+     2    92.47 fedora:rawhide    : Ok   gcc (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6), clang version 11.0.0 (Fedora 11.0.0-1.fc34)
+  #
+
+Avoid that by ditching that 'initfunc' function pointer with its:
+
+    #define Py_EXPORTED_SYMBOL _attribute_ ((visibility ("default")))
+    #define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
+
+And just call PyImport_AppendInittab() at the end of the ifdef python3
+block with the functions that were being attributed to that initfunc.
+
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Tapas Kundu <tkundu@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/scripting-engines/trace-event-python.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/tools/perf/util/scripting-engines/trace-event-python.c
++++ b/tools/perf/util/scripting-engines/trace-event-python.c
+@@ -1587,7 +1587,6 @@ static void _free_command_line(wchar_t *
+ static int python_start_script(const char *script, int argc, const char **argv)
+ {
+       struct tables *tables = &tables_global;
+-      PyMODINIT_FUNC (*initfunc)(void);
+ #if PY_MAJOR_VERSION < 3
+       const char **command_line;
+ #else
+@@ -1602,20 +1601,18 @@ static int python_start_script(const cha
+       FILE *fp;
+ #if PY_MAJOR_VERSION < 3
+-      initfunc = initperf_trace_context;
+       command_line = malloc((argc + 1) * sizeof(const char *));
+       command_line[0] = script;
+       for (i = 1; i < argc + 1; i++)
+               command_line[i] = argv[i - 1];
++      PyImport_AppendInittab(name, initperf_trace_context);
+ #else
+-      initfunc = PyInit_perf_trace_context;
+       command_line = malloc((argc + 1) * sizeof(wchar_t *));
+       command_line[0] = Py_DecodeLocale(script, NULL);
+       for (i = 1; i < argc + 1; i++)
+               command_line[i] = Py_DecodeLocale(argv[i - 1], NULL);
++      PyImport_AppendInittab(name, PyInit_perf_trace_context);
+ #endif
+-
+-      PyImport_AppendInittab(name, initfunc);
+       Py_Initialize();
+ #if PY_MAJOR_VERSION < 3
index 9b0243696df4223d06a20fdc0f1a46740ac1fa0c..56610a7f9fb8d77ba18900923b06c7da7046da97 100644 (file)
@@ -145,3 +145,5 @@ r8169-fix-potential-skb-double-free-in-an-error-path.patch
 drm-i915-correctly-set-sfc-capability-for-video-engines.patch
 powerpc-603-always-fault-when-_page_accessed-is-not-set.patch
 x86-speculation-allow-ibpb-to-be-conditionally-enabled-on-cpus-with-always-on-stibp.patch
+perf-scripting-python-avoid-declaring-function-pointers-with-a-visibility-attribute.patch
+perf-core-fix-race-in-the-perf_mmap_close-function.patch