Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34408
b: refs/heads/master
c: 7420ed2
h: refs/heads/master
v: v3
  • Loading branch information
Venkat Yekkirala authored and David S. Miller committed Sep 22, 2006
1 parent 640ba1d commit c9f18f5
Show file tree
Hide file tree
Showing 12 changed files with 1,021 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 96cb8e3313c7a12e026c1ed510522ae6f6023875
refs/heads/master: 7420ed23a4f77480b5b7b3245e5da30dd24b7575
25 changes: 13 additions & 12 deletions trunk/include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,8 @@ struct security_operations {
int (*unix_may_send) (struct socket * sock, struct socket * other);

int (*socket_create) (int family, int type, int protocol, int kern);
void (*socket_post_create) (struct socket * sock, int family,
int type, int protocol, int kern);
int (*socket_post_create) (struct socket * sock, int family,
int type, int protocol, int kern);
int (*socket_bind) (struct socket * sock,
struct sockaddr * address, int addrlen);
int (*socket_connect) (struct socket * sock,
Expand Down Expand Up @@ -2824,13 +2824,13 @@ static inline int security_socket_create (int family, int type,
return security_ops->socket_create(family, type, protocol, kern);
}

static inline void security_socket_post_create(struct socket * sock,
int family,
int type,
int protocol, int kern)
static inline int security_socket_post_create(struct socket * sock,
int family,
int type,
int protocol, int kern)
{
security_ops->socket_post_create(sock, family, type,
protocol, kern);
return security_ops->socket_post_create(sock, family, type,
protocol, kern);
}

static inline int security_socket_bind(struct socket * sock,
Expand Down Expand Up @@ -2982,11 +2982,12 @@ static inline int security_socket_create (int family, int type,
return 0;
}

static inline void security_socket_post_create(struct socket * sock,
int family,
int type,
int protocol, int kern)
static inline int security_socket_post_create(struct socket * sock,
int family,
int type,
int protocol, int kern)
{
return 0;
}

static inline int security_socket_bind(struct socket * sock,
Expand Down
13 changes: 11 additions & 2 deletions trunk/net/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,11 +973,18 @@ int sock_create_lite(int family, int type, int protocol, struct socket **res)
goto out;
}

security_socket_post_create(sock, family, type, protocol, 1);
sock->type = type;
err = security_socket_post_create(sock, family, type, protocol, 1);
if (err)
goto out_release;

out:
*res = sock;
return err;
out_release:
sock_release(sock);
sock = NULL;
goto out;
}

/* No kernel lock held - perfect */
Expand Down Expand Up @@ -1214,7 +1221,9 @@ static int __sock_create(int family, int type, int protocol, struct socket **res
*/
module_put(net_families[family]->owner);
*res = sock;
security_socket_post_create(sock, family, type, protocol, kern);
err = security_socket_post_create(sock, family, type, protocol, kern);
if (err)
goto out_release;

out:
net_family_read_unlock();
Expand Down
6 changes: 3 additions & 3 deletions trunk/security/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,10 @@ static int dummy_socket_create (int family, int type,
return 0;
}

static void dummy_socket_post_create (struct socket *sock, int family, int type,
int protocol, int kern)
static int dummy_socket_post_create (struct socket *sock, int family, int type,
int protocol, int kern)
{
return;
return 0;
}

static int dummy_socket_bind (struct socket *sock, struct sockaddr *address,
Expand Down
56 changes: 45 additions & 11 deletions trunk/security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
* 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,
Expand Down Expand Up @@ -74,6 +76,7 @@
#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
Expand Down Expand Up @@ -2395,6 +2398,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t

static int selinux_file_permission(struct file *file, int mask)
{
int rc;
struct inode *inode = file->f_dentry->d_inode;

if (!mask) {
Expand All @@ -2406,8 +2410,12 @@ static int selinux_file_permission(struct file *file, int 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)
Expand Down Expand Up @@ -3058,9 +3066,10 @@ static int selinux_socket_create(int family, int type,
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;
Expand All @@ -3077,9 +3086,12 @@ static void selinux_socket_post_create(struct socket *sock, int family,
if (sock->sk) {
sksec = sock->sk->sk_security;
sksec->sid = isec->sid;
err = selinux_netlbl_socket_post_create(sock,
family,
isec->sid);
}

return;
return err;
}

/* Range of port numbers used to automatically bind.
Expand Down Expand Up @@ -3260,7 +3272,13 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
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,
Expand Down Expand Up @@ -3468,6 +3486,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
if (err)
goto out;

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;
Expand All @@ -3491,8 +3513,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
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;
Expand Down Expand Up @@ -3532,8 +3555,11 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *

if (sock && (sock->sk->sk_family == PF_UNIX))
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
else if (skb)
peer_secid = selinux_socket_getpeer_dgram(skb);
else if (skb) {
peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb);
if (peer_secid == SECSID_NULL)
peer_secid = selinux_socket_getpeer_dgram(skb);
}

if (peer_secid == SECSID_NULL)
err = -EINVAL;
Expand Down Expand Up @@ -3578,16 +3604,24 @@ void selinux_sock_graft(struct sock* sk, struct socket *parent)
struct sk_security_struct *sksec = sk->sk_security;

isec->sid = sksec->sid;

selinux_netlbl_sock_graft(sk, parent);
}

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 = 0;
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);

Expand Down
8 changes: 8 additions & 0 deletions trunk/security/selinux/include/objsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ struct sk_security_struct {
struct sock *sk; /* back pointer to sk object */
u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */
#ifdef CONFIG_NETLABEL
u16 sclass; /* sock security class */
enum { /* NetLabel state */
NLBL_UNSET = 0,
NLBL_REQUIRE,
NLBL_LABELED,
} nlbl_state;
#endif
};

struct key_security_struct {
Expand Down
125 changes: 125 additions & 0 deletions trunk/security/selinux/include/selinux_netlabel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* SELinux interface to the NetLabel subsystem
*
* Author : Paul Moore <paul.moore@hp.com>
*
*/

/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#ifndef _SELINUX_NETLABEL_H_
#define _SELINUX_NETLABEL_H_

#ifdef CONFIG_NETLABEL
void selinux_netlbl_cache_invalidate(void);
int selinux_netlbl_socket_post_create(struct socket *sock,
int sock_family,
u32 sid);
void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock);
u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
struct avc_audit_data *ad);
u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock);
u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb);

int __selinux_netlbl_inode_permission(struct inode *inode, int mask);
/**
* selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
* @inode: the file descriptor's inode
* @mask: the permission mask
*
* Description:
* Looks at a file's inode and if it is marked as a socket protected by
* NetLabel then verify that the socket has been labeled, if not try to label
* the socket now with the inode's SID. Returns zero on success, negative
* values on failure.
*
*/
static inline int selinux_netlbl_inode_permission(struct inode *inode,
int mask)
{
int rc = 0;
struct inode_security_struct *isec;
struct sk_security_struct *sksec;

if (!S_ISSOCK(inode->i_mode))
return 0;

isec = inode->i_security;
sksec = SOCKET_I(inode)->sk->sk_security;
down(&isec->sem);
if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
(mask & (MAY_WRITE | MAY_APPEND))))
rc = __selinux_netlbl_inode_permission(inode, mask);
up(&isec->sem);

return rc;
}
#else
static inline void selinux_netlbl_cache_invalidate(void)
{
return;
}

static inline int selinux_netlbl_socket_post_create(struct socket *sock,
int sock_family,
u32 sid)
{
return 0;
}

static inline void selinux_netlbl_sock_graft(struct sock *sk,
struct socket *sock)
{
return;
}

static inline u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb,
u32 sock_sid)
{
return SECSID_NULL;
}

static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
struct avc_audit_data *ad)
{
return 0;
}

static inline u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
{
return SECSID_NULL;
}

static inline u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
{
return SECSID_NULL;
}

static inline int selinux_netlbl_inode_permission(struct inode *inode,
int mask)
{
return 0;
}
#endif /* CONFIG_NETLABEL */

#endif
Loading

0 comments on commit c9f18f5

Please sign in to comment.