aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c98
-rw-r--r--net/netlink/attr.c5
-rw-r--r--net/netlink/genetlink.c66
3 files changed, 88 insertions, 81 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c48b0f49f003..42d2fb94eff1 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -56,6 +56,7 @@
56#include <linux/types.h> 56#include <linux/types.h>
57#include <linux/audit.h> 57#include <linux/audit.h>
58#include <linux/selinux.h> 58#include <linux/selinux.h>
59#include <linux/mutex.h>
59 60
60#include <net/sock.h> 61#include <net/sock.h>
61#include <net/scm.h> 62#include <net/scm.h>
@@ -76,7 +77,8 @@ struct netlink_sock {
76 unsigned long state; 77 unsigned long state;
77 wait_queue_head_t wait; 78 wait_queue_head_t wait;
78 struct netlink_callback *cb; 79 struct netlink_callback *cb;
79 spinlock_t cb_lock; 80 struct mutex *cb_mutex;
81 struct mutex cb_def_mutex;
80 void (*data_ready)(struct sock *sk, int bytes); 82 void (*data_ready)(struct sock *sk, int bytes);
81 struct module *module; 83 struct module *module;
82}; 84};
@@ -108,6 +110,7 @@ struct netlink_table {
108 unsigned long *listeners; 110 unsigned long *listeners;
109 unsigned int nl_nonroot; 111 unsigned int nl_nonroot;
110 unsigned int groups; 112 unsigned int groups;
113 struct mutex *cb_mutex;
111 struct module *module; 114 struct module *module;
112 int registered; 115 int registered;
113}; 116};
@@ -118,6 +121,7 @@ static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
118 121
119static int netlink_dump(struct sock *sk); 122static int netlink_dump(struct sock *sk);
120static void netlink_destroy_callback(struct netlink_callback *cb); 123static void netlink_destroy_callback(struct netlink_callback *cb);
124static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb);
121 125
122static DEFINE_RWLOCK(nl_table_lock); 126static DEFINE_RWLOCK(nl_table_lock);
123static atomic_t nl_table_users = ATOMIC_INIT(0); 127static atomic_t nl_table_users = ATOMIC_INIT(0);
@@ -370,7 +374,8 @@ static struct proto netlink_proto = {
370 .obj_size = sizeof(struct netlink_sock), 374 .obj_size = sizeof(struct netlink_sock),
371}; 375};
372 376
373static int __netlink_create(struct socket *sock, int protocol) 377static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
378 int protocol)
374{ 379{
375 struct sock *sk; 380 struct sock *sk;
376 struct netlink_sock *nlk; 381 struct netlink_sock *nlk;
@@ -384,7 +389,12 @@ static int __netlink_create(struct socket *sock, int protocol)
384 sock_init_data(sock, sk); 389 sock_init_data(sock, sk);
385 390
386 nlk = nlk_sk(sk); 391 nlk = nlk_sk(sk);
387 spin_lock_init(&nlk->cb_lock); 392 if (cb_mutex)
393 nlk->cb_mutex = cb_mutex;
394 else {
395 nlk->cb_mutex = &nlk->cb_def_mutex;
396 mutex_init(nlk->cb_mutex);
397 }
388 init_waitqueue_head(&nlk->wait); 398 init_waitqueue_head(&nlk->wait);
389 399
390 sk->sk_destruct = netlink_sock_destruct; 400 sk->sk_destruct = netlink_sock_destruct;
@@ -395,8 +405,8 @@ static int __netlink_create(struct socket *sock, int protocol)
395static int netlink_create(struct socket *sock, int protocol) 405static int netlink_create(struct socket *sock, int protocol)
396{ 406{
397 struct module *module = NULL; 407 struct module *module = NULL;
408 struct mutex *cb_mutex;
398 struct netlink_sock *nlk; 409 struct netlink_sock *nlk;
399 unsigned int groups;
400 int err = 0; 410 int err = 0;
401 411
402 sock->state = SS_UNCONNECTED; 412 sock->state = SS_UNCONNECTED;
@@ -418,10 +428,10 @@ static int netlink_create(struct socket *sock, int protocol)
418 if (nl_table[protocol].registered && 428 if (nl_table[protocol].registered &&
419 try_module_get(nl_table[protocol].module)) 429 try_module_get(nl_table[protocol].module))
420 module = nl_table[protocol].module; 430 module = nl_table[protocol].module;
421 groups = nl_table[protocol].groups; 431 cb_mutex = nl_table[protocol].cb_mutex;
422 netlink_unlock_table(); 432 netlink_unlock_table();
423 433
424 if ((err = __netlink_create(sock, protocol)) < 0) 434 if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0)
425 goto out_module; 435 goto out_module;
426 436
427 nlk = nlk_sk(sock->sk); 437 nlk = nlk_sk(sock->sk);
@@ -446,14 +456,14 @@ static int netlink_release(struct socket *sock)
446 sock_orphan(sk); 456 sock_orphan(sk);
447 nlk = nlk_sk(sk); 457 nlk = nlk_sk(sk);
448 458
449 spin_lock(&nlk->cb_lock); 459 mutex_lock(nlk->cb_mutex);
450 if (nlk->cb) { 460 if (nlk->cb) {
451 if (nlk->cb->done) 461 if (nlk->cb->done)
452 nlk->cb->done(nlk->cb); 462 nlk->cb->done(nlk->cb);
453 netlink_destroy_callback(nlk->cb); 463 netlink_destroy_callback(nlk->cb);
454 nlk->cb = NULL; 464 nlk->cb = NULL;
455 } 465 }
456 spin_unlock(&nlk->cb_lock); 466 mutex_unlock(nlk->cb_mutex);
457 467
458 /* OK. Socket is unlinked, and, therefore, 468 /* OK. Socket is unlinked, and, therefore,
459 no new packets will arrive */ 469 no new packets will arrive */
@@ -1215,7 +1225,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1215 copied = len; 1225 copied = len;
1216 } 1226 }
1217 1227
1218 skb->h.raw = skb->data; 1228 skb_reset_transport_header(skb);
1219 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1229 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1220 1230
1221 if (msg->msg_name) { 1231 if (msg->msg_name) {
@@ -1242,6 +1252,9 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1242 1252
1243 scm_recv(sock, msg, siocb->scm, flags); 1253 scm_recv(sock, msg, siocb->scm, flags);
1244 1254
1255 if (flags & MSG_TRUNC)
1256 copied = skb->len;
1257
1245out: 1258out:
1246 netlink_rcv_wake(sk); 1259 netlink_rcv_wake(sk);
1247 return err ? : copied; 1260 return err ? : copied;
@@ -1265,7 +1278,7 @@ static void netlink_data_ready(struct sock *sk, int len)
1265struct sock * 1278struct sock *
1266netlink_kernel_create(int unit, unsigned int groups, 1279netlink_kernel_create(int unit, unsigned int groups,
1267 void (*input)(struct sock *sk, int len), 1280 void (*input)(struct sock *sk, int len),
1268 struct module *module) 1281 struct mutex *cb_mutex, struct module *module)
1269{ 1282{
1270 struct socket *sock; 1283 struct socket *sock;
1271 struct sock *sk; 1284 struct sock *sk;
@@ -1280,7 +1293,7 @@ netlink_kernel_create(int unit, unsigned int groups,
1280 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) 1293 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
1281 return NULL; 1294 return NULL;
1282 1295
1283 if (__netlink_create(sock, unit) < 0) 1296 if (__netlink_create(sock, cb_mutex, unit) < 0)
1284 goto out_sock_release; 1297 goto out_sock_release;
1285 1298
1286 if (groups < 32) 1299 if (groups < 32)
@@ -1304,6 +1317,7 @@ netlink_kernel_create(int unit, unsigned int groups,
1304 netlink_table_grab(); 1317 netlink_table_grab();
1305 nl_table[unit].groups = groups; 1318 nl_table[unit].groups = groups;
1306 nl_table[unit].listeners = listeners; 1319 nl_table[unit].listeners = listeners;
1320 nl_table[unit].cb_mutex = cb_mutex;
1307 nl_table[unit].module = module; 1321 nl_table[unit].module = module;
1308 nl_table[unit].registered = 1; 1322 nl_table[unit].registered = 1;
1309 netlink_table_ungrab(); 1323 netlink_table_ungrab();
@@ -1346,7 +1360,7 @@ static int netlink_dump(struct sock *sk)
1346 if (!skb) 1360 if (!skb)
1347 goto errout; 1361 goto errout;
1348 1362
1349 spin_lock(&nlk->cb_lock); 1363 mutex_lock(nlk->cb_mutex);
1350 1364
1351 cb = nlk->cb; 1365 cb = nlk->cb;
1352 if (cb == NULL) { 1366 if (cb == NULL) {
@@ -1357,7 +1371,7 @@ static int netlink_dump(struct sock *sk)
1357 len = cb->dump(skb, cb); 1371 len = cb->dump(skb, cb);
1358 1372
1359 if (len > 0) { 1373 if (len > 0) {
1360 spin_unlock(&nlk->cb_lock); 1374 mutex_unlock(nlk->cb_mutex);
1361 skb_queue_tail(&sk->sk_receive_queue, skb); 1375 skb_queue_tail(&sk->sk_receive_queue, skb);
1362 sk->sk_data_ready(sk, len); 1376 sk->sk_data_ready(sk, len);
1363 return 0; 1377 return 0;
@@ -1375,13 +1389,13 @@ static int netlink_dump(struct sock *sk)
1375 if (cb->done) 1389 if (cb->done)
1376 cb->done(cb); 1390 cb->done(cb);
1377 nlk->cb = NULL; 1391 nlk->cb = NULL;
1378 spin_unlock(&nlk->cb_lock); 1392 mutex_unlock(nlk->cb_mutex);
1379 1393
1380 netlink_destroy_callback(cb); 1394 netlink_destroy_callback(cb);
1381 return 0; 1395 return 0;
1382 1396
1383errout_skb: 1397errout_skb:
1384 spin_unlock(&nlk->cb_lock); 1398 mutex_unlock(nlk->cb_mutex);
1385 kfree_skb(skb); 1399 kfree_skb(skb);
1386errout: 1400errout:
1387 return err; 1401 return err;
@@ -1413,19 +1427,24 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1413 } 1427 }
1414 nlk = nlk_sk(sk); 1428 nlk = nlk_sk(sk);
1415 /* A dump or destruction is in progress... */ 1429 /* A dump or destruction is in progress... */
1416 spin_lock(&nlk->cb_lock); 1430 mutex_lock(nlk->cb_mutex);
1417 if (nlk->cb || sock_flag(sk, SOCK_DEAD)) { 1431 if (nlk->cb || sock_flag(sk, SOCK_DEAD)) {
1418 spin_unlock(&nlk->cb_lock); 1432 mutex_unlock(nlk->cb_mutex);
1419 netlink_destroy_callback(cb); 1433 netlink_destroy_callback(cb);
1420 sock_put(sk); 1434 sock_put(sk);
1421 return -EBUSY; 1435 return -EBUSY;
1422 } 1436 }
1423 nlk->cb = cb; 1437 nlk->cb = cb;
1424 spin_unlock(&nlk->cb_lock); 1438 mutex_unlock(nlk->cb_mutex);
1425 1439
1426 netlink_dump(sk); 1440 netlink_dump(sk);
1427 sock_put(sk); 1441 sock_put(sk);
1428 return 0; 1442
1443 /* We successfully started a dump, by returning -EINTR we
1444 * signal the queue mangement to interrupt processing of
1445 * any netlink messages so userspace gets a chance to read
1446 * the results. */
1447 return -EINTR;
1429} 1448}
1430 1449
1431void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) 1450void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
@@ -1462,27 +1481,35 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1462} 1481}
1463 1482
1464static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, 1483static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1465 struct nlmsghdr *, int *)) 1484 struct nlmsghdr *))
1466{ 1485{
1467 struct nlmsghdr *nlh; 1486 struct nlmsghdr *nlh;
1468 int err; 1487 int err;
1469 1488
1470 while (skb->len >= nlmsg_total_size(0)) { 1489 while (skb->len >= nlmsg_total_size(0)) {
1471 nlh = (struct nlmsghdr *) skb->data; 1490 nlh = nlmsg_hdr(skb);
1491 err = 0;
1472 1492
1473 if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len) 1493 if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
1474 return 0; 1494 return 0;
1475 1495
1476 if (cb(skb, nlh, &err) < 0) { 1496 /* Only requests are handled by the kernel */
1477 /* Not an error, but we have to interrupt processing 1497 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
1478 * here. Note: that in this case we do not pull 1498 goto skip;
1479 * message from skb, it will be processed later. 1499
1480 */ 1500 /* Skip control messages */
1481 if (err == 0) 1501 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
1482 return -1; 1502 goto skip;
1503
1504 err = cb(skb, nlh);
1505 if (err == -EINTR) {
1506 /* Not an error, but we interrupt processing */
1507 netlink_queue_skip(nlh, skb);
1508 return err;
1509 }
1510skip:
1511 if (nlh->nlmsg_flags & NLM_F_ACK || err)
1483 netlink_ack(skb, nlh, err); 1512 netlink_ack(skb, nlh, err);
1484 } else if (nlh->nlmsg_flags & NLM_F_ACK)
1485 netlink_ack(skb, nlh, 0);
1486 1513
1487 netlink_queue_skip(nlh, skb); 1514 netlink_queue_skip(nlh, skb);
1488 } 1515 }
@@ -1504,9 +1531,14 @@ static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1504 * 1531 *
1505 * qlen must be initialized to 0 before the initial entry, afterwards 1532 * qlen must be initialized to 0 before the initial entry, afterwards
1506 * the function may be called repeatedly until qlen reaches 0. 1533 * the function may be called repeatedly until qlen reaches 0.
1534 *
1535 * The callback function may return -EINTR to signal that processing
1536 * of netlink messages shall be interrupted. In this case the message
1537 * currently being processed will NOT be requeued onto the receive
1538 * queue.
1507 */ 1539 */
1508void netlink_run_queue(struct sock *sk, unsigned int *qlen, 1540void netlink_run_queue(struct sock *sk, unsigned int *qlen,
1509 int (*cb)(struct sk_buff *, struct nlmsghdr *, int *)) 1541 int (*cb)(struct sk_buff *, struct nlmsghdr *))
1510{ 1542{
1511 struct sk_buff *skb; 1543 struct sk_buff *skb;
1512 1544
@@ -1537,7 +1569,7 @@ void netlink_run_queue(struct sock *sk, unsigned int *qlen,
1537 * Pulls the given netlink message off the socket buffer so the next 1569 * Pulls the given netlink message off the socket buffer so the next
1538 * call to netlink_queue_run() will not reconsider the message. 1570 * call to netlink_queue_run() will not reconsider the message.
1539 */ 1571 */
1540void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb) 1572static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
1541{ 1573{
1542 int msglen = NLMSG_ALIGN(nlh->nlmsg_len); 1574 int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
1543 1575
@@ -1820,12 +1852,10 @@ core_initcall(netlink_proto_init);
1820 1852
1821EXPORT_SYMBOL(netlink_ack); 1853EXPORT_SYMBOL(netlink_ack);
1822EXPORT_SYMBOL(netlink_run_queue); 1854EXPORT_SYMBOL(netlink_run_queue);
1823EXPORT_SYMBOL(netlink_queue_skip);
1824EXPORT_SYMBOL(netlink_broadcast); 1855EXPORT_SYMBOL(netlink_broadcast);
1825EXPORT_SYMBOL(netlink_dump_start); 1856EXPORT_SYMBOL(netlink_dump_start);
1826EXPORT_SYMBOL(netlink_kernel_create); 1857EXPORT_SYMBOL(netlink_kernel_create);
1827EXPORT_SYMBOL(netlink_register_notifier); 1858EXPORT_SYMBOL(netlink_register_notifier);
1828EXPORT_SYMBOL(netlink_set_err);
1829EXPORT_SYMBOL(netlink_set_nonroot); 1859EXPORT_SYMBOL(netlink_set_nonroot);
1830EXPORT_SYMBOL(netlink_unicast); 1860EXPORT_SYMBOL(netlink_unicast);
1831EXPORT_SYMBOL(netlink_unregister_notifier); 1861EXPORT_SYMBOL(netlink_unregister_notifier);
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index 004139557e09..df5f820a4c32 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -67,6 +67,11 @@ static int validate_nla(struct nlattr *nla, int maxtype,
67 } 67 }
68 break; 68 break;
69 69
70 case NLA_BINARY:
71 if (pt->len && attrlen > pt->len)
72 return -ERANGE;
73 break;
74
70 default: 75 default:
71 if (pt->len) 76 if (pt->len)
72 minlen = pt->len; 77 minlen = pt->len;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index c2996794eb25..6e31234a4196 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -295,66 +295,46 @@ int genl_unregister_family(struct genl_family *family)
295 return -ENOENT; 295 return -ENOENT;
296} 296}
297 297
298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
299 int *errp)
300{ 299{
301 struct genl_ops *ops; 300 struct genl_ops *ops;
302 struct genl_family *family; 301 struct genl_family *family;
303 struct genl_info info; 302 struct genl_info info;
304 struct genlmsghdr *hdr = nlmsg_data(nlh); 303 struct genlmsghdr *hdr = nlmsg_data(nlh);
305 int hdrlen, err = -EINVAL; 304 int hdrlen, err;
306
307 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
308 goto ignore;
309
310 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
311 goto ignore;
312 305
313 family = genl_family_find_byid(nlh->nlmsg_type); 306 family = genl_family_find_byid(nlh->nlmsg_type);
314 if (family == NULL) { 307 if (family == NULL)
315 err = -ENOENT; 308 return -ENOENT;
316 goto errout;
317 }
318 309
319 hdrlen = GENL_HDRLEN + family->hdrsize; 310 hdrlen = GENL_HDRLEN + family->hdrsize;
320 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 311 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
321 goto errout; 312 return -EINVAL;
322 313
323 ops = genl_get_cmd(hdr->cmd, family); 314 ops = genl_get_cmd(hdr->cmd, family);
324 if (ops == NULL) { 315 if (ops == NULL)
325 err = -EOPNOTSUPP; 316 return -EOPNOTSUPP;
326 goto errout;
327 }
328 317
329 if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb, CAP_NET_ADMIN)) { 318 if ((ops->flags & GENL_ADMIN_PERM) &&
330 err = -EPERM; 319 security_netlink_recv(skb, CAP_NET_ADMIN))
331 goto errout; 320 return -EPERM;
332 }
333 321
334 if (nlh->nlmsg_flags & NLM_F_DUMP) { 322 if (nlh->nlmsg_flags & NLM_F_DUMP) {
335 if (ops->dumpit == NULL) { 323 if (ops->dumpit == NULL)
336 err = -EOPNOTSUPP; 324 return -EOPNOTSUPP;
337 goto errout;
338 }
339 325
340 *errp = err = netlink_dump_start(genl_sock, skb, nlh, 326 return netlink_dump_start(genl_sock, skb, nlh,
341 ops->dumpit, ops->done); 327 ops->dumpit, ops->done);
342 if (err == 0)
343 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
344 skb->len));
345 return -1;
346 } 328 }
347 329
348 if (ops->doit == NULL) { 330 if (ops->doit == NULL)
349 err = -EOPNOTSUPP; 331 return -EOPNOTSUPP;
350 goto errout;
351 }
352 332
353 if (family->attrbuf) { 333 if (family->attrbuf) {
354 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr, 334 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
355 ops->policy); 335 ops->policy);
356 if (err < 0) 336 if (err < 0)
357 goto errout; 337 return err;
358 } 338 }
359 339
360 info.snd_seq = nlh->nlmsg_seq; 340 info.snd_seq = nlh->nlmsg_seq;
@@ -364,15 +344,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
364 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 344 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
365 info.attrs = family->attrbuf; 345 info.attrs = family->attrbuf;
366 346
367 *errp = err = ops->doit(skb, &info); 347 return ops->doit(skb, &info);
368 return err;
369
370ignore:
371 return 0;
372
373errout:
374 *errp = err;
375 return -1;
376} 348}
377 349
378static void genl_rcv(struct sock *sk, int len) 350static void genl_rcv(struct sock *sk, int len)
@@ -586,7 +558,7 @@ static int __init genl_init(void)
586 558
587 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); 559 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
588 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, 560 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
589 genl_rcv, THIS_MODULE); 561 genl_rcv, NULL, THIS_MODULE);
590 if (genl_sock == NULL) 562 if (genl_sock == NULL)
591 panic("GENL: Cannot initialize generic netlink\n"); 563 panic("GENL: Cannot initialize generic netlink\n");
592 564