0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/types.h>
0011 #include <linux/slab.h>
0012 #include <linux/stddef.h>
0013 #include <linux/kernel.h>
0014 #include <linux/export.h>
0015 #include <linux/skbuff.h>
0016 #include <linux/selinux_netlink.h>
0017 #include <net/net_namespace.h>
0018 #include <net/netlink.h>
0019
0020 #include "security.h"
0021
0022 static struct sock *selnl __ro_after_init;
0023
0024 static int selnl_msglen(int msgtype)
0025 {
0026 int ret = 0;
0027
0028 switch (msgtype) {
0029 case SELNL_MSG_SETENFORCE:
0030 ret = sizeof(struct selnl_msg_setenforce);
0031 break;
0032
0033 case SELNL_MSG_POLICYLOAD:
0034 ret = sizeof(struct selnl_msg_policyload);
0035 break;
0036
0037 default:
0038 BUG();
0039 }
0040 return ret;
0041 }
0042
0043 static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *data)
0044 {
0045 switch (msgtype) {
0046 case SELNL_MSG_SETENFORCE: {
0047 struct selnl_msg_setenforce *msg = nlmsg_data(nlh);
0048
0049 memset(msg, 0, len);
0050 msg->val = *((int *)data);
0051 break;
0052 }
0053
0054 case SELNL_MSG_POLICYLOAD: {
0055 struct selnl_msg_policyload *msg = nlmsg_data(nlh);
0056
0057 memset(msg, 0, len);
0058 msg->seqno = *((u32 *)data);
0059 break;
0060 }
0061
0062 default:
0063 BUG();
0064 }
0065 }
0066
0067 static void selnl_notify(int msgtype, void *data)
0068 {
0069 int len;
0070 sk_buff_data_t tmp;
0071 struct sk_buff *skb;
0072 struct nlmsghdr *nlh;
0073
0074 len = selnl_msglen(msgtype);
0075
0076 skb = nlmsg_new(len, GFP_USER);
0077 if (!skb)
0078 goto oom;
0079
0080 tmp = skb->tail;
0081 nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0);
0082 if (!nlh)
0083 goto out_kfree_skb;
0084 selnl_add_payload(nlh, len, msgtype, data);
0085 nlh->nlmsg_len = skb->tail - tmp;
0086 NETLINK_CB(skb).dst_group = SELNLGRP_AVC;
0087 netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER);
0088 out:
0089 return;
0090
0091 out_kfree_skb:
0092 kfree_skb(skb);
0093 oom:
0094 pr_err("SELinux: OOM in %s\n", __func__);
0095 goto out;
0096 }
0097
0098 void selnl_notify_setenforce(int val)
0099 {
0100 selnl_notify(SELNL_MSG_SETENFORCE, &val);
0101 }
0102
0103 void selnl_notify_policyload(u32 seqno)
0104 {
0105 selnl_notify(SELNL_MSG_POLICYLOAD, &seqno);
0106 }
0107
0108 static int __init selnl_init(void)
0109 {
0110 struct netlink_kernel_cfg cfg = {
0111 .groups = SELNLGRP_MAX,
0112 .flags = NL_CFG_F_NONROOT_RECV,
0113 };
0114
0115 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, &cfg);
0116 if (selnl == NULL)
0117 panic("SELinux: Cannot create netlink socket.");
0118 return 0;
0119 }
0120
0121 __initcall(selnl_init);