--- /dev/null
+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;
+
+ /*
--- /dev/null
+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