* Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* <dgoeddel@trustedcs.com>
+ * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
+ * Paul Moore, <paul.moore@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sysctl.h>
#include <linux/audit.h>
#include <linux/string.h>
+#include <linux/selinux.h>
#include "avc.h"
#include "objsec.h"
#include "netif.h"
#include "xfrm.h"
+#include "selinux_netlabel.h"
#define XATTR_SELINUX_SUFFIX "selinux"
#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
sbsec->sb = sb;
sbsec->sid = SECINITSID_UNLABELED;
sbsec->def_sid = SECINITSID_FILE;
+ sbsec->mntpoint_sid = SECINITSID_UNLABELED;
sb->s_security = sbsec;
return 0;
{
struct sk_security_struct *ssec;
- if (family != PF_UNIX)
- return 0;
-
ssec = kzalloc(sizeof(*ssec), priority);
if (!ssec)
return -ENOMEM;
ssec->sk = sk;
ssec->peer_sid = SECINITSID_UNLABELED;
+ ssec->sid = SECINITSID_UNLABELED;
sk->sk_security = ssec;
return 0;
{
struct sk_security_struct *ssec = sk->sk_security;
- if (sk->sk_family != PF_UNIX)
- return;
-
sk->sk_security = NULL;
kfree(ssec);
}
Opt_context = 1,
Opt_fscontext = 2,
Opt_defcontext = 4,
+ Opt_rootcontext = 8,
};
static match_table_t tokens = {
{Opt_context, "context=%s"},
{Opt_fscontext, "fscontext=%s"},
{Opt_defcontext, "defcontext=%s"},
+ {Opt_rootcontext, "rootcontext=%s"},
};
#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
+static int may_context_mount_sb_relabel(u32 sid,
+ struct superblock_security_struct *sbsec,
+ struct task_security_struct *tsec)
+{
+ int rc;
+
+ rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELFROM, NULL);
+ if (rc)
+ return rc;
+
+ rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELTO, NULL);
+ return rc;
+}
+
+static int may_context_mount_inode_relabel(u32 sid,
+ struct superblock_security_struct *sbsec,
+ struct task_security_struct *tsec)
+{
+ int rc;
+ rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__RELABELFROM, NULL);
+ if (rc)
+ return rc;
+
+ rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
+ FILESYSTEM__ASSOCIATE, NULL);
+ return rc;
+}
+
static int try_context_mount(struct super_block *sb, void *data)
{
char *context = NULL, *defcontext = NULL;
+ char *fscontext = NULL, *rootcontext = NULL;
const char *name;
u32 sid;
int alloc = 0, rc = 0, seen = 0;
switch (token) {
case Opt_context:
- if (seen) {
+ if (seen & (Opt_context|Opt_defcontext)) {
rc = -EINVAL;
printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
goto out_free;
break;
case Opt_fscontext:
- if (seen & (Opt_context|Opt_fscontext)) {
+ if (seen & Opt_fscontext) {
rc = -EINVAL;
printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
goto out_free;
}
- context = match_strdup(&args[0]);
- if (!context) {
+ fscontext = match_strdup(&args[0]);
+ if (!fscontext) {
rc = -ENOMEM;
goto out_free;
}
seen |= Opt_fscontext;
break;
+ case Opt_rootcontext:
+ if (seen & Opt_rootcontext) {
+ rc = -EINVAL;
+ printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
+ goto out_free;
+ }
+ rootcontext = match_strdup(&args[0]);
+ if (!rootcontext) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+ if (!alloc)
+ alloc = 1;
+ seen |= Opt_rootcontext;
+ break;
+
case Opt_defcontext:
if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
rc = -EINVAL;
if (!seen)
goto out;
+ /* sets the context of the superblock for the fs being mounted. */
+ if (fscontext) {
+ rc = security_context_to_sid(fscontext, strlen(fscontext), &sid);
+ if (rc) {
+ printk(KERN_WARNING "SELinux: security_context_to_sid"
+ "(%s) failed for (dev %s, type %s) errno=%d\n",
+ fscontext, sb->s_id, name, rc);
+ goto out_free;
+ }
+
+ rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
+ if (rc)
+ goto out_free;
+
+ sbsec->sid = sid;
+ }
+
+ /*
+ * Switch to using mount point labeling behavior.
+ * sets the label used on all file below the mountpoint, and will set
+ * the superblock context if not already set.
+ */
if (context) {
rc = security_context_to_sid(context, strlen(context), &sid);
if (rc) {
goto out_free;
}
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELFROM, NULL);
- if (rc)
+ if (!fscontext) {
+ rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
+ if (rc)
+ goto out_free;
+ sbsec->sid = sid;
+ } else {
+ rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
+ if (rc)
+ goto out_free;
+ }
+ sbsec->mntpoint_sid = sid;
+
+ sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+ }
+
+ if (rootcontext) {
+ struct inode *inode = sb->s_root->d_inode;
+ struct inode_security_struct *isec = inode->i_security;
+ rc = security_context_to_sid(rootcontext, strlen(rootcontext), &sid);
+ if (rc) {
+ printk(KERN_WARNING "SELinux: security_context_to_sid"
+ "(%s) failed for (dev %s, type %s) errno=%d\n",
+ rootcontext, sb->s_id, name, rc);
goto out_free;
+ }
- rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELTO, NULL);
+ rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
if (rc)
goto out_free;
- sbsec->sid = sid;
-
- if (seen & Opt_context)
- sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+ isec->sid = sid;
+ isec->initialized = 1;
}
if (defcontext) {
if (sid == sbsec->def_sid)
goto out_free;
- rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__RELABELFROM, NULL);
- if (rc)
- goto out_free;
-
- rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
- FILESYSTEM__ASSOCIATE, NULL);
+ rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
if (rc)
goto out_free;
if (alloc) {
kfree(context);
kfree(defcontext);
+ kfree(fscontext);
+ kfree(rootcontext);
}
out:
return rc;
goto out;
isec->sid = sid;
break;
+ case SECURITY_FS_USE_MNTPOINT:
+ isec->sid = sbsec->mntpoint_sid;
+ break;
default:
- /* Default to the fs SID. */
+ /* Default to the fs superblock SID. */
isec->sid = sbsec->sid;
if (sbsec->proc) {
/* Default to the current task SID. */
bsec->sid = tsec->sid;
- /* Reset create and sockcreate SID on execve. */
+ /* Reset fs, key, and sock SIDs on execve. */
tsec->create_sid = 0;
+ tsec->keycreate_sid = 0;
tsec->sockcreate_sid = 0;
if (tsec->exec_sid) {
{
return (match_prefix("context=", sizeof("context=")-1, option, len) ||
match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
- match_prefix("defcontext=", sizeof("defcontext=")-1, option, len));
+ match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||
+ match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));
}
static inline void take_option(char **to, char *from, int *first, int len)
static int selinux_file_permission(struct file *file, int mask)
{
+ int rc;
struct inode *inode = file->f_dentry->d_inode;
if (!mask) {
if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
mask |= MAY_APPEND;
- return file_has_perm(current, file,
- file_mask_to_av(inode->i_mode, mask));
+ rc = file_has_perm(current, file,
+ file_mask_to_av(inode->i_mode, mask));
+ if (rc)
+ return rc;
+
+ return selinux_netlbl_inode_permission(inode, mask);
}
static int selinux_file_alloc_security(struct file *file)
tsec2->osid = tsec1->osid;
tsec2->sid = tsec1->sid;
- /* Retain the exec, create, and sock SIDs across fork */
+ /* Retain the exec, fs, key, and sock SIDs across fork */
tsec2->exec_sid = tsec1->exec_sid;
tsec2->create_sid = tsec1->create_sid;
+ tsec2->keycreate_sid = tsec1->keycreate_sid;
tsec2->sockcreate_sid = tsec1->sockcreate_sid;
/* Retain ptracer SID across fork, if any.
return task_has_perm(current, p, PROCESS__GETSESSION);
}
+static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
+{
+ selinux_get_task_sid(p, secid);
+}
+
static int selinux_task_setgroups(struct group_info *group_info)
{
/* See the comment for setuid above. */
return task_has_perm(current, p, PROCESS__SETSCHED);
}
+static int selinux_task_getioprio(struct task_struct *p)
+{
+ return task_has_perm(current, p, PROCESS__GETSCHED);
+}
+
static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
{
struct rlimit *old_rlim = current->signal->rlim + resource;
return task_has_perm(current, p, PROCESS__SETSCHED);
}
-static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig)
+static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
{
u32 perm;
int rc;
+ struct task_security_struct *tsec;
- rc = secondary_ops->task_kill(p, info, sig);
+ rc = secondary_ops->task_kill(p, info, sig, secid);
if (rc)
return rc;
perm = PROCESS__SIGNULL; /* null signal; existence test */
else
perm = signal_to_av(sig);
-
- return task_has_perm(current, p, perm);
+ tsec = p->security;
+ if (secid)
+ rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL);
+ else
+ rc = task_has_perm(current, p, perm);
+ return rc;
}
static int selinux_task_prctl(int option,
return err;
}
-static void selinux_socket_post_create(struct socket *sock, int family,
- int type, int protocol, int kern)
+static int selinux_socket_post_create(struct socket *sock, int family,
+ int type, int protocol, int kern)
{
+ int err = 0;
struct inode_security_struct *isec;
struct task_security_struct *tsec;
+ struct sk_security_struct *sksec;
u32 newsid;
isec = SOCK_INODE(sock)->i_security;
isec->sid = kern ? SECINITSID_KERNEL : newsid;
isec->initialized = 1;
- return;
+ if (sock->sk) {
+ sksec = sock->sk->sk_security;
+ sksec->sid = isec->sid;
+ err = selinux_netlbl_socket_post_create(sock,
+ family,
+ isec->sid);
+ }
+
+ return err;
}
/* Range of port numbers used to automatically bind.
static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
int size)
{
- return socket_has_perm(current, sock, SOCKET__WRITE);
+ int rc;
+
+ rc = socket_has_perm(current, sock, SOCKET__WRITE);
+ if (rc)
+ return rc;
+
+ return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
}
static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
/* server child socket */
ssec = newsk->sk_security;
ssec->peer_sid = isec->sid;
-
- return 0;
+ err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid);
+
+ return err;
}
static int selinux_socket_unix_may_send(struct socket *sock,
}
static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
- struct avc_audit_data *ad, u32 sock_sid, u16 sock_class,
- u16 family, char *addrp, int len)
+ struct avc_audit_data *ad, u16 family, char *addrp, int len)
{
int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
+ struct socket *sock;
+ u16 sock_class = 0;
+ u32 sock_sid = 0;
+
+ read_lock_bh(&sk->sk_callback_lock);
+ sock = sk->sk_socket;
+ if (sock) {
+ struct inode *inode;
+ inode = SOCK_INODE(sock);
+ if (inode) {
+ struct inode_security_struct *isec;
+ isec = inode->i_security;
+ sock_sid = isec->sid;
+ sock_class = isec->sclass;
+ }
+ }
+ read_unlock_bh(&sk->sk_callback_lock);
+ if (!sock_sid)
+ goto out;
if (!skb->dev)
goto out;
static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
u16 family;
- u16 sock_class = 0;
char *addrp;
int len, err = 0;
- u32 sock_sid = 0;
- struct socket *sock;
struct avc_audit_data ad;
+ struct sk_security_struct *sksec = sk->sk_security;
family = sk->sk_family;
if (family != PF_INET && family != PF_INET6)
if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
family = PF_INET;
- read_lock_bh(&sk->sk_callback_lock);
- sock = sk->sk_socket;
- if (sock) {
- struct inode *inode;
- inode = SOCK_INODE(sock);
- if (inode) {
- struct inode_security_struct *isec;
- isec = inode->i_security;
- sock_sid = isec->sid;
- sock_class = isec->sclass;
- }
- }
- read_unlock_bh(&sk->sk_callback_lock);
- if (!sock_sid)
- goto out;
-
AVC_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
ad.u.net.family = family;
goto out;
if (selinux_compat_net)
- err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid,
- sock_class, family,
+ err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family,
addrp, len);
else
- err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET,
+ err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
if (err)
goto out;
- err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+ err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
+ if (err)
+ goto out;
+
+ err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
out:
return err;
}
peer_sid = ssec->peer_sid;
}
else if (isec->sclass == SECCLASS_TCP_SOCKET) {
- peer_sid = selinux_socket_getpeer_stream(sock->sk);
-
+ peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
+ if (peer_sid == SECSID_NULL)
+ peer_sid = selinux_socket_getpeer_stream(sock->sk);
if (peer_sid == SECSID_NULL) {
err = -ENOPROTOOPT;
goto out;
return err;
}
-static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
+static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
{
+ u32 peer_secid = SECSID_NULL;
int err = 0;
- u32 peer_sid = selinux_socket_getpeer_dgram(skb);
- if (peer_sid == SECSID_NULL)
- return -EINVAL;
+ if (sock && (sock->sk->sk_family == PF_UNIX))
+ selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
+ else if (skb) {
+ peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb);
+ if (peer_secid == SECSID_NULL)
+ peer_secid = selinux_socket_getpeer_dgram(skb);
+ }
- err = security_sid_to_context(peer_sid, secdata, seclen);
- if (err)
- return err;
+ if (peer_secid == SECSID_NULL)
+ err = -EINVAL;
+ *secid = peer_secid;
- return 0;
+ return err;
}
-
-
static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
return sk_alloc_security(sk, family, priority);
sk_free_security(sk);
}
-static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
+static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
{
- struct inode_security_struct *isec;
- u32 sock_sid = SECINITSID_ANY_SOCKET;
+ struct sk_security_struct *ssec = sk->sk_security;
+ struct sk_security_struct *newssec = newsk->sk_security;
+ newssec->sid = ssec->sid;
+ newssec->peer_sid = ssec->peer_sid;
+}
+
+static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
+{
if (!sk)
- return selinux_no_sk_sid(fl);
+ *secid = SECINITSID_ANY_SOCKET;
+ else {
+ struct sk_security_struct *sksec = sk->sk_security;
- read_lock_bh(&sk->sk_callback_lock);
- isec = get_sock_isec(sk);
+ *secid = sksec->sid;
+ }
+}
+
+static void selinux_sock_graft(struct sock* sk, struct socket *parent)
+{
+ struct inode_security_struct *isec = SOCK_INODE(parent)->i_security;
+ struct sk_security_struct *sksec = sk->sk_security;
- if (isec)
- sock_sid = isec->sid;
+ isec->sid = sksec->sid;
- read_unlock_bh(&sk->sk_callback_lock);
- return sock_sid;
+ selinux_netlbl_sock_graft(sk, parent);
+}
+
+static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req)
+{
+ struct sk_security_struct *sksec = sk->sk_security;
+ int err;
+ u32 newsid;
+ u32 peersid;
+
+ newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid);
+ if (newsid != SECSID_NULL) {
+ req->secid = newsid;
+ return 0;
+ }
+
+ err = selinux_xfrm_decode_session(skb, &peersid, 0);
+ BUG_ON(err);
+
+ if (peersid == SECSID_NULL) {
+ req->secid = sksec->sid;
+ return 0;
+ }
+
+ err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
+ if (err)
+ return err;
+
+ req->secid = newsid;
+ return 0;
+}
+
+static void selinux_inet_csk_clone(struct sock *newsk,
+ const struct request_sock *req)
+{
+ struct sk_security_struct *newsksec = newsk->sk_security;
+
+ newsksec->sid = req->secid;
+ /* NOTE: Ideally, we should also get the isec->sid for the
+ new socket in sync, but we don't have the isec available yet.
+ So we will wait until sock_graft to do it, by which
+ time it will have been created and available. */
+}
+
+static void selinux_req_classify_flow(const struct request_sock *req,
+ struct flowi *fl)
+{
+ fl->secid = req->secid;
}
static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
#ifdef CONFIG_NETFILTER
static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
- struct inode_security_struct *isec,
struct avc_audit_data *ad,
u16 family, char *addrp, int len)
{
- int err;
+ int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
+ struct socket *sock;
+ struct inode *inode;
+ struct inode_security_struct *isec;
+
+ sock = sk->sk_socket;
+ if (!sock)
+ goto out;
+
+ inode = SOCK_INODE(sock);
+ if (!inode)
+ goto out;
+
+ isec = inode->i_security;
err = sel_netif_sids(dev, &if_sid, NULL);
if (err)
char *addrp;
int len, err = 0;
struct sock *sk;
- struct socket *sock;
- struct inode *inode;
struct sk_buff *skb = *pskb;
- struct inode_security_struct *isec;
struct avc_audit_data ad;
struct net_device *dev = (struct net_device *)out;
+ struct sk_security_struct *sksec;
sk = skb->sk;
if (!sk)
goto out;
- sock = sk->sk_socket;
- if (!sock)
- goto out;
-
- inode = SOCK_INODE(sock);
- if (!inode)
- goto out;
-
- isec = inode->i_security;
+ sksec = sk->sk_security;
AVC_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.netif = dev->name;
goto out;
if (selinux_compat_net)
- err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad,
+ err = selinux_ip_postroute_last_compat(sk, dev, &ad,
family, addrp, len);
else
- err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET,
+ err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
PACKET__SEND, &ad);
if (err)
goto out;
- err = selinux_xfrm_postroute_last(isec->sid, skb);
+ err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad);
out:
return err ? NF_DROP : NF_ACCEPT;
}
static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
{
- struct task_security_struct *tsec;
- struct av_decision avd;
int err;
err = secondary_ops->netlink_send(sk, skb);
if (err)
return err;
- tsec = current->security;
-
- avd.allowed = 0;
- avc_has_perm_noaudit(tsec->sid, tsec->sid,
- SECCLASS_CAPABILITY, ~0, &avd);
- cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
-
if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
err = selinux_nlmsg_perm(sk, skb);
return err;
}
-static int selinux_netlink_recv(struct sk_buff *skb)
+static int selinux_netlink_recv(struct sk_buff *skb, int capability)
{
- if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
- return -EPERM;
- return 0;
+ int err;
+ struct avc_audit_data ad;
+
+ err = secondary_ops->netlink_recv(skb, capability);
+ if (err)
+ return err;
+
+ AVC_AUDIT_DATA_INIT(&ad, CAP);
+ ad.u.cap = capability;
+
+ return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
+ SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad);
}
static int ipc_alloc_security(struct task_struct *task,
return size;
}
+static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return security_sid_to_context(secid, secdata, seclen);
+}
+
+static void selinux_release_secctx(char *secdata, u32 seclen)
+{
+ if (secdata)
+ kfree(secdata);
+}
+
#ifdef CONFIG_KEYS
static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
.task_setpgid = selinux_task_setpgid,
.task_getpgid = selinux_task_getpgid,
.task_getsid = selinux_task_getsid,
+ .task_getsecid = selinux_task_getsecid,
.task_setgroups = selinux_task_setgroups,
.task_setnice = selinux_task_setnice,
.task_setioprio = selinux_task_setioprio,
+ .task_getioprio = selinux_task_getioprio,
.task_setrlimit = selinux_task_setrlimit,
.task_setscheduler = selinux_task_setscheduler,
.task_getscheduler = selinux_task_getscheduler,
.getprocattr = selinux_getprocattr,
.setprocattr = selinux_setprocattr,
+ .secid_to_secctx = selinux_secid_to_secctx,
+ .release_secctx = selinux_release_secctx,
+
.unix_stream_connect = selinux_socket_unix_stream_connect,
.unix_may_send = selinux_socket_unix_may_send,
.socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
.sk_alloc_security = selinux_sk_alloc_security,
.sk_free_security = selinux_sk_free_security,
- .sk_getsid = selinux_sk_getsid_security,
+ .sk_clone_security = selinux_sk_clone_security,
+ .sk_getsecid = selinux_sk_getsecid,
+ .sock_graft = selinux_sock_graft,
+ .inet_conn_request = selinux_inet_conn_request,
+ .inet_csk_clone = selinux_inet_csk_clone,
+ .req_classify_flow = selinux_req_classify_flow,
#ifdef CONFIG_SECURITY_NETWORK_XFRM
.xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
.xfrm_state_free_security = selinux_xfrm_state_free,
.xfrm_state_delete_security = selinux_xfrm_state_delete,
.xfrm_policy_lookup = selinux_xfrm_policy_lookup,
+ .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match,
+ .xfrm_flow_state_match = selinux_xfrm_flow_state_match,
+ .xfrm_decode_session = selinux_xfrm_decode_session,
#endif
#ifdef CONFIG_KEYS