Markers : fix check format with rcu callback race
PATCH 1/1 Markers : fix check format with rcu callback race
The fix "markers: fix unchecked format" introduced an RCU callback race. This patch takes care of calling any pending RCU callback before set_format is called.
Quoted 7 lines · * Lai Jiangshan ([email protected]) wrote:
bit-field is not thread-safe nor smp-safe.
struct marker_entry.rcu_pending is not protected by any lock in rcu-callback
free_old_closure().
so we must turn it into a safe type.
All struct marker_entry.rcu_pending accesses are done with the markers_mutex held, except the one done in free_old_closure(). Normally, there should be a
if (entry->rcu_pending)
rcu_barrier_sched();At the beginning of each markers_mutex section (just after get_marker()) to make sure any pending callback is executed at that point before any of rcu_pending or ptype are touched.
--- kernel/marker.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
kernel/marker.c +13 -11
@@ -657,21 +657,23 @@ int marker_probe_register(const char *na entry =add_marker (name, format);if (IS_ERR (entry)) ret =PTR_ERR (entry); - }else if (format) { -if (!entry->format) - ret =marker_set_format (&entry, format); -else if (strcmp (entry->format, format)) - ret = -EPERM ; + }else { +/* +* If we detect that a call_rcu is pending for this marker, +* make sure it's executed now. +*/ +if (entry->rcu_pending) +rcu_barrier_sched (); +if (format) { +if (!entry->format) + ret =marker_set_format (&entry, format); +else if (strcmp (entry->format, format)) + ret = -EPERM ; + } }if (ret) goto end; -/* -* If we detect that a call_rcu is pending for this marker, -* make sure it's executed now. -*/ -if (entry->rcu_pending) -rcu_barrier_sched (); old =marker_entry_add_probe (entry, probe, probe_private);if (IS_ERR (old)) { ret =PTR_ERR (old);
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Quoted 4 lines · Mathieu Desnoyers
The fix "markers: fix unchecked format" introduced an RCU callback race. This patch takes care of calling any pending RCU callback before
set_formatis called.
marker_set_format() has this statement:
if ((*entry)->rcu_pending) rcu_barrier_sched();
Quoted 65 lines · * Lai Jiangshan ([email protected]) wrote:
Quoted 6 lines
bit-field is not thread-safe nor smp-safe.
struct marker_entry.rcu_pending is not protected by any lock in rcu-callback
free_old_closure().
so we must turn it into a safe type.All struct marker_entry.rcu_pending accesses are done with the
markers_mutexheld, except the one done infree_old_closure(). Normally, there should be aif (entry->rcu_pending) rcu_barrier_sched();At the beginning of each
markers_mutexsection (just afterget_marker()) to make sure any pending callback is executed at that point before any ofrcu_pendingor ptype are touched.Signed-off-by Mathieu Desnoyers <[email protected]>CC Ingo Molnar <[email protected]>CC Lai Jiangshan <[email protected]>--- kernel/marker.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)Index:
linux-2.6-lttng/kernel/marker.c
===================================================================kernel/marker.c +13
-11@@ -657,21 +657,23 @@ int marker_probe_register(const char *na entry =add_marker (name, format);if (IS_ERR (entry)) ret =PTR_ERR (entry); - }else if (format) { -if (!entry->format) - ret =marker_set_format (&entry, format); -else if (strcmp (entry->format, format)) - ret = -EPERM ; + }else { +/* +* If we detect that a call_rcu is pending for this marker, +* make sure it's executed now. +*/ +if (entry->rcu_pending) +rcu_barrier_sched (); +if (format) { +if (!entry->format) + ret =marker_set_format (&entry, format); +else if (strcmp (entry->format, format)) + ret = -EPERM ; + } }if (ret) goto end; -/* -* If we detect that a call_rcu is pending for this marker, -* make sure it's executed now. -*/ -if (entry->rcu_pending) -rcu_barrier_sched (); old =marker_entry_add_probe (entry, probe, probe_private);if (IS_ERR (old)) { ret =PTR_ERR (old);
Quoted 11 lines · * Lai Jiangshan ([email protected]) wrote:
Quoted 4 lines · Mathieu Desnoyers
The fix "markers: fix unchecked format" introduced an RCU callback race. This patch takes care of calling any pending RCU callback before
set_formatis called.
marker_set_format()has this statement:if ((*entry)->rcu_pending) rcu_barrier_sched();
True, therefore my fix is not needed.
Mathieu
Quoted 67 lines
Quoted 65 lines · * Lai Jiangshan ([email protected]) wrote:
Quoted 6 lines
bit-field is not thread-safe nor smp-safe.
struct marker_entry.rcu_pending is not protected by any lock in rcu-callback
free_old_closure().
so we must turn it into a safe type.All struct marker_entry.rcu_pending accesses are done with the
markers_mutexheld, except the one done infree_old_closure(). Normally, there should be aif (entry->rcu_pending) rcu_barrier_sched();At the beginning of each
markers_mutexsection (just afterget_marker()) to make sure any pending callback is executed at that point before any ofrcu_pendingor ptype are touched.Signed-off-by Mathieu Desnoyers <[email protected]>CC Ingo Molnar <[email protected]>CC Lai Jiangshan <[email protected]>--- kernel/marker.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)Index:
linux-2.6-lttng/kernel/marker.c
===================================================================kernel/marker.c +13
-11@@ -657,21 +657,23 @@ int marker_probe_register(const char *na entry =add_marker (name, format);if (IS_ERR (entry)) ret =PTR_ERR (entry); - }else if (format) { -if (!entry->format) - ret =marker_set_format (&entry, format); -else if (strcmp (entry->format, format)) - ret = -EPERM ; + }else { +/* +* If we detect that a call_rcu is pending for this marker, +* make sure it's executed now. +*/ +if (entry->rcu_pending) +rcu_barrier_sched (); +if (format) { +if (!entry->format) + ret =marker_set_format (&entry, format); +else if (strcmp (entry->format, format)) + ret = -EPERM ; + } }if (ret) goto end; -/* -* If we detect that a call_rcu is pending for this marker, -* make sure it's executed now. -*/ -if (entry->rcu_pending) -rcu_barrier_sched (); old =marker_entry_add_probe (entry, probe, probe_private);if (IS_ERR (old)) { ret =PTR_ERR (old);
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68