1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * connector.c 4 * 5 * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> 6 * All rights reserved. 7 */ 8 9 #include <linux/compiler.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/list.h> 13 #include <linux/skbuff.h> 14 #include <net/netlink.h> 15 #include <linux/moduleparam.h> 16 #include <linux/connector.h> 17 #include <linux/slab.h> 18 #include <linux/mutex.h> 19 #include <linux/proc_fs.h> 20 #include <linux/spinlock.h> 21 22 #include <net/sock.h> 23 24 MODULE_LICENSE("GPL"); 25 MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); 26 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); 27 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); 28 29 static struct cn_dev cdev; 30 31 static int cn_already_initialized; 32 33 /* 34 * Sends mult (multiple) cn_msg at a time. 35 * 36 * msg->seq and msg->ack are used to determine message genealogy. 37 * When someone sends message it puts there locally unique sequence 38 * and random acknowledge numbers. Sequence number may be copied into 39 * nlmsghdr->nlmsg_seq too. 40 * 41 * Sequence number is incremented with each message to be sent. 42 * 43 * If we expect a reply to our message then the sequence number in 44 * received message MUST be the same as in original message, and 45 * acknowledge number MUST be the same + 1. 46 * 47 * If we receive a message and its sequence number is not equal to the 48 * one we are expecting then it is a new message. 49 * 50 * If we receive a message and its sequence number is the same as one 51 * we are expecting but it's acknowledgement number is not equal to 52 * the acknowledgement number in the original message + 1, then it is 53 * a new message. 54 * 55 * If msg->len != len, then additional cn_msg messages are expected following 56 * the first msg. 57 * 58 * The message is sent to, the portid if given, the group if given, both if 59 * both, or if both are zero then the group is looked up and sent there. 60 */ 61 int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 __group, 62 gfp_t gfp_mask, 63 int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data), 64 void *filter_data) 65 { 66 struct cn_callback_entry *__cbq; 67 unsigned int size; 68 struct sk_buff *skb; 69 struct nlmsghdr *nlh; 70 struct cn_msg *data; 71 struct cn_dev *dev = &cdev; 72 u32 group = 0; 73 int found = 0; 74 75 if (portid || __group) { 76 group = __group; 77 } else { 78 spin_lock_bh(&dev->cbdev->queue_lock); 79 list_for_each_entry(__cbq, &dev->cbdev->queue_list, 80 callback_entry) { 81 if (cn_cb_equal(&__cbq->id.id, &msg->id)) { 82 found = 1; 83 group = __cbq->group; 84 break; 85 } 86 } 87 spin_unlock_bh(&dev->cbdev->queue_lock); 88 89 if (!found) 90 return -ENODEV; 91 } 92 93 if (!portid && !netlink_has_listeners(dev->nls, group)) 94 return -ESRCH; 95 96 size = sizeof(*msg) + len; 97 98 skb = nlmsg_new(size, gfp_mask); 99 if (!skb) 100 return -ENOMEM; 101 102 nlh = nlmsg_put(skb, 0, msg->seq, NLMSG_DONE, size, 0); 103 if (!nlh) { 104 kfree_skb(skb); 105 return -EMSGSIZE; 106 } 107 108 data = nlmsg_data(nlh); 109 110 memcpy(data, msg, size); 111 112 NETLINK_CB(skb).dst_group = group; 113 114 if (group) 115 return netlink_broadcast_filtered(dev->nls, skb, portid, group, 116 gfp_mask, filter, 117 (void *)filter_data); 118 return netlink_unicast(dev->nls, skb, portid, 119 !gfpflags_allow_blocking(gfp_mask)); 120 } 121 EXPORT_SYMBOL_GPL(cn_netlink_send_mult); 122 123 /* same as cn_netlink_send_mult except msg->len is used for len */ 124 int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, 125 gfp_t gfp_mask) 126 { 127 return cn_netlink_send_mult(msg, msg->len, portid, __group, gfp_mask, 128 NULL, NULL); 129 } 130 EXPORT_SYMBOL_GPL(cn_netlink_send); 131 132 /* 133 * Callback helper - queues work and setup destructor for given data. 134 */ 135 static int cn_call_callback(struct sk_buff *skb) 136 { 137 struct nlmsghdr *nlh; 138 struct cn_callback_entry *i, *cbq = NULL; 139 struct cn_dev *dev = &cdev; 140 struct cn_msg *msg = nlmsg_data(nlmsg_hdr(skb)); 141 struct netlink_skb_parms *nsp = &NETLINK_CB(skb); 142 int err = -ENODEV; 143 144 /* verify msg->len is within skb */ 145 nlh = nlmsg_hdr(skb); 146 if (nlh->nlmsg_len < NLMSG_HDRLEN + sizeof(struct cn_msg) + msg->len) 147 return -EINVAL; 148 149 spin_lock_bh(&dev->cbdev->queue_lock); 150 list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) { 151 if (cn_cb_equal(&i->id.id, &msg->id)) { 152 refcount_inc(&i->refcnt); 153 cbq = i; 154 break; 155 } 156 } 157 spin_unlock_bh(&dev->cbdev->queue_lock); 158 159 if (cbq != NULL) { 160 cbq->callback(msg, nsp); 161 kfree_skb(skb); 162 cn_queue_release_callback(cbq); 163 err = 0; 164 } 165 166 return err; 167 } 168 169 /* 170 * Allow non-root access for NETLINK_CONNECTOR family having CN_IDX_PROC 171 * multicast group. 172 */ 173 static int cn_bind(struct net *net, int group) 174 { 175 unsigned long groups = (unsigned long) group; 176 177 if (ns_capable(net->user_ns, CAP_NET_ADMIN)) 178 return 0; 179 180 if (test_bit(CN_IDX_PROC - 1, &groups)) 181 return 0; 182 183 return -EPERM; 184 } 185 186 static void cn_release(struct sock *sk, unsigned long *groups) 187 { 188 if (groups && test_bit(CN_IDX_PROC - 1, groups)) { 189 kfree(sk->sk_user_data); 190 sk->sk_user_data = NULL; 191 } 192 } 193 194 /* 195 * Main netlink receiving function. 196 * 197 * It checks skb, netlink header and msg sizes, and calls callback helper. 198 */ 199 static void cn_rx_skb(struct sk_buff *skb) 200 { 201 struct nlmsghdr *nlh; 202 int len, err; 203 204 if (skb->len >= NLMSG_HDRLEN) { 205 nlh = nlmsg_hdr(skb); 206 len = nlmsg_len(nlh); 207 208 if (len < (int)sizeof(struct cn_msg) || 209 skb->len < nlh->nlmsg_len || 210 len > CONNECTOR_MAX_MSG_SIZE) 211 return; 212 213 err = cn_call_callback(skb_get(skb)); 214 if (err < 0) 215 kfree_skb(skb); 216 } 217 } 218 219 /* 220 * Callback add routing - adds callback with given ID and name. 221 * If there is registered callback with the same ID it will not be added. 222 * 223 * May sleep. 224 */ 225 int cn_add_callback(const struct cb_id *id, const char *name, 226 void (*callback)(struct cn_msg *, 227 struct netlink_skb_parms *)) 228 { 229 struct cn_dev *dev = &cdev; 230 231 if (!cn_already_initialized) 232 return -EAGAIN; 233 234 return cn_queue_add_callback(dev->cbdev, name, id, callback); 235 } 236 EXPORT_SYMBOL_GPL(cn_add_callback); 237 238 /* 239 * Callback remove routing - removes callback 240 * with given ID. 241 * If there is no registered callback with given 242 * ID nothing happens. 243 * 244 * May sleep while waiting for reference counter to become zero. 245 */ 246 void cn_del_callback(const struct cb_id *id) 247 { 248 struct cn_dev *dev = &cdev; 249 250 cn_queue_del_callback(dev->cbdev, id); 251 } 252 EXPORT_SYMBOL_GPL(cn_del_callback); 253 254 static int __maybe_unused cn_proc_show(struct seq_file *m, void *v) 255 { 256 struct cn_queue_dev *dev = cdev.cbdev; 257 struct cn_callback_entry *cbq; 258 259 seq_printf(m, "Name ID\n"); 260 261 spin_lock_bh(&dev->queue_lock); 262 263 list_for_each_entry(cbq, &dev->queue_list, callback_entry) { 264 seq_printf(m, "%-15s %u:%u\n", 265 cbq->id.name, 266 cbq->id.id.idx, 267 cbq->id.id.val); 268 } 269 270 spin_unlock_bh(&dev->queue_lock); 271 272 return 0; 273 } 274 275 static int cn_init(void) 276 { 277 struct cn_dev *dev = &cdev; 278 struct netlink_kernel_cfg cfg = { 279 .groups = CN_NETLINK_USERS + 0xf, 280 .input = cn_rx_skb, 281 .flags = NL_CFG_F_NONROOT_RECV, 282 .bind = cn_bind, 283 .release = cn_release, 284 }; 285 286 dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, &cfg); 287 if (!dev->nls) 288 return -EIO; 289 290 dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls); 291 if (!dev->cbdev) { 292 netlink_kernel_release(dev->nls); 293 return -EINVAL; 294 } 295 296 cn_already_initialized = 1; 297 298 proc_create_single("connector", S_IRUGO, init_net.proc_net, cn_proc_show); 299 300 return 0; 301 } 302 303 static void cn_fini(void) 304 { 305 struct cn_dev *dev = &cdev; 306 307 cn_already_initialized = 0; 308 309 remove_proc_entry("connector", init_net.proc_net); 310 311 cn_queue_free_dev(dev->cbdev); 312 netlink_kernel_release(dev->nls); 313 } 314 315 subsys_initcall(cn_init); 316 module_exit(cn_fini); 317