Blame view
security/selinux/netlink.c
2.29 KB
d2912cb15
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c
|
2 3 4 5 6 7 |
/* * Netlink event notifications for SELinux. * * Author: James Morris <jmorris@redhat.com> * * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> |
1da177e4c
|
8 9 10 |
*/ #include <linux/init.h> #include <linux/types.h> |
5a0e3ad6a
|
11 |
#include <linux/slab.h> |
1da177e4c
|
12 13 |
#include <linux/stddef.h> #include <linux/kernel.h> |
44fc7ea0b
|
14 |
#include <linux/export.h> |
1da177e4c
|
15 |
#include <linux/skbuff.h> |
1da177e4c
|
16 |
#include <linux/selinux_netlink.h> |
b4b510290
|
17 |
#include <net/net_namespace.h> |
01f534d0a
|
18 |
#include <net/netlink.h> |
1da177e4c
|
19 |
|
6a3fbe811
|
20 |
#include "security.h" |
1da177e4c
|
21 22 23 24 25 |
static struct sock *selnl; static int selnl_msglen(int msgtype) { int ret = 0; |
c544c028e
|
26 |
|
1da177e4c
|
27 28 29 30 |
switch (msgtype) { case SELNL_MSG_SETENFORCE: ret = sizeof(struct selnl_msg_setenforce); break; |
c544c028e
|
31 |
|
1da177e4c
|
32 33 34 |
case SELNL_MSG_POLICYLOAD: ret = sizeof(struct selnl_msg_policyload); break; |
c544c028e
|
35 |
|
1da177e4c
|
36 37 38 39 40 41 42 43 44 45 |
default: BUG(); } return ret; } static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *data) { switch (msgtype) { case SELNL_MSG_SETENFORCE: { |
01f534d0a
|
46 |
struct selnl_msg_setenforce *msg = nlmsg_data(nlh); |
c544c028e
|
47 |
|
1da177e4c
|
48 49 50 51 |
memset(msg, 0, len); msg->val = *((int *)data); break; } |
c544c028e
|
52 |
|
1da177e4c
|
53 |
case SELNL_MSG_POLICYLOAD: { |
01f534d0a
|
54 |
struct selnl_msg_policyload *msg = nlmsg_data(nlh); |
c544c028e
|
55 |
|
1da177e4c
|
56 57 58 59 60 61 62 63 64 65 66 67 68 |
memset(msg, 0, len); msg->seqno = *((u32 *)data); break; } default: BUG(); } } static void selnl_notify(int msgtype, void *data) { int len; |
27a884dc3
|
69 |
sk_buff_data_t tmp; |
1da177e4c
|
70 71 |
struct sk_buff *skb; struct nlmsghdr *nlh; |
c544c028e
|
72 |
|
1da177e4c
|
73 |
len = selnl_msglen(msgtype); |
c544c028e
|
74 |
|
77954983a
|
75 |
skb = nlmsg_new(len, GFP_USER); |
1da177e4c
|
76 77 78 79 |
if (!skb) goto oom; tmp = skb->tail; |
01f534d0a
|
80 81 82 |
nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0); if (!nlh) goto out_kfree_skb; |
1da177e4c
|
83 84 |
selnl_add_payload(nlh, len, msgtype, data); nlh->nlmsg_len = skb->tail - tmp; |
ac6d439d2
|
85 86 |
NETLINK_CB(skb).dst_group = SELNLGRP_AVC; netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER); |
1da177e4c
|
87 88 |
out: return; |
c544c028e
|
89 |
|
01f534d0a
|
90 |
out_kfree_skb: |
1da177e4c
|
91 92 |
kfree_skb(skb); oom: |
d85a78334
|
93 94 |
pr_err("SELinux: OOM in %s ", __func__); |
1da177e4c
|
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
goto out; } void selnl_notify_setenforce(int val) { selnl_notify(SELNL_MSG_SETENFORCE, &val); } void selnl_notify_policyload(u32 seqno) { selnl_notify(SELNL_MSG_POLICYLOAD, &seqno); } static int __init selnl_init(void) { |
a31f2d17b
|
110 111 |
struct netlink_kernel_cfg cfg = { .groups = SELNLGRP_MAX, |
9785e10ae
|
112 |
.flags = NL_CFG_F_NONROOT_RECV, |
a31f2d17b
|
113 |
}; |
9f00d9776
|
114 |
selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, &cfg); |
1da177e4c
|
115 116 |
if (selnl == NULL) panic("SELinux: Cannot create netlink socket."); |
1da177e4c
|
117 118 119 120 |
return 0; } __initcall(selnl_init); |