mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
2.3 KiB
121 lines
2.3 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* Netlink event notifications for SELinux. |
|
* |
|
* Author: James Morris <[email protected]> |
|
* |
|
* Copyright (C) 2004 Red Hat, Inc., James Morris <[email protected]> |
|
*/ |
|
#include <linux/init.h> |
|
#include <linux/types.h> |
|
#include <linux/slab.h> |
|
#include <linux/stddef.h> |
|
#include <linux/kernel.h> |
|
#include <linux/export.h> |
|
#include <linux/skbuff.h> |
|
#include <linux/selinux_netlink.h> |
|
#include <net/net_namespace.h> |
|
#include <net/netlink.h> |
|
|
|
#include "security.h" |
|
|
|
static struct sock *selnl __ro_after_init; |
|
|
|
static int selnl_msglen(int msgtype) |
|
{ |
|
int ret = 0; |
|
|
|
switch (msgtype) { |
|
case SELNL_MSG_SETENFORCE: |
|
ret = sizeof(struct selnl_msg_setenforce); |
|
break; |
|
|
|
case SELNL_MSG_POLICYLOAD: |
|
ret = sizeof(struct selnl_msg_policyload); |
|
break; |
|
|
|
default: |
|
BUG(); |
|
} |
|
return ret; |
|
} |
|
|
|
static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *data) |
|
{ |
|
switch (msgtype) { |
|
case SELNL_MSG_SETENFORCE: { |
|
struct selnl_msg_setenforce *msg = nlmsg_data(nlh); |
|
|
|
memset(msg, 0, len); |
|
msg->val = *((int *)data); |
|
break; |
|
} |
|
|
|
case SELNL_MSG_POLICYLOAD: { |
|
struct selnl_msg_policyload *msg = nlmsg_data(nlh); |
|
|
|
memset(msg, 0, len); |
|
msg->seqno = *((u32 *)data); |
|
break; |
|
} |
|
|
|
default: |
|
BUG(); |
|
} |
|
} |
|
|
|
static void selnl_notify(int msgtype, void *data) |
|
{ |
|
int len; |
|
sk_buff_data_t tmp; |
|
struct sk_buff *skb; |
|
struct nlmsghdr *nlh; |
|
|
|
len = selnl_msglen(msgtype); |
|
|
|
skb = nlmsg_new(len, GFP_USER); |
|
if (!skb) |
|
goto oom; |
|
|
|
tmp = skb->tail; |
|
nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0); |
|
if (!nlh) |
|
goto out_kfree_skb; |
|
selnl_add_payload(nlh, len, msgtype, data); |
|
nlh->nlmsg_len = skb->tail - tmp; |
|
NETLINK_CB(skb).dst_group = SELNLGRP_AVC; |
|
netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER); |
|
out: |
|
return; |
|
|
|
out_kfree_skb: |
|
kfree_skb(skb); |
|
oom: |
|
pr_err("SELinux: OOM in %s\n", __func__); |
|
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) |
|
{ |
|
struct netlink_kernel_cfg cfg = { |
|
.groups = SELNLGRP_MAX, |
|
.flags = NL_CFG_F_NONROOT_RECV, |
|
}; |
|
|
|
selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, &cfg); |
|
if (selnl == NULL) |
|
panic("SELinux: Cannot create netlink socket."); |
|
return 0; |
|
} |
|
|
|
__initcall(selnl_init);
|
|
|