stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Alexander Lam <azl@google.com>,
	Steven Rostedt <rostedt@goodmis.org>
Subject: [ 100/103] tracing: Add trace_array_get/put() to handle instance refs better
Date: Tue, 23 Jul 2013 15:26:51 -0700	[thread overview]
Message-ID: <20130723220433.321782562@linuxfoundation.org> (raw)
In-Reply-To: <20130723220418.532514378@linuxfoundation.org>

3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

commit ff451961a8b2a17667a7bfa39c86fb9b351445db upstream.

Commit a695cb58162 "tracing: Prevent deleting instances when they are being read"
tried to fix a race between deleting a trace instance and reading contents
of a trace file. But it wasn't good enough. The following could crash the kernel:

 # cd /sys/kernel/debug/tracing/instances
 # ( while :; do mkdir foo; rmdir foo; done ) &
 # ( while :; do cat foo/trace &> /dev/null; done ) &

Luckily this can only be done by root user, but it should be fixed regardless.

The problem is that a delete of the file can happen after the reader starts
to open the file but before it grabs the trace_types_mutex.

The solution is to validate the trace array before using it. If the trace
array does not exist in the list of trace arrays, then it returns -ENODEV.

There's a possibility that a trace_array could be deleted and a new one
created and the open would open its file instead. But that is very minor as
it will just return the data of the new trace array, it may confuse the user
but it will not crash the system. As this can only be done by root anyway,
the race will only occur if root is deleting what its trying to read at
the same time.

Reported-by: Alexander Lam <azl@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 kernel/trace/trace.c |   83 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 65 insertions(+), 18 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -193,6 +193,37 @@ static struct trace_array	global_trace;
 
 LIST_HEAD(ftrace_trace_arrays);
 
+int trace_array_get(struct trace_array *this_tr)
+{
+	struct trace_array *tr;
+	int ret = -ENODEV;
+
+	mutex_lock(&trace_types_lock);
+	list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+		if (tr == this_tr) {
+			tr->ref++;
+			ret = 0;
+			break;
+		}
+	}
+	mutex_unlock(&trace_types_lock);
+
+	return ret;
+}
+
+static void __trace_array_put(struct trace_array *this_tr)
+{
+	WARN_ON(!this_tr->ref);
+	this_tr->ref--;
+}
+
+void trace_array_put(struct trace_array *this_tr)
+{
+	mutex_lock(&trace_types_lock);
+	__trace_array_put(this_tr);
+	mutex_unlock(&trace_types_lock);
+}
+
 int filter_current_check_discard(struct ring_buffer *buffer,
 				 struct ftrace_event_call *call, void *rec,
 				 struct ring_buffer_event *event)
@@ -2768,10 +2799,9 @@ static const struct seq_operations trace
 };
 
 static struct trace_iterator *
