diff options
| -rw-r--r-- | drivers/w1/w1_int.c | 4 | ||||
| -rw-r--r-- | include/linux/net.h | 3 | ||||
| -rw-r--r-- | include/linux/netlink.h | 2 | ||||
| -rw-r--r-- | kernel/audit.c | 3 | ||||
| -rw-r--r-- | lib/kobject_uevent.c | 3 | ||||
| -rw-r--r-- | net/bridge/netfilter/ebt_ulog.c | 2 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 2 | ||||
| -rw-r--r-- | net/decnet/netfilter/dn_rtmsg.c | 4 | ||||
| -rw-r--r-- | net/ipv4/fib_frontend.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 3 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 3 | ||||
| -rw-r--r-- | net/ipv4/tcp_diag.c | 3 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 2 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink.c | 5 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 108 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 4 | ||||
| -rw-r--r-- | security/selinux/netlink.c | 2 |
17 files changed, 119 insertions, 36 deletions
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index b5a5e04b6d37..8809788dac26 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
| @@ -88,7 +88,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
| 88 | 88 | ||
| 89 | dev->groups = 23; | 89 | dev->groups = 23; |
| 90 | dev->seq = 1; | 90 | dev->seq = 1; |
| 91 | dev->nls = netlink_kernel_create(NETLINK_W1, NULL); | 91 | dev->nls = netlink_kernel_create(NETLINK_W1, NULL, THIS_MODULE); |
| 92 | if (!dev->nls) { | 92 | if (!dev->nls) { |
| 93 | printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n", | 93 | printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n", |
| 94 | NETLINK_NFLOG, dev->dev.bus_id); | 94 | NETLINK_NFLOG, dev->dev.bus_id); |
| @@ -225,3 +225,5 @@ void w1_remove_master_device(struct w1_bus_master *bm) | |||
| 225 | 225 | ||
| 226 | EXPORT_SYMBOL(w1_add_master_device); | 226 | EXPORT_SYMBOL(w1_add_master_device); |
| 227 | EXPORT_SYMBOL(w1_remove_master_device); | 227 | EXPORT_SYMBOL(w1_remove_master_device); |
| 228 | |||
| 229 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_W1); | ||
diff --git a/include/linux/net.h b/include/linux/net.h index 20cb226b2268..39906619b9d7 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
| @@ -282,5 +282,8 @@ static struct proto_ops name##_ops = { \ | |||
| 282 | #define MODULE_ALIAS_NETPROTO(proto) \ | 282 | #define MODULE_ALIAS_NETPROTO(proto) \ |
| 283 | MODULE_ALIAS("net-pf-" __stringify(proto)) | 283 | MODULE_ALIAS("net-pf-" __stringify(proto)) |
| 284 | 284 | ||
| 285 | #define MODULE_ALIAS_NET_PF_PROTO(pf, proto) \ | ||
| 286 | MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto)) | ||
| 287 | |||
| 285 | #endif /* __KERNEL__ */ | 288 | #endif /* __KERNEL__ */ |
| 286 | #endif /* _LINUX_NET_H */ | 289 | #endif /* _LINUX_NET_H */ |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 6552b71bfa73..1c50fea8995b 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -117,7 +117,7 @@ struct netlink_skb_parms | |||
| 117 | #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) | 117 | #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) |
| 118 | 118 | ||
| 119 | 119 | ||
| 120 | extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)); | 120 | extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct module *module); |
| 121 | extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); | 121 | extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); |
| 122 | extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); | 122 | extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); |
| 123 | extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, | 123 | extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, |
diff --git a/kernel/audit.c b/kernel/audit.c index ef35166fdc29..ed4019563d56 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -514,7 +514,8 @@ static int __init audit_init(void) | |||
| 514 | { | 514 | { |
| 515 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", | 515 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", |
| 516 | audit_default ? "enabled" : "disabled"); | 516 | audit_default ? "enabled" : "disabled"); |
| 517 | audit_sock = netlink_kernel_create(NETLINK_AUDIT, audit_receive); | 517 | audit_sock = netlink_kernel_create(NETLINK_AUDIT, audit_receive, |
| 518 | THIS_MODULE); | ||
| 518 | if (!audit_sock) | 519 | if (!audit_sock) |
| 519 | audit_panic("cannot initialize netlink socket"); | 520 | audit_panic("cannot initialize netlink socket"); |
| 520 | 521 | ||
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 8e49d21057e4..88f4d746aa05 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
| @@ -153,7 +153,8 @@ EXPORT_SYMBOL_GPL(kobject_uevent_atomic); | |||
| 153 | 153 | ||
| 154 | static int __init kobject_uevent_init(void) | 154 | static int __init kobject_uevent_init(void) |
| 155 | { | 155 | { |
| 156 | uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, NULL); | 156 | uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, NULL, |
| 157 | THIS_MODULE); | ||
| 157 | 158 | ||
| 158 | if (!uevent_sock) { | 159 | if (!uevent_sock) { |
| 159 | printk(KERN_ERR | 160 | printk(KERN_ERR |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 01af4fcef26d..561d75c8ed5a 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
| @@ -258,7 +258,7 @@ static int __init init(void) | |||
| 258 | spin_lock_init(&ulog_buffers[i].lock); | 258 | spin_lock_init(&ulog_buffers[i].lock); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL); | 261 | ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL, THIS_MODULE); |
| 262 | if (!ebtulognl) | 262 | if (!ebtulognl) |
| 263 | ret = -ENOMEM; | 263 | ret = -ENOMEM; |
| 264 | else if ((ret = ebt_register_watcher(&ulog))) | 264 | else if ((ret = ebt_register_watcher(&ulog))) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4b1bb30e6381..9b3c61f1a37d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -708,7 +708,7 @@ void __init rtnetlink_init(void) | |||
| 708 | if (!rta_buf) | 708 | if (!rta_buf) |
| 709 | panic("rtnetlink_init: cannot allocate rta_buf\n"); | 709 | panic("rtnetlink_init: cannot allocate rta_buf\n"); |
| 710 | 710 | ||
| 711 | rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv); | 711 | rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv, THIS_MODULE); |
| 712 | if (rtnl == NULL) | 712 | if (rtnl == NULL) |
| 713 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); | 713 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); |
| 714 | netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); | 714 | netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 284a9998e53d..3068fddb2da3 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
| @@ -138,7 +138,8 @@ static int __init init(void) | |||
| 138 | { | 138 | { |
| 139 | int rv = 0; | 139 | int rv = 0; |
| 140 | 140 | ||
| 141 | dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, dnrmg_receive_user_sk); | 141 | dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, dnrmg_receive_user_sk, |
| 142 | THIS_MODULE); | ||
| 142 | if (dnrmg == NULL) { | 143 | if (dnrmg == NULL) { |
| 143 | printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); | 144 | printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); |
| 144 | return -ENOMEM; | 145 | return -ENOMEM; |
| @@ -162,6 +163,7 @@ static void __exit fini(void) | |||
| 162 | MODULE_DESCRIPTION("DECnet Routing Message Grabulator"); | 163 | MODULE_DESCRIPTION("DECnet Routing Message Grabulator"); |
| 163 | MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>"); | 164 | MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>"); |
| 164 | MODULE_LICENSE("GPL"); | 165 | MODULE_LICENSE("GPL"); |
| 166 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DNRTMSG); | ||
| 165 | 167 | ||
| 166 | module_init(init); | 168 | module_init(init); |
| 167 | module_exit(fini); | 169 | module_exit(fini); |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index e5722084239b..b5e2f1550c91 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -567,7 +567,7 @@ static void nl_fib_input(struct sock *sk, int len) | |||
| 567 | 567 | ||
| 568 | static void nl_fib_lookup_init(void) | 568 | static void nl_fib_lookup_init(void) |
| 569 | { | 569 | { |
| 570 | netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input); | 570 | netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input, THIS_MODULE); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | static void fib_disable_ip(struct net_device *dev, int force) | 573 | static void fib_disable_ip(struct net_device *dev, int force) |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index ae975ac59c6a..b237f7fcad92 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -692,7 +692,8 @@ init_or_cleanup(int init) | |||
| 692 | goto cleanup; | 692 | goto cleanup; |
| 693 | 693 | ||
| 694 | netlink_register_notifier(&ipq_nl_notifier); | 694 | netlink_register_notifier(&ipq_nl_notifier); |
| 695 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, ipq_rcv_sk); | 695 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, ipq_rcv_sk, |
| 696 | THIS_MODULE); | ||
| 696 | if (ipqnl == NULL) { | 697 | if (ipqnl == NULL) { |
| 697 | printk(KERN_ERR "ip_queue: failed to create netlink socket\n"); | 698 | printk(KERN_ERR "ip_queue: failed to create netlink socket\n"); |
| 698 | goto cleanup_netlink_notifier; | 699 | goto cleanup_netlink_notifier; |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 52a0076302a7..4ea8371ab270 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | MODULE_LICENSE("GPL"); | 62 | MODULE_LICENSE("GPL"); |
| 63 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); | 63 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); |
| 64 | MODULE_DESCRIPTION("iptables userspace logging module"); | 64 | MODULE_DESCRIPTION("iptables userspace logging module"); |
| 65 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); | ||
| 65 | 66 | ||
| 66 | #define ULOG_NL_EVENT 111 /* Harald's favorite number */ | 67 | #define ULOG_NL_EVENT 111 /* Harald's favorite number */ |
| 67 | #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ | 68 | #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ |
| @@ -372,7 +373,7 @@ static int __init init(void) | |||
| 372 | ulog_buffers[i].timer.data = i; | 373 | ulog_buffers[i].timer.data = i; |
| 373 | } | 374 | } |
| 374 | 375 | ||
| 375 | nflognl = netlink_kernel_create(NETLINK_NFLOG, NULL); | 376 | nflognl = netlink_kernel_create(NETLINK_NFLOG, NULL, THIS_MODULE); |
| 376 | if (!nflognl) | 377 | if (!nflognl) |
| 377 | return -ENOMEM; | 378 | return -ENOMEM; |
| 378 | 379 | ||
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index f66945cb158f..f79bd11a4701 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
| @@ -774,7 +774,8 @@ static void tcpdiag_rcv(struct sock *sk, int len) | |||
| 774 | 774 | ||
| 775 | static int __init tcpdiag_init(void) | 775 | static int __init tcpdiag_init(void) |
| 776 | { | 776 | { |
| 777 | tcpnl = netlink_kernel_create(NETLINK_TCPDIAG, tcpdiag_rcv); | 777 | tcpnl = netlink_kernel_create(NETLINK_TCPDIAG, tcpdiag_rcv, |
| 778 | THIS_MODULE); | ||
| 778 | if (tcpnl == NULL) | 779 | if (tcpnl == NULL) |
| 779 | return -ENOMEM; | 780 | return -ENOMEM; |
| 780 | return 0; | 781 | return 0; |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 7130603a32c5..1c3d247a22cc 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
| @@ -685,7 +685,7 @@ init_or_cleanup(int init) | |||
| 685 | goto cleanup; | 685 | goto cleanup; |
| 686 | 686 | ||
| 687 | netlink_register_notifier(&ipq_nl_notifier); | 687 | netlink_register_notifier(&ipq_nl_notifier); |
| 688 | ipqnl = netlink_kernel_create(NETLINK_IP6_FW, ipq_rcv_sk); | 688 | ipqnl = netlink_kernel_create(NETLINK_IP6_FW, ipq_rcv_sk, THIS_MODULE); |
| 689 | if (ipqnl == NULL) { | 689 | if (ipqnl == NULL) { |
| 690 | printk(KERN_ERR "ip6_queue: failed to create netlink socket\n"); | 690 | printk(KERN_ERR "ip6_queue: failed to create netlink socket\n"); |
| 691 | goto cleanup_netlink_notifier; | 691 | goto cleanup_netlink_notifier; |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index b0ed57981847..6210ca42166c 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
| @@ -38,6 +38,8 @@ | |||
| 38 | #include <linux/netfilter/nfnetlink.h> | 38 | #include <linux/netfilter/nfnetlink.h> |
| 39 | 39 | ||
| 40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
| 41 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
| 42 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER); | ||
| 41 | 43 | ||
| 42 | static char __initdata nfversion[] = "0.30"; | 44 | static char __initdata nfversion[] = "0.30"; |
| 43 | 45 | ||
| @@ -324,7 +326,8 @@ int __init nfnetlink_init(void) | |||
| 324 | { | 326 | { |
| 325 | printk("Netfilter messages via NETLINK v%s.\n", nfversion); | 327 | printk("Netfilter messages via NETLINK v%s.\n", nfversion); |
| 326 | 328 | ||
| 327 | nfnl = netlink_kernel_create(NETLINK_NETFILTER, nfnetlink_rcv); | 329 | nfnl = netlink_kernel_create(NETLINK_NETFILTER, nfnetlink_rcv, |
| 330 | THIS_MODULE); | ||
| 328 | if (!nfnl) { | 331 | if (!nfnl) { |
| 329 | printk(KERN_ERR "cannot initialize nfnetlink!\n"); | 332 | printk(KERN_ERR "cannot initialize nfnetlink!\n"); |
| 330 | return -1; | 333 | return -1; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ff774a06c89d..5d487cd69c8c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -13,7 +13,12 @@ | |||
| 13 | * added netlink_proto_exit | 13 | * added netlink_proto_exit |
| 14 | * Tue Jan 22 18:32:44 BRST 2002 Arnaldo C. de Melo <acme@conectiva.com.br> | 14 | * Tue Jan 22 18:32:44 BRST 2002 Arnaldo C. de Melo <acme@conectiva.com.br> |
| 15 | * use nlk_sk, as sk->protinfo is on a diet 8) | 15 | * use nlk_sk, as sk->protinfo is on a diet 8) |
| 16 | * | 16 | * Fri Jul 22 19:51:12 MEST 2005 Harald Welte <laforge@gnumonks.org> |
| 17 | * - inc module use count of module that owns | ||
| 18 | * the kernel socket in case userspace opens | ||
| 19 | * socket of same protocol | ||
| 20 | * - remove all module support, since netlink is | ||
| 21 | * mandatory if CONFIG_NET=y these days | ||
| 17 | */ | 22 | */ |
| 18 | 23 | ||
| 19 | #include <linux/config.h> | 24 | #include <linux/config.h> |
| @@ -92,6 +97,7 @@ struct netlink_table { | |||
| 92 | struct nl_pid_hash hash; | 97 | struct nl_pid_hash hash; |
| 93 | struct hlist_head mc_list; | 98 | struct hlist_head mc_list; |
| 94 | unsigned int nl_nonroot; | 99 | unsigned int nl_nonroot; |
| 100 | struct proto_ops *p_ops; | ||
| 95 | }; | 101 | }; |
| 96 | 102 | ||
| 97 | static struct netlink_table *nl_table; | 103 | static struct netlink_table *nl_table; |
| @@ -341,7 +347,21 @@ static int netlink_create(struct socket *sock, int protocol) | |||
| 341 | if (protocol<0 || protocol >= MAX_LINKS) | 347 | if (protocol<0 || protocol >= MAX_LINKS) |
| 342 | return -EPROTONOSUPPORT; | 348 | return -EPROTONOSUPPORT; |
| 343 | 349 | ||
| 344 | sock->ops = &netlink_ops; | 350 | netlink_table_grab(); |
| 351 | if (!nl_table[protocol].hash.entries) { | ||
| 352 | #ifdef CONFIG_KMOD | ||
| 353 | /* We do 'best effort'. If we find a matching module, | ||
| 354 | * it is loaded. If not, we don't return an error to | ||
| 355 | * allow pure userspace<->userspace communication. -HW | ||
| 356 | */ | ||
| 357 | netlink_table_ungrab(); | ||
| 358 | request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); | ||
| 359 | netlink_table_grab(); | ||
| 360 | #endif | ||
| 361 | } | ||
| 362 | netlink_table_ungrab(); | ||
| 363 | |||
| 364 | sock->ops = nl_table[protocol].p_ops; | ||
| 345 | 365 | ||
| 346 | sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); | 366 | sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); |
| 347 | if (!sk) | 367 | if (!sk) |
| @@ -394,6 +414,22 @@ static int netlink_release(struct socket *sock) | |||
| 394 | }; | 414 | }; |
| 395 | notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); | 415 | notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); |
| 396 | } | 416 | } |
| 417 | |||
| 418 | /* When this is a kernel socket, we need to remove the owner pointer, | ||
| 419 | * since we don't know whether the module will be dying at any given | ||
| 420 | * point - HW | ||
| 421 | */ | ||
| 422 | if (!nlk->pid) { | ||
| 423 | struct proto_ops *p_tmp; | ||
| 424 | |||
| 425 | netlink_table_grab(); | ||
| 426 | p_tmp = nl_table[sk->sk_protocol].p_ops; | ||
| 427 | if (p_tmp != &netlink_ops) { | ||
| 428 | nl_table[sk->sk_protocol].p_ops = &netlink_ops; | ||
| 429 | kfree(p_tmp); | ||
| 430 | } | ||
| 431 | netlink_table_ungrab(); | ||
| 432 | } | ||
| 397 | 433 | ||
| 398 | sock_put(sk); | 434 | sock_put(sk); |
| 399 | return 0; | 435 | return 0; |
| @@ -1023,8 +1059,9 @@ static void netlink_data_ready(struct sock *sk, int len) | |||
| 1023 | */ | 1059 | */ |
| 1024 | 1060 | ||
| 1025 | struct sock * | 1061 | struct sock * |
| 1026 | netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)) | 1062 | netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len), struct module *module) |
| 1027 | { | 1063 | { |
| 1064 | struct proto_ops *p_ops; | ||
| 1028 | struct socket *sock; | 1065 | struct socket *sock; |
| 1029 | struct sock *sk; | 1066 | struct sock *sk; |
| 1030 | 1067 | ||
| @@ -1034,22 +1071,63 @@ netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)) | |||
| 1034 | if (unit<0 || unit>=MAX_LINKS) | 1071 | if (unit<0 || unit>=MAX_LINKS) |
| 1035 | return NULL; | 1072 | return NULL; |
| 1036 | 1073 | ||
| 1074 | /* Do a quick check, to make us not go down to netlink_insert() | ||
| 1075 | * if protocol already has kernel socket. | ||
| 1076 | */ | ||
| 1077 | sk = netlink_lookup(unit, 0); | ||
| 1078 | if (unlikely(sk)) { | ||
| 1079 | sock_put(sk); | ||
| 1080 | return NULL; | ||
| 1081 | } | ||
| 1082 | |||
| 1037 | if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) | 1083 | if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) |
| 1038 | return NULL; | 1084 | return NULL; |
| 1039 | 1085 | ||
| 1086 | sk = NULL; | ||
| 1087 | if (module) { | ||
| 1088 | /* Every registering protocol implemented in a module needs | ||
| 1089 | * it's own p_ops, since the socket code cannot deal with | ||
| 1090 | * module refcounting otherwise. -HW | ||
| 1091 | */ | ||
| 1092 | p_ops = kmalloc(sizeof(*p_ops), GFP_KERNEL); | ||
| 1093 | if (!p_ops) | ||
| 1094 | goto out_sock_release; | ||
| 1095 | |||
| 1096 | memcpy(p_ops, &netlink_ops, sizeof(*p_ops)); | ||
| 1097 | p_ops->owner = module; | ||
| 1098 | } else | ||
| 1099 | p_ops = &netlink_ops; | ||
| 1100 | |||
| 1101 | netlink_table_grab(); | ||
| 1102 | nl_table[unit].p_ops = p_ops; | ||
| 1103 | netlink_table_ungrab(); | ||
| 1104 | |||
| 1040 | if (netlink_create(sock, unit) < 0) { | 1105 | if (netlink_create(sock, unit) < 0) { |
| 1041 | sock_release(sock); | 1106 | sk = NULL; |
| 1042 | return NULL; | 1107 | goto out_kfree_p_ops; |
| 1043 | } | 1108 | } |
| 1109 | |||
| 1044 | sk = sock->sk; | 1110 | sk = sock->sk; |
| 1045 | sk->sk_data_ready = netlink_data_ready; | 1111 | sk->sk_data_ready = netlink_data_ready; |
| 1046 | if (input) | 1112 | if (input) |
| 1047 | nlk_sk(sk)->data_ready = input; | 1113 | nlk_sk(sk)->data_ready = input; |
| 1048 | 1114 | ||
| 1049 | if (netlink_insert(sk, 0)) { | 1115 | if (netlink_insert(sk, 0)) { |
| 1050 | sock_release(sock); | 1116 | sk = NULL; |
| 1051 | return NULL; | 1117 | goto out_kfree_p_ops; |
| 1118 | } | ||
| 1119 | |||
| 1120 | return sk; | ||
| 1121 | |||
| 1122 | out_kfree_p_ops: | ||
| 1123 | netlink_table_grab(); | ||
| 1124 | if (nl_table[unit].p_ops != &netlink_ops) { | ||
| 1125 | kfree(nl_table[unit].p_ops); | ||
| 1126 | nl_table[unit].p_ops = &netlink_ops; | ||
| 1052 | } | 1127 | } |
| 1128 | netlink_table_ungrab(); | ||
| 1129 | out_sock_release: | ||
| 1130 | sock_release(sock); | ||
| 1053 | return sk; | 1131 | return sk; |
| 1054 | } | 1132 | } |
| 1055 | 1133 | ||
| @@ -1413,6 +1491,8 @@ enomem: | |||
| 1413 | for (i = 0; i < MAX_LINKS; i++) { | 1491 | for (i = 0; i < MAX_LINKS; i++) { |
| 1414 | struct nl_pid_hash *hash = &nl_table[i].hash; | 1492 | struct nl_pid_hash *hash = &nl_table[i].hash; |
| 1415 | 1493 | ||
| 1494 | nl_table[i].p_ops = &netlink_ops; | ||
| 1495 | |||
| 1416 | hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table)); | 1496 | hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table)); |
| 1417 | if (!hash->table) { | 1497 | if (!hash->table) { |
| 1418 | while (i-- > 0) | 1498 | while (i-- > 0) |
| @@ -1438,21 +1518,7 @@ out: | |||
| 1438 | return err; | 1518 | return err; |
| 1439 | } | 1519 | } |
| 1440 | 1520 | ||
| 1441 | static void __exit netlink_proto_exit(void) | ||
| 1442 | { | ||
| 1443 | sock_unregister(PF_NETLINK); | ||
| 1444 | proc_net_remove("netlink"); | ||
| 1445 | kfree(nl_table); | ||
| 1446 | nl_table = NULL; | ||
| 1447 | proto_unregister(&netlink_proto); | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | core_initcall(netlink_proto_init); | 1521 | core_initcall(netlink_proto_init); |
| 1451 | module_exit(netlink_proto_exit); | ||
| 1452 | |||
| 1453 | MODULE_LICENSE("GPL"); | ||
| 1454 | |||
| 1455 | MODULE_ALIAS_NETPROTO(PF_NETLINK); | ||
| 1456 | 1522 | ||
| 1457 | EXPORT_SYMBOL(netlink_ack); | 1523 | EXPORT_SYMBOL(netlink_ack); |
| 1458 | EXPORT_SYMBOL(netlink_broadcast); | 1524 | EXPORT_SYMBOL(netlink_broadcast); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8da3e25b2c4c..33ceeea783b1 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -1519,7 +1519,8 @@ static int __init xfrm_user_init(void) | |||
| 1519 | { | 1519 | { |
| 1520 | printk(KERN_INFO "Initializing IPsec netlink socket\n"); | 1520 | printk(KERN_INFO "Initializing IPsec netlink socket\n"); |
| 1521 | 1521 | ||
| 1522 | xfrm_nl = netlink_kernel_create(NETLINK_XFRM, xfrm_netlink_rcv); | 1522 | xfrm_nl = netlink_kernel_create(NETLINK_XFRM, xfrm_netlink_rcv, |
| 1523 | THIS_MODULE); | ||
| 1523 | if (xfrm_nl == NULL) | 1524 | if (xfrm_nl == NULL) |
| 1524 | return -ENOMEM; | 1525 | return -ENOMEM; |
| 1525 | 1526 | ||
| @@ -1537,3 +1538,4 @@ static void __exit xfrm_user_exit(void) | |||
| 1537 | module_init(xfrm_user_init); | 1538 | module_init(xfrm_user_init); |
| 1538 | module_exit(xfrm_user_exit); | 1539 | module_exit(xfrm_user_exit); |
| 1539 | MODULE_LICENSE("GPL"); | 1540 | MODULE_LICENSE("GPL"); |
| 1541 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_XFRM); | ||
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index 18d08acafa78..341dbe2579be 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c | |||
| @@ -103,7 +103,7 @@ void selnl_notify_policyload(u32 seqno) | |||
| 103 | 103 | ||
| 104 | static int __init selnl_init(void) | 104 | static int __init selnl_init(void) |
| 105 | { | 105 | { |
| 106 | selnl = netlink_kernel_create(NETLINK_SELINUX, NULL); | 106 | selnl = netlink_kernel_create(NETLINK_SELINUX, NULL, THIS_MODULE); |
| 107 | if (selnl == NULL) | 107 | if (selnl == NULL) |
| 108 | panic("SELinux: Cannot create netlink socket."); | 108 | panic("SELinux: Cannot create netlink socket."); |
| 109 | netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); | 109 | netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); |
