cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

netlink.c (2358B)


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