-__tracing_open(struct inode *inode, struct file *file, bool snapshot)
+__tracing_open(struct trace_array *tr, struct trace_cpu *tc,
+	       struct inode *inode, struct file *file, bool snapshot)
 {
-	struct trace_cpu *tc = inode->i_private;
-	struct trace_array *tr = tc->tr;
 	struct trace_iterator *iter;
 	int cpu;
 
@@ -2850,8 +2880,6 @@ __tracing_open(struct inode *inode, stru
 		tracing_iter_reset(iter, cpu);
 	}
 
-	tr->ref++;
-
 	mutex_unlock(&trace_types_lock);
 
 	return iter;
@@ -2881,17 +2909,20 @@ static int tracing_release(struct inode
 	struct trace_array *tr;
 	int cpu;
 
-	if (!(file->f_mode & FMODE_READ))
+	/* Writes do not use seq_file, need to grab tr from inode */
+	if (!(file->f_mode & FMODE_READ)) {
+		struct trace_cpu *tc = inode->i_private;
+
+		trace_array_put(tc->tr);
 		return 0;
+	}
 
 	iter = m->private;
 	tr = iter->tr;
+	trace_array_put(tr);
 
 	mutex_lock(&trace_types_lock);
 
-	WARN_ON(!tr->ref);
-	tr->ref--;
-
 	for_each_tracing_cpu(cpu) {
 		if (iter->buffer_iter[cpu])
 			ring_buffer_read_finish(iter->buffer_iter[cpu]);
@@ -2910,20 +2941,23 @@ static int tracing_release(struct inode
 	kfree(iter->trace);
 	kfree(iter->buffer_iter);
 	seq_release_private(inode, file);
+
 	return 0;
 }
 
 static int tracing_open(struct inode *inode, struct file *file)
 {
+	struct trace_cpu *tc = inode->i_private;
+	struct trace_array *tr = tc->tr;
 	struct trace_iterator *iter;
 	int ret = 0;
 
+	if (trace_array_get(tr) < 0)
+		return -ENODEV;
+
 	/* If this file was open for write, then erase contents */
 	if ((file->f_mode & FMODE_WRITE) &&
 	    (file->f_flags & O_TRUNC)) {
-		struct trace_cpu *tc = inode->i_private;
-		struct trace_array *tr = tc->tr;
-
 		if (tc->cpu == RING_BUFFER_ALL_CPUS)
 			tracing_reset_online_cpus(&tr->trace_buffer);
 		else
@@ -2931,12 +2965,16 @@ static int tracing_open(struct inode *in
 	}
 
 	if (file->f_mode & FMODE_READ) {
-		iter = __tracing_open(inode, file, false);
+		iter = __tracing_open(tr, tc, inode, file, false);
 		if (IS_ERR(iter))
 			ret = PTR_ERR(iter);
 		else if (trace_flags & TRACE_ITER_LATENCY_FMT)
 			iter->iter_flags |= TRACE_FILE_LAT_FMT;
 	}
+
+	if (ret < 0)
+		trace_array_put(tr);
+
 	return ret;
 }
 
@@ -4512,12 +4550,16 @@ struct ftrace_buffer_info {
 static int tracing_snapshot_open(struct inode *inode, struct file *file)
 {
 	struct trace_cpu *tc = inode->i_private;
+	struct trace_array *tr = tc->tr;
 	struct trace_iterator *iter;
 	struct seq_file *m;
 	int ret = 0;
 
+	if (trace_array_get(tr) < 0)
+		return -ENODEV;
+
 	if (file->f_mode & FMODE_READ) {
-		iter = __tracing_open(inode, file, true);
+		iter = __tracing_open(tr, tc, inode, file, true);
 		if (IS_ERR(iter))
 			ret = PTR_ERR(iter);
 	} else {
@@ -4530,13 +4572,16 @@ static int tracing_snapshot_open(struct
 			kfree(m);
 			return -ENOMEM;
 		}
-		iter->tr = tc->tr;
+		iter->tr = tr;
 		iter->trace_buffer = &tc->tr->max_buffer;
 		iter->cpu_file = tc->cpu;
 		m->private = iter;
 		file->private_data = m;
 	}
 
+	if (ret < 0)
+		trace_array_put(tr);
+
 	return ret;
 }
 
@@ -4617,9 +4662,12 @@ out:
 static int tracing_snapshot_release(struct inode *inode, struct file *file)
 {
 	struct seq_file *m = file->private_data;
+	int ret;
+
+	ret = tracing_release(inode, file);
 
 	if (file->f_mode & FMODE_READ)
-		return tracing_release(inode, file);
+		return ret;
 
 	/* If write only, the seq_file is just a stub */
 	if (m)
@@ -4864,8 +4912,7 @@ static int tracing_buffers_release(struc
 
 	mutex_lock(&trace_types_lock);
 
-	WARN_ON(!iter->tr->ref);
-	iter->tr->ref--;
+	__trace_array_put(iter->tr);
 
 	if (info->spare)
 		ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare);



  parent reply	other threads:[~2013-07-23 22:26 UTC|newest]

Thread overview: 119+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-23 22:25 [ 000/103] 3.10.3-stable review Greg Kroah-Hartman
2013-07-23 22:25 ` [ 001/103] powerpc/hw_brk: Fix setting of length for exact mode breakpoints Greg Kroah-Hartman
2013-07-23 22:25 ` [ 002/103] powerpc/hw_brk: Fix clearing of extraneous IRQ Greg Kroah-Hartman
2013-07-23 22:25 ` [ 003/103] powerpc/hw_brk: Fix off by one error when validating DAWR region end Greg Kroah-Hartman
2013-07-23 22:25 ` [ 004/103] powerpc/powernv: Fix iommu initialization again Greg Kroah-Hartman
2013-07-23 22:25 ` [ 005/103] powerpc/tm: Fix writing top half of MSR on 32 bit signals Greg Kroah-Hartman
2013-07-23 22:25 ` [ 006/103] powerpc/tm: Fix 32 bit non-rt signals Greg Kroah-Hartman
2013-07-23 22:25 ` [ 007/103] powerpc/tm: Fix restoration of MSR on 32bit signal return Greg Kroah-Hartman
2013-07-23 22:25 ` [ 008/103] powerpc/tm: Fix return of 32bit rt signals to active transactions Greg Kroah-Hartman
2013-07-23 22:25 ` [ 009/103] powerpc/tm: Fix return of active 64bit signals Greg Kroah-Hartman
2013-07-23 22:25 ` [ 010/103] powerpc: Remove unreachable relocation on exception handlers Greg Kroah-Hartman
2013-07-23 22:25 ` [ 011/103] powerpc: Remove KVMTEST from RELON " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 012/103] powerpc: Rename and flesh out the facility unavailable exception handler Greg Kroah-Hartman
2013-07-23 22:25 ` [ 013/103] powerpc: Wire up the HV facility unavailable exception Greg Kroah-Hartman
2013-07-23 22:25 ` [ 014/103] powerpc/smp: Section mismatch from smp_release_cpus to __initdata spinning_secondaries Greg Kroah-Hartman
2013-07-23 22:25 ` [ 015/103] powerpc/numa: Do not update sysfs cpu registration from invalid context Greg Kroah-Hartman
2013-07-23 22:25 ` [ 016/103] powerpc/perf: Check that events only include valid bits on Power8 Greg Kroah-Hartman
2013-07-23 22:25 ` [ 017/103] powerpc/perf: Rework disable logic in pmu_disable() Greg Kroah-Hartman
2013-07-23 22:25 ` [ 018/103] powerpc/perf: Freeze PMC5/6 if were not using them Greg Kroah-Hartman
2013-07-23 22:25 ` [ 019/103] powerpc/perf: Use existing out label in power_pmu_enable() Greg Kroah-Hartman
2013-07-23 22:25 ` [ 020/103] powerpc/perf: Dont enable if we have zero events Greg Kroah-Hartman
2013-07-23 22:25 ` [ 021/103] cpufreq: Revert commit a66b2e to fix suspend/resume regression Greg Kroah-Hartman
2013-07-23 22:25 ` [ 022/103] cpufreq: Revert commit 2f7021a8 to fix CPU hotplug regression Greg Kroah-Hartman
2013-07-23 22:25 ` [ 023/103] arm64: mm: dont treat user cache maintenance faults as writes Greg Kroah-Hartman
2013-07-23 22:25 ` [ 024/103] iio: Fix iio_channel_has_info Greg Kroah-Hartman
2013-07-23 22:25 ` [ 025/103] iio: inkern: fix iio_convert_raw_to_processed_unlocked Greg Kroah-Hartman
2013-07-23 22:25 ` [ 026/103] ALSA: hda - Fix EAPD vmaster hook for AD1884 & co Greg Kroah-Hartman
2013-07-23 22:25 ` [ 027/103] ALSA: hda - Fix return value of snd_hda_check_power_state() Greg Kroah-Hartman
2013-07-23 22:25 ` [ 028/103] ALSA: hda - Cache the MUX selection for generic HDMI Greg Kroah-Hartman
2013-07-23 22:25 ` [ 029/103] ALSA: hda - Fix missing Mic Boost controls for VIA codecs Greg Kroah-Hartman
2013-07-23 22:25 ` [ 030/103] ALSA: hda - Fix the max length of control name in generic parser Greg Kroah-Hartman
2013-07-23 22:25 ` [ 031/103] ALSA: hda - Add new GPU codec ID to snd-hda Greg Kroah-Hartman
2013-07-23 22:25 ` [ 032/103] ALSA: seq-oss: Initialize MIDI clients asynchronously Greg Kroah-Hartman
2013-07-23 22:25 ` [ 033/103] ALSA: 6fire: Fix unlocked snd_pcm_stop() call Greg Kroah-Hartman
2013-07-23 22:25 ` [ 034/103] ALSA: ua101: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 035/103] ALSA: pxa2xx: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 036/103] ALSA: atiixp: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 037/103] ALSA: asihpi: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 038/103] ALSA: usx2y: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 039/103] hwmon: (nct6775) Fix temperature alarm attributes Greg Kroah-Hartman
2013-07-23 22:25 ` [ 040/103] hwmon: (nct6775) Drop unsupported fan alarm attributes for NCT6775 Greg Kroah-Hartman
2013-07-23 22:25 ` [ 041/103] libata-zpodd: must use ata_tf_init() Greg Kroah-Hartman
2013-07-23 22:25 ` [ 042/103] libata: skip SRST for all SIMG [34]7x port-multipliers Greg Kroah-Hartman
2013-07-23 22:25 ` [ 043/103] ata_piix: IDE-mode SATA patch for Intel Coleto Creek DeviceIDs Greg Kroah-Hartman
2013-07-23 22:25 ` [ 044/103] sata_highbank: increase retry count but shorten duration for Calxeda controller Greg Kroah-Hartman
2013-07-23 22:25 ` [ 045/103] i2c-piix4: Add AMD CZ SMBus device ID Greg Kroah-Hartman
2013-07-23 22:25 ` [ 046/103] ASoC: s6000: Fix unlocked snd_pcm_stop() call Greg Kroah-Hartman
2013-07-23 22:25 ` [ 047/103] ASoC: atmel: " Greg Kroah-Hartman
2013-07-23 22:25 ` [ 048/103] ASoC: sglt5000: Fix SGTL5000_PLL_FRAC_DIV_MASK Greg Kroah-Hartman
2013-07-23 22:26 ` [ 049/103] md/raid10: fix bug which causes all RAID10 reshapes to move no data Greg Kroah-Hartman
2013-07-23 22:26 ` [ 050/103] md/raid10: fix two bugs affecting RAID10 reshape Greg Kroah-Hartman
2013-07-23 22:26 ` [ 051/103] md/raid10: fix two problems with RAID10 resync Greg Kroah-Hartman
2013-07-23 22:26 ` [ 052/103] tick: Sanitize broadcast control logic Greg Kroah-Hartman
2013-07-23 22:26 ` [ 053/103] tick: Prevent uncontrolled switch to oneshot mode Greg Kroah-Hartman
2013-07-23 22:26 ` [ 054/103] clocksource: dw_apb: Fix error check Greg Kroah-Hartman
2013-07-23 22:26 ` [ 055/103] rt2x00: read 5GHz TX power values from the correct offset Greg Kroah-Hartman
2013-07-23 22:26 ` [ 056/103] rt2x00: rt2800lib: fix default TX power check for RT55xx Greg Kroah-Hartman
2013-07-23 22:26 ` [ 057/103] ath9k_hw: Assign default xlna config for AR9485 Greg Kroah-Hartman
2013-07-23 22:26 ` [ 058/103] ath9k: Fix noisefloor calibration Greg Kroah-Hartman
2013-07-23 22:26 ` [ 059/103] ath9k: Do not assign noise for NULL caldata Greg Kroah-Hartman
2013-07-23 22:26 ` [ 060/103] SCSI: sd: Update WRITE SAME heuristics Greg Kroah-Hartman
2013-07-23 22:26 ` [ 061/103] SCSI: aacraid: Fix for arrays are going offline in the system. System hangs Greg Kroah-Hartman
2013-07-23 22:26 ` [ 062/103] SCSI: zfcp: fix adapter (re)open recovery while link to SAN is down Greg Kroah-Hartman
2013-07-23 22:26 ` [ 063/103] SCSI: zfcp: block queue limits with data router Greg Kroah-Hartman
2013-07-23 22:26 ` [ 064/103] SCSI: zfcp: status read buffers on first adapter open with link down Greg Kroah-Hartman
2013-07-23 22:26 ` [ 065/103] SCSI: mpt2sas: fix firmware failure with wrong task attribute Greg Kroah-Hartman
2013-07-23 22:26 ` [ 066/103] SCSI: mpt2sas: Fix for issue Missing delay not getting set during system bootup Greg Kroah-Hartman
2013-07-23 22:26 ` [ 067/103] SUNRPC: fix races on PipeFS MOUNT notifications Greg Kroah-Hartman
2013-07-23 22:26 ` [ 068/103] SUNRPC: fix races on PipeFS UMOUNT notifications Greg Kroah-Hartman
2013-07-23 22:30   ` Myklebust, Trond
2013-07-23 22:50     ` Greg Kroah-Hartman
2013-07-23 22:26 ` [ 069/103] virtio_balloon: leak_balloon(): only tell host if we got pages deflated Greg Kroah-Hartman
2013-07-23 22:26 ` [ 070/103] b43: ensue that BCMA is "y" when B43 is "y" Greg Kroah-Hartman
2013-07-23 22:26 ` [ 071/103] mac80211: close AP_VLAN interfaces before unregistering all Greg Kroah-Hartman
2013-07-23 22:26 ` [ 072/103] printk: Fix rq->lock vs logbuf_lock unlock lock inversion Greg Kroah-Hartman
2013-07-23 22:26 ` [ 073/103] uprobes: Fix return value in error handling path Greg Kroah-Hartman
2013-07-23 22:26 ` [ 074/103] svcrpc: fix failures to handle -1 uids Greg Kroah-Hartman
2013-07-23 22:26 ` [ 075/103] svcrpc: fix handling of too-short rpcs Greg Kroah-Hartman
2013-07-23 22:26 ` [ 076/103] svcrpc: dont error out on small tcp fragment Greg Kroah-Hartman
2013-07-23 22:26 ` [ 077/103] of: Fix address decoding on Bimini and js2x machines Greg Kroah-Hartman
2013-07-23 22:26 ` [ 078/103] drm/i915: Fix up sdvo hpd pins for i965g/gm Greg Kroah-Hartman
2013-07-23 22:26 ` [ 079/103] drm/i915: Fix context sizes on HSW Greg Kroah-Hartman
2013-07-23 22:26 ` [ 080/103] drm/i915: Only clear write-domains after a successful wait-seqno Greg Kroah-Hartman
2013-07-23 22:26 ` [ 081/103] drm/gem: fix not to assign error value to gem name Greg Kroah-Hartman
2013-07-23 22:26 ` [ 082/103] drm/mgag200: Added resolution and bandwidth limits for various G200e products Greg Kroah-Hartman
2013-07-23 22:26 ` [ 083/103] drm/nouveau: use vmalloc for pgt allocation Greg Kroah-Hartman
2013-07-23 22:26 ` [ 084/103] drm/radeon: fix AVI infoframe generation Greg Kroah-Hartman
2013-07-23 22:26 ` [ 085/103] drm/radeon: add backlight quirk for hybrid mac Greg Kroah-Hartman
2013-07-23 22:26 ` [ 086/103] drm/nva3/disp: Fix HDMI audio regression Greg Kroah-Hartman
2013-07-23 22:26 ` [ 087/103] drm/nv50-/disp: Use output specific mask in interrupt Greg Kroah-Hartman
2013-07-23 22:26 ` [ 088/103] iommu/amd: Only unmap large pages from the first pte Greg Kroah-Hartman
2013-07-23 22:26 ` [ 089/103] xtensa: adjust boot parameters address when INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is selected Greg Kroah-Hartman
2013-07-23 22:26 ` [ 090/103] thermal: cpu_cooling: fix stub function Greg Kroah-Hartman
2013-07-23 22:26 ` [ 091/103] MIPS: Octeon: Dont clobber bootloader data structures Greg Kroah-Hartman
2013-07-23 22:26 ` [ 092/103] staging: line6: Fix unlocked snd_pcm_stop() call Greg Kroah-Hartman
2013-07-23 22:26 ` [ 093/103] perf: Clone child context from parent context pmu Greg Kroah-Hartman
2013-07-23 22:26 ` [ 094/103] perf: Remove WARN_ON_ONCE() check in __perf_event_enable() for valid scenario Greg Kroah-Hartman
2013-07-23 22:26 ` [ 095/103] perf: Fix perf_lock_task_context() vs RCU Greg Kroah-Hartman
2013-07-23 22:26 ` [ 096/103] tracing: Failed to create system directory Greg Kroah-Hartman
2013-07-23 22:26 ` [ 097/103] tracing: Fix irqs-off tag display in syscall tracing Greg Kroah-Hartman
2013-07-23 22:26 ` [ 098/103] tracing: Make trace_marker use the correct per-instance buffer Greg Kroah-Hartman
2013-07-23 22:26 ` [ 099/103] tracing: Protect ftrace_trace_arrays list in trace_events.c Greg Kroah-Hartman
2013-07-23 22:26 ` Greg Kroah-Hartman [this message]
2013-07-23 22:26 ` [ 101/103] tracing: Get trace_array ref counts when accessing trace files Greg Kroah-Hartman
2013-07-23 22:26 ` [ 102/103] tracing: Fix race between deleting buffer and setting events Greg Kroah-Hartman
2013-07-23 22:26 ` [ 103/103] tracing: Add trace_array_get/put() to event handling Greg Kroah-Hartman
     [not found] ` <CAKocOOPO61YUj5kTL7k1HuEeDdB_x=sxWga007nBSiLD4Px5Mg@mail.gmail.com>
2013-07-24 13:40   ` [ 000/103] 3.10.3-stable review Shuah Khan
2013-07-24 14:55     ` gregkh@linuxfoundation.org >> "Kroah-Hartman, Greg"
2013-07-24 17:04       ` Linus Torvalds
2013-07-24 17:15         ` Willy Tarreau
2013-07-24 17:16         ` Steven Rostedt
2013-07-24 17:24           ` Linus Torvalds
2013-07-24 17:46             ` Steven Rostedt
2013-07-24 17:52               ` gregkh@linuxfoundation.org >> Kroah-Hartman, Greg
2013-07-24 18:05                 ` Steven Rostedt
2013-07-25  9:52               ` Geert Uytterhoeven
2013-07-25 12:47                 ` Steven Rostedt
2013-07-25  3:10 ` linux
2013-07-25  4:20   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130723220433.321782562@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=azl@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).