Loading...
Note: File does not exist in v5.14.15.
1// SPDX-License-Identifier: GPL-2.0-only
2
3#include <linux/debugfs.h>
4#include <linux/fault-inject.h>
5#include <linux/netdevice.h>
6#include <linux/skbuff.h>
7
8static struct {
9 struct fault_attr attr;
10 char devname[IFNAMSIZ];
11 bool filtered;
12} skb_realloc = {
13 .attr = FAULT_ATTR_INITIALIZER,
14 .filtered = false,
15};
16
17static bool should_fail_net_realloc_skb(struct sk_buff *skb)
18{
19 struct net_device *net = skb->dev;
20
21 if (skb_realloc.filtered &&
22 strncmp(net->name, skb_realloc.devname, IFNAMSIZ))
23 /* device name filter set, but names do not match */
24 return false;
25
26 if (!should_fail(&skb_realloc.attr, 1))
27 return false;
28
29 return true;
30}
31ALLOW_ERROR_INJECTION(should_fail_net_realloc_skb, TRUE);
32
33void skb_might_realloc(struct sk_buff *skb)
34{
35 if (!should_fail_net_realloc_skb(skb))
36 return;
37
38 pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
39}
40EXPORT_SYMBOL(skb_might_realloc);
41
42static int __init fail_skb_realloc_setup(char *str)
43{
44 return setup_fault_attr(&skb_realloc.attr, str);
45}
46__setup("fail_skb_realloc=", fail_skb_realloc_setup);
47
48static void reset_settings(void)
49{
50 skb_realloc.filtered = false;
51 memset(&skb_realloc.devname, 0, IFNAMSIZ);
52}
53
54static ssize_t devname_write(struct file *file, const char __user *buffer,
55 size_t count, loff_t *ppos)
56{
57 ssize_t ret;
58
59 reset_settings();
60 ret = simple_write_to_buffer(&skb_realloc.devname, IFNAMSIZ,
61 ppos, buffer, count);
62 if (ret < 0)
63 return ret;
64
65 skb_realloc.devname[IFNAMSIZ - 1] = '\0';
66 /* Remove a possible \n at the end of devname */
67 strim(skb_realloc.devname);
68
69 if (strnlen(skb_realloc.devname, IFNAMSIZ))
70 skb_realloc.filtered = true;
71
72 return count;
73}
74
75static ssize_t devname_read(struct file *file,
76 char __user *buffer,
77 size_t size, loff_t *ppos)
78{
79 if (!skb_realloc.filtered)
80 return 0;
81
82 return simple_read_from_buffer(buffer, size, ppos, &skb_realloc.devname,
83 strlen(skb_realloc.devname));
84}
85
86static const struct file_operations devname_ops = {
87 .write = devname_write,
88 .read = devname_read,
89};
90
91static int __init fail_skb_realloc_debugfs(void)
92{
93 umode_t mode = S_IFREG | 0600;
94 struct dentry *dir;
95
96 dir = fault_create_debugfs_attr("fail_skb_realloc", NULL,
97 &skb_realloc.attr);
98 if (IS_ERR(dir))
99 return PTR_ERR(dir);
100
101 debugfs_create_file("devname", mode, dir, NULL, &devname_ops);
102
103 return 0;
104}
105
106late_initcall(fail_skb_realloc_debugfs);