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 8 static 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 17 static 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 } 31 ALLOW_ERROR_INJECTION(should_fail_net_realloc_skb, TRUE); 32 33 void 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 } 40 EXPORT_SYMBOL(skb_might_realloc); 41 42 static 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 48 static void reset_settings(void) 49 { 50 skb_realloc.filtered = false; 51 memset(&skb_realloc.devname, 0, IFNAMSIZ); 52 } 53 54 static 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 75 static 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 86 static const struct file_operations devname_ops = { 87 .write = devname_write, 88 .read = devname_read, 89 }; 90 91 static 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 106 late_initcall(fail_skb_realloc_debugfs); 107