Fix: allow racy tracepoint string input from kernel and userspace
[deliverable/lttng-modules.git] / probes / lttng.c
CommitLineData
0c956676
MD
1/*
2 * lttng.c
3 *
4 * LTTng logger ABI
5 *
6 * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/tracepoint.h>
25#include <linux/uaccess.h>
26#include <linux/gfp.h>
27#include <linux/fs.h>
28#include <linux/proc_fs.h>
29#include <linux/slab.h>
30#include <linux/mm.h>
31#include "../wrapper/vmalloc.h"
32#include "../lttng-events.h"
33
34#define TP_MODULE_NOAUTOLOAD
35#define LTTNG_PACKAGE_BUILD
36#define CREATE_TRACE_POINTS
37#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
38#define TRACE_INCLUDE_FILE lttng
39
40#include "../instrumentation/events/lttng-module/lttng.h"
41
42/* Events written through logger are truncated at 1024 bytes */
43#define LTTNG_LOGGER_COUNT_MAX 1024
44#define LTTNG_LOGGER_FILE "lttng-logger"
45
20591cf7
MD
46DEFINE_TRACE(lttng_logger);
47
0c956676
MD
48static struct proc_dir_entry *lttng_logger_dentry;
49
50/**
51 * lttng_logger_write - write a userspace string into the trace system
52 * @file: file pointer
53 * @user_buf: user string
54 * @count: length to copy
55 * @ppos: file position
56 *
57 * Copy a userspace string into a trace event named "lttng:logger".
58 * Copies at most @count bytes into the event "msg" dynamic array.
59 * Truncates the count at LTTNG_LOGGER_COUNT_MAX. Returns the number of
60 * bytes copied from the source.
61 * Return -1 on error, with EFAULT errno.
62 */
63static
64ssize_t lttng_logger_write(struct file *file, const char __user *user_buf,
65 size_t count, loff_t *ppos)
66{
67 unsigned int nr_pages = 1, i;
68 unsigned long uaddr = (unsigned long) user_buf;
69 struct page *pages[2];
70 ssize_t written;
71 int ret;
72
73 /* Truncate count */
74 if (unlikely(count > LTTNG_LOGGER_COUNT_MAX))
75 count = LTTNG_LOGGER_COUNT_MAX;
76
77 /* How many pages are we dealing with ? */
78 if (unlikely((uaddr & PAGE_MASK) != ((uaddr + count) & PAGE_MASK)))
79 nr_pages = 2;
80
81 /* Pin userspace pages */
82 ret = get_user_pages_fast(uaddr, nr_pages, 0, pages);
83 if (unlikely(ret < nr_pages)) {
84 if (ret > 0) {
85 BUG_ON(ret != 1);
86 put_page(pages[0]);
87 }
88 written = -EFAULT;
89 goto end;
90 }
91
92 /* Trace the event */
93 trace_lttng_logger(user_buf, count);
94 written = count;
95 *ppos += written;
96
97 for (i = 0; i < nr_pages; i++)
98 put_page(pages[i]);
99end:
100 return written;
101}
102
103static const struct file_operations lttng_logger_operations = {
104 .write = lttng_logger_write,
105};
106
107int __init lttng_logger_init(void)
108{
109 int ret = 0;
110
111 wrapper_vmalloc_sync_all();
112 lttng_logger_dentry = proc_create_data(LTTNG_LOGGER_FILE,
113 S_IRUGO | S_IWUGO, NULL,
114 &lttng_logger_operations, NULL);
115 if (!lttng_logger_dentry) {
116 printk(KERN_ERR "Error creating LTTng logger file\n");
117 ret = -ENOMEM;
118 goto error;
119 }
120 ret = __lttng_events_init__lttng();
121 if (ret)
122 goto error_events;
123 return ret;
124
125error_events:
126 remove_proc_entry("lttng-logger", NULL);
127error:
128 return ret;
129}
130
131void __exit lttng_logger_exit(void)
132{
133 __lttng_events_exit__lttng();
134 if (lttng_logger_dentry)
135 remove_proc_entry("lttng-logger", NULL);
136}
This page took 0.02957 seconds and 5 git commands to generate.