1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
4 *
5 * Runtime reactor interface.
6 *
7 * A runtime monitor can cause a reaction to the detection of an
8 * exception on the model's execution. By default, the monitors have
9 * tracing reactions, printing the monitor output via tracepoints.
10 * But other reactions can be added (on-demand) via this interface.
11 *
12 * == Registering reactors ==
13 *
14 * The struct rv_reactor defines a callback function to be executed
15 * in case of a model exception happens. The callback function
16 * receives a message to be (optionally) printed before executing
17 * the reaction.
18 *
19 * A RV reactor is registered via:
20 * int rv_register_reactor(struct rv_reactor *reactor)
21 * And unregistered via:
22 * int rv_unregister_reactor(struct rv_reactor *reactor)
23 *
24 * These functions are exported to modules, enabling reactors to be
25 * dynamically loaded.
26 *
27 * == User interface ==
28 *
29 * The user interface resembles the kernel tracing interface and
30 * presents these files:
31 *
32 * "available_reactors"
33 * - List the available reactors, one per line.
34 *
35 * For example:
36 * # cat available_reactors
37 * nop
38 * panic
39 * printk
40 *
41 * "reacting_on"
42 * - It is an on/off general switch for reactors, disabling
43 * all reactions.
44 *
45 * "monitors/MONITOR/reactors"
46 * - List available reactors, with the select reaction for the given
47 * MONITOR inside []. The default one is the nop (no operation)
48 * reactor.
49 * - Writing the name of an reactor enables it to the given
50 * MONITOR.
51 *
52 * For example:
53 * # cat monitors/wip/reactors
54 * [nop]
55 * panic
56 * printk
57 * # echo panic > monitors/wip/reactors
58 * # cat monitors/wip/reactors
59 * nop
60 * [panic]
61 * printk
62 */
63
64 #include <linux/slab.h>
65
66 #include "rv.h"
67
68 /*
69 * Interface for the reactor register.
70 */
71 static LIST_HEAD(rv_reactors_list);
72
get_reactor_rdef_by_name(char * name)73 static struct rv_reactor_def *get_reactor_rdef_by_name(char *name)
74 {
75 struct rv_reactor_def *r;
76
77 list_for_each_entry(r, &rv_reactors_list, list) {
78 if (strcmp(name, r->reactor->name) == 0)
79 return r;
80 }
81 return NULL;
82 }
83
84 /*
85 * Available reactors seq functions.
86 */
reactors_show(struct seq_file * m,void * p)87 static int reactors_show(struct seq_file *m, void *p)
88 {
89 struct rv_reactor_def *rea_def = p;
90
91 seq_printf(m, "%s\n", rea_def->reactor->name);
92 return 0;
93 }
94
reactors_stop(struct seq_file * m,void * p)95 static void reactors_stop(struct seq_file *m, void *p)
96 {
97 mutex_unlock(&rv_interface_lock);
98 }
99
reactors_start(struct seq_file * m,loff_t * pos)100 static void *reactors_start(struct seq_file *m, loff_t *pos)
101 {
102 mutex_lock(&rv_interface_lock);
103 return seq_list_start(&rv_reactors_list, *pos);
104 }
105
reactors_next(struct seq_file * m,void * p,loff_t * pos)106 static void *reactors_next(struct seq_file *m, void *p, loff_t *pos)
107 {
108 return seq_list_next(p, &rv_reactors_list, pos);
109 }
110
111 /*
112 * available_reactors seq definition.
113 */
114 static const struct seq_operations available_reactors_seq_ops = {
115 .start = reactors_start,
116 .next = reactors_next,
117 .stop = reactors_stop,
118 .show = reactors_show
119 };
120
121 /*
122 * available_reactors interface.
123 */
available_reactors_open(struct inode * inode,struct file * file)124 static int available_reactors_open(struct inode *inode, struct file *file)
125 {
126 return seq_open(file, &available_reactors_seq_ops);
127 };
128
129 static const struct file_operations available_reactors_ops = {
130 .open = available_reactors_open,
131 .read = seq_read,
132 .llseek = seq_lseek,
133 .release = seq_release
134 };
135
136 /*
137 * Monitor's reactor file.
138 */
monitor_reactor_show(struct seq_file * m,void * p)139 static int monitor_reactor_show(struct seq_file *m, void *p)
140 {
141 struct rv_monitor_def *mdef = m->private;
142 struct rv_reactor_def *rdef = p;
143
144 if (mdef->rdef == rdef)
145 seq_printf(m, "[%s]\n", rdef->reactor->name);
146 else
147 seq_printf(m, "%s\n", rdef->reactor->name);
148 return 0;
149 }
150
151 /*
152 * available_reactors seq definition.
153 */
154 static const struct seq_operations monitor_reactors_seq_ops = {
155 .start = reactors_start,
156 .next = reactors_next,
157 .stop = reactors_stop,
158 .show = monitor_reactor_show
159 };
160
monitor_swap_reactors_single(struct rv_monitor_def * mdef,struct rv_reactor_def * rdef,bool reacting,bool nested)161 static void monitor_swap_reactors_single(struct rv_monitor_def *mdef,
162 struct rv_reactor_def *rdef,
163 bool reacting, bool nested)
164 {
165 bool monitor_enabled;
166
167 /* nothing to do */
168 if (mdef->rdef == rdef)
169 return;
170
171 monitor_enabled = mdef->monitor->enabled;
172 if (monitor_enabled)
173 rv_disable_monitor(mdef);
174
175 /* swap reactor's usage */
176 mdef->rdef->counter--;
177 rdef->counter++;
178
179 mdef->rdef = rdef;
180 mdef->reacting = reacting;
181 mdef->monitor->react = rdef->reactor->react;
182
183 /* enable only once if iterating through a container */
184 if (monitor_enabled && !nested)
185 rv_enable_monitor(mdef);
186 }
187
monitor_swap_reactors(struct rv_monitor_def * mdef,struct rv_reactor_def * rdef,bool reacting)188 static void monitor_swap_reactors(struct rv_monitor_def *mdef,
189 struct rv_reactor_def *rdef, bool reacting)
190 {
191 struct rv_monitor_def *p = mdef;
192
193 if (rv_is_container_monitor(mdef))
194 list_for_each_entry_continue(p, &rv_monitors_list, list) {
195 if (p->parent != mdef->monitor)
196 break;
197 monitor_swap_reactors_single(p, rdef, reacting, true);
198 }
199 /*
200 * This call enables and disables the monitor if they were active.
201 * In case of a container, we already disabled all and will enable all.
202 * All nested monitors are enabled also if they were off, we may refine
203 * this logic in the future.
204 */
205 monitor_swap_reactors_single(mdef, rdef, reacting, false);
206 }
207
208 static ssize_t
monitor_reactors_write(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)209 monitor_reactors_write(struct file *file, const char __user *user_buf,
210 size_t count, loff_t *ppos)
211 {
212 char buff[MAX_RV_REACTOR_NAME_SIZE + 2];
213 struct rv_monitor_def *mdef;
214 struct rv_reactor_def *rdef;
215 struct seq_file *seq_f;
216 int retval = -EINVAL;
217 bool enable;
218 char *ptr;
219 int len;
220
221 if (count < 1 || count > MAX_RV_REACTOR_NAME_SIZE + 1)
222 return -EINVAL;
223
224 memset(buff, 0, sizeof(buff));
225
226 retval = simple_write_to_buffer(buff, sizeof(buff) - 1, ppos, user_buf, count);
227 if (retval < 0)
228 return -EFAULT;
229
230 ptr = strim(buff);
231
232 len = strlen(ptr);
233 if (!len)
234 return count;
235
236 /*
237 * See monitor_reactors_open()
238 */
239 seq_f = file->private_data;
240 mdef = seq_f->private;
241
242 mutex_lock(&rv_interface_lock);
243
244 retval = -EINVAL;
245
246 list_for_each_entry(rdef, &rv_reactors_list, list) {
247 if (strcmp(ptr, rdef->reactor->name) != 0)
248 continue;
249
250 if (rdef == get_reactor_rdef_by_name("nop"))
251 enable = false;
252 else
253 enable = true;
254
255 monitor_swap_reactors(mdef, rdef, enable);
256
257 retval = count;
258 break;
259 }
260
261 mutex_unlock(&rv_interface_lock);
262
263 return retval;
264 }
265
266 /*
267 * available_reactors interface.
268 */
monitor_reactors_open(struct inode * inode,struct file * file)269 static int monitor_reactors_open(struct inode *inode, struct file *file)
270 {
271 struct rv_monitor_def *mdef = inode->i_private;
272 struct seq_file *seq_f;
273 int ret;
274
275 ret = seq_open(file, &monitor_reactors_seq_ops);
276 if (ret < 0)
277 return ret;
278
279 /*
280 * seq_open stores the seq_file on the file->private data.
281 */
282 seq_f = file->private_data;
283
284 /*
285 * Copy the create file "private" data to the seq_file private data.
286 */
287 seq_f->private = mdef;
288
289 return 0;
290 };
291
292 static const struct file_operations monitor_reactors_ops = {
293 .open = monitor_reactors_open,
294 .read = seq_read,
295 .llseek = seq_lseek,
296 .release = seq_release,
297 .write = monitor_reactors_write
298 };
299
__rv_register_reactor(struct rv_reactor * reactor)300 static int __rv_register_reactor(struct rv_reactor *reactor)
301 {
302 struct rv_reactor_def *r;
303
304 list_for_each_entry(r, &rv_reactors_list, list) {
305 if (strcmp(reactor->name, r->reactor->name) == 0) {
306 pr_info("Reactor %s is already registered\n", reactor->name);
307 return -EINVAL;
308 }
309 }
310
311 r = kzalloc(sizeof(struct rv_reactor_def), GFP_KERNEL);
312 if (!r)
313 return -ENOMEM;
314
315 r->reactor = reactor;
316 r->counter = 0;
317
318 list_add_tail(&r->list, &rv_reactors_list);
319
320 return 0;
321 }
322
323 /**
324 * rv_register_reactor - register a rv reactor.
325 * @reactor: The rv_reactor to be registered.
326 *
327 * Returns 0 if successful, error otherwise.
328 */
rv_register_reactor(struct rv_reactor * reactor)329 int rv_register_reactor(struct rv_reactor *reactor)
330 {
331 int retval = 0;
332
333 if (strlen(reactor->name) >= MAX_RV_REACTOR_NAME_SIZE) {
334 pr_info("Reactor %s has a name longer than %d\n",
335 reactor->name, MAX_RV_MONITOR_NAME_SIZE);
336 return -EINVAL;
337 }
338
339 mutex_lock(&rv_interface_lock);
340 retval = __rv_register_reactor(reactor);
341 mutex_unlock(&rv_interface_lock);
342 return retval;
343 }
344
345 /**
346 * rv_unregister_reactor - unregister a rv reactor.
347 * @reactor: The rv_reactor to be unregistered.
348 *
349 * Returns 0 if successful, error otherwise.
350 */
rv_unregister_reactor(struct rv_reactor * reactor)351 int rv_unregister_reactor(struct rv_reactor *reactor)
352 {
353 struct rv_reactor_def *ptr, *next;
354 int ret = 0;
355
356 mutex_lock(&rv_interface_lock);
357
358 list_for_each_entry_safe(ptr, next, &rv_reactors_list, list) {
359 if (strcmp(reactor->name, ptr->reactor->name) == 0) {
360
361 if (!ptr->counter) {
362 list_del(&ptr->list);
363 } else {
364 printk(KERN_WARNING
365 "rv: the rv_reactor %s is in use by %d monitor(s)\n",
366 ptr->reactor->name, ptr->counter);
367 printk(KERN_WARNING "rv: the rv_reactor %s cannot be removed\n",
368 ptr->reactor->name);
369 ret = -EBUSY;
370 break;
371 }
372 }
373 }
374
375 mutex_unlock(&rv_interface_lock);
376 return ret;
377 }
378
379 /*
380 * reacting_on interface.
381 */
382 static bool __read_mostly reacting_on;
383
384 /**
385 * rv_reacting_on - checks if reacting is on
386 *
387 * Returns 1 if on, 0 otherwise.
388 */
rv_reacting_on(void)389 bool rv_reacting_on(void)
390 {
391 /* Ensures that concurrent monitors read consistent reacting_on */
392 smp_rmb();
393 return READ_ONCE(reacting_on);
394 }
395
reacting_on_read_data(struct file * filp,char __user * user_buf,size_t count,loff_t * ppos)396 static ssize_t reacting_on_read_data(struct file *filp,
397 char __user *user_buf,
398 size_t count, loff_t *ppos)
399 {
400 char *buff;
401
402 buff = rv_reacting_on() ? "1\n" : "0\n";
403
404 return simple_read_from_buffer(user_buf, count, ppos, buff, strlen(buff)+1);
405 }
406
turn_reacting_off(void)407 static void turn_reacting_off(void)
408 {
409 WRITE_ONCE(reacting_on, false);
410 /* Ensures that concurrent monitors read consistent reacting_on */
411 smp_wmb();
412 }
413
turn_reacting_on(void)414 static void turn_reacting_on(void)
415 {
416 WRITE_ONCE(reacting_on, true);
417 /* Ensures that concurrent monitors read consistent reacting_on */
418 smp_wmb();
419 }
420
reacting_on_write_data(struct file * filp,const char __user * user_buf,size_t count,loff_t * ppos)421 static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
422 size_t count, loff_t *ppos)
423 {
424 int retval;
425 bool val;
426
427 retval = kstrtobool_from_user(user_buf, count, &val);
428 if (retval)
429 return retval;
430
431 mutex_lock(&rv_interface_lock);
432
433 if (val)
434 turn_reacting_on();
435 else
436 turn_reacting_off();
437
438 /*
439 * Wait for the execution of all events to finish
440 * before returning to user-space.
441 */
442 tracepoint_synchronize_unregister();
443
444 mutex_unlock(&rv_interface_lock);
445
446 return count;
447 }
448
449 static const struct file_operations reacting_on_fops = {
450 .open = simple_open,
451 .write = reacting_on_write_data,
452 .read = reacting_on_read_data,
453 };
454
455 /**
456 * reactor_populate_monitor - creates per monitor reactors file
457 * @mdef: monitor's definition.
458 *
459 * Returns 0 if successful, error otherwise.
460 */
reactor_populate_monitor(struct rv_monitor_def * mdef)461 int reactor_populate_monitor(struct rv_monitor_def *mdef)
462 {
463 struct dentry *tmp;
464
465 tmp = rv_create_file("reactors", RV_MODE_WRITE, mdef->root_d, mdef, &monitor_reactors_ops);
466 if (!tmp)
467 return -ENOMEM;
468
469 /*
470 * Configure as the rv_nop reactor.
471 */
472 mdef->rdef = get_reactor_rdef_by_name("nop");
473 mdef->rdef->counter++;
474 mdef->reacting = false;
475
476 return 0;
477 }
478
479 /**
480 * reactor_cleanup_monitor - cleanup a monitor reference
481 * @mdef: monitor's definition.
482 */
reactor_cleanup_monitor(struct rv_monitor_def * mdef)483 void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
484 {
485 lockdep_assert_held(&rv_interface_lock);
486 mdef->rdef->counter--;
487 WARN_ON_ONCE(mdef->rdef->counter < 0);
488 }
489
490 /*
491 * Nop reactor register
492 */
rv_nop_reaction(char * msg)493 static void rv_nop_reaction(char *msg)
494 {
495 }
496
497 static struct rv_reactor rv_nop = {
498 .name = "nop",
499 .description = "no-operation reactor: do nothing.",
500 .react = rv_nop_reaction
501 };
502
init_rv_reactors(struct dentry * root_dir)503 int init_rv_reactors(struct dentry *root_dir)
504 {
505 struct dentry *available, *reacting;
506 int retval;
507
508 available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
509 &available_reactors_ops);
510 if (!available)
511 goto out_err;
512
513 reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
514 if (!reacting)
515 goto rm_available;
516
517 retval = __rv_register_reactor(&rv_nop);
518 if (retval)
519 goto rm_reacting;
520
521 turn_reacting_on();
522
523 return 0;
524
525 rm_reacting:
526 rv_remove(reacting);
527 rm_available:
528 rv_remove(available);
529 out_err:
530 return -ENOMEM;
531 }
532