Re: [PATCH] accessfs v0.6 ported to 2.5.35-lsm1 - 1/2

From: Olaf Dietsche (olaf.dietsche--list.linux-security-moduleat_private)
Date: Tue Oct 01 2002 - 02:42:18 PDT

  • Next message: Mike Wray: "Re: graft_tree/attach_mnt rfc"

    Stephen Smalley <sdsat_private> writes:
    
    > However, I understand your point and don't object to your hook, except to
    > suggest that you not pass both the port and the (address, addrlen) pair
    > to it.  You could drop the latter without harm to SELinux, but it would be
    > more general to drop the port and pass the full address.  My only other
    
    Here is the new patch with your suggested interface change.
    
    > concern is whether the kernel developers will object to having a LSM hook
    > in both sys_bind and inet_bind.
    
    Well, we'll never know until we try :-). Besides that, sys_bind() and
    inet_bind() are on an entirely different level.
    
    Regards, Olaf.
    
    diff -urN a/include/linux/security.h b/include/linux/security.h
    --- a/include/linux/security.h	Mon Sep 30 21:57:14 2002
    +++ b/include/linux/security.h	Mon Sep 30 22:10:07 2002
    @@ -784,6 +784,15 @@
      *	A non-zero return value will cause an ICMP parameter problem message to
      *	be generated and transmitted to the sender.  The @pp_ptr parameter may
      *	be used to point to the offending option parameter.
    + * @ip_prot_sock:
    + *	Check, whether this is a protected port.
    + *	Security modules may use this hook to implement fine grained control
    + *	based on the port number.
    + *	@sock contains the socket structure.
    + *	@address contains the address to bind to.
    + *	@addrlen contains the length of address.
    + *	The module should return 0, if permission to access this port is
    + *	granted, -EACCES otherwise.
      *
      * Security hooks for network devices.
      * @netdev_unregister:
    @@ -1351,6 +1360,8 @@
     	void (*ip_decapsulate) (struct sk_buff * skb);
     	int (*ip_decode_options) (struct sk_buff * skb,
     				  const char *optptr, unsigned char **pp_ptr);
    +	int (*ip_prot_sock) (struct socket *sock,
    +			     struct sockaddr *address, int addrlen);
     
     	void (*netdev_unregister) (struct net_device * dev);
     
    @@ -1405,6 +1416,10 @@
     extern int mod_reg_security	(const char *name, struct security_operations *ops);
     extern int mod_unreg_security	(const char *name, struct security_operations *ops);
     extern int capable		(int cap);
    +
    +/* default implementations for use by other security modules */
    +extern int dummy_ip_prot_sock (struct socket *sock,
    +			       struct sockaddr *address, int addrlen);
     
     /* global variables */
     extern struct security_operations *security_ops;
    diff -urN a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
    --- a/net/ipv4/af_inet.c	Wed Sep 18 02:58:46 2002
    +++ b/net/ipv4/af_inet.c	Mon Sep 30 22:00:18 2002
    @@ -531,7 +531,7 @@
     
     	snum = ntohs(addr->sin_port);
     	err = -EACCES;
    -	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
    +	if (security_ops->ip_prot_sock(sock, uaddr, addr_len))
     		goto out;
     
     	/*      We keep a pair of addresses. rcv_saddr is the one
    diff -urN a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
    --- a/net/ipv6/af_inet6.c	Wed Sep 18 02:58:59 2002
    +++ b/net/ipv6/af_inet6.c	Mon Sep 30 22:00:32 2002
    @@ -313,7 +313,7 @@
     	}
     
     	snum = ntohs(addr->sin6_port);
    -	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
    +	if (security_ops->ip_prot_sock(sock, uaddr, addr_len))
     		return -EACCES;
     
     	lock_sock(sk);
    diff -urN a/security/Makefile b/security/Makefile
    --- a/security/Makefile	Mon Sep 30 21:57:14 2002
    +++ b/security/Makefile	Mon Sep 30 22:10:53 2002
    @@ -9,7 +9,7 @@
     subdir-$(CONFIG_LIDS)			+= lids
     
     # Objects that export symbols
    -export-objs	:= security.o
    +export-objs	:= security.o dummy.o
     
     # Object file lists
     obj-y		:= security.o dummy.o
    diff -urN a/security/capability.c b/security/capability.c
    --- a/security/capability.c	Mon Sep 30 21:57:14 2002
    +++ b/security/capability.c	Mon Sep 30 22:11:29 2002
    @@ -1189,6 +1189,7 @@
     	.ip_encapsulate =		cap_ip_encapsulate,
     	.ip_decapsulate =		cap_ip_decapsulate,
     	.ip_decode_options =		cap_ip_decode_options,
    +	.ip_prot_sock =			dummy_ip_prot_sock,
     
     	.netdev_unregister =		cap_netdev_unregister,
     
    diff -urN a/security/dte/dte.c b/security/dte/dte.c
    --- a/security/dte/dte.c	Mon Sep 30 21:57:14 2002
    +++ b/security/dte/dte.c	Mon Sep 30 22:12:06 2002
    @@ -1053,6 +1053,7 @@
     	ip_encapsulate:			dte_ip_encapsulate,
     	ip_decapsulate:			dte_ip_decapsulate,
     	ip_decode_options:		dte_ip_decode_options,
    +	ip_prot_sock:			dummy_ip_prot_sock,
     	
     	netdev_unregister:		dte_netdev_unregister,
     	
    diff -urN a/security/dummy.c b/security/dummy.c
    --- a/security/dummy.c	Mon Sep 30 21:57:14 2002
    +++ b/security/dummy.c	Tue Oct  1 11:19:04 2002
    @@ -18,6 +18,8 @@
     #include <linux/security.h>
     #include <linux/skbuff.h>
     #include <linux/netlink.h>
    +#include <linux/in.h>
    +#include <net/sock.h>
     
     static int dummy_sethostname (char *hostname)
     {
    @@ -590,6 +592,18 @@
     	return 0;
     }
     
    +int dummy_ip_prot_sock (struct socket *sock,
    +			struct sockaddr *address, int addrlen)
    +{
    +	struct sockaddr_in *addr = (struct sockaddr_in *) address;
    +	unsigned short port = ntohs(addr->sin_port);
    +
    +	if (port && port < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
    +		return -EACCES;
    +
    +	return 0;
    +}
    +
     static void dummy_netdev_unregister (struct net_device *dev)
     {
     	return;
    @@ -1009,6 +1023,7 @@
     	.ip_encapsulate =		dummy_ip_encapsulate,
     	.ip_decapsulate =		dummy_ip_decapsulate,
     	.ip_decode_options =		dummy_ip_decode_options,
    +	.ip_prot_sock =			dummy_ip_prot_sock,
     
     	.ipc_permission =		dummy_ipc_permission,
     	.ipc_getinfo =			dummy_ipc_getinfo,
    @@ -1045,3 +1060,4 @@
     	.unregister_security =		dummy_unregister,
     };
     
    +EXPORT_SYMBOL (dummy_ip_prot_sock);
    diff -urN a/security/lids/lids_lsm.c b/security/lids/lids_lsm.c
    --- a/security/lids/lids_lsm.c	Mon Sep 30 21:57:14 2002
    +++ b/security/lids/lids_lsm.c	Mon Sep 30 22:12:33 2002
    @@ -1208,6 +1208,7 @@
     	ip_encapsulate:			lids_ip_encapsulate,
     	ip_decapsulate:			lids_ip_decapsulate,
     	ip_decode_options:		lids_ip_decode_options,
    +	ip_prot_sock:			dummy_ip_prot_sock,
     	
     	ipc_permission:			lids_ipc_permission,
     	ipc_getinfo:			lids_ipc_getinfo,
    diff -urN a/security/owlsm.c b/security/owlsm.c
    --- a/security/owlsm.c	Mon Sep 30 21:57:14 2002
    +++ b/security/owlsm.c	Mon Sep 30 22:13:01 2002
    @@ -1005,6 +1005,7 @@
     	ip_encapsulate:			owlsm_ip_encapsulate,
     	ip_decapsulate:			owlsm_ip_decapsulate,
     	ip_decode_options:		owlsm_decode_options,
    +	ip_prot_sock:			dummy_ip_prot_sock,
     
     	netdev_unregister:		owlsm_netdev_unregister,
     	
    diff -urN a/security/selinux/hooks.c b/security/selinux/hooks.c
    --- a/security/selinux/hooks.c	Mon Sep 30 21:57:14 2002
    +++ b/security/selinux/hooks.c	Tue Oct  1 00:02:20 2002
    @@ -3218,6 +3218,54 @@
     	return nsid_ip_decode_options(skb, optptr, pp_ptr);
     }
     
    +static int selinux_ip_prot_sock(struct socket *sock,
    +				struct sockaddr *address, int addrlen)
    +{
    +	struct sockaddr_in *addr = (struct sockaddr_in *)address;
    +	unsigned short snum = ntohs(addr->sin_port);
    +
    +	/*
    +	 * If PF_INET, check name_bind permission for the port.
    +	 */
    +	if (sock->sk->family == PF_INET) {
    +		struct inode_security_struct *isec;
    +		struct task_security_struct *tsec;
    +		avc_audit_data_t ad;
    +		struct sock *sk = sock->sk;
    +		security_id_t sid;
    +		int err;
    +
    +		err = task_precondition(current);
    +		if (err <= 0)
    +			return err;
    +		tsec = current->security;
    +		err = inode_precondition(SOCK_INODE(sock));
    +		if (err <= 0)
    +			return err;
    +		isec = SOCK_INODE(sock)->i_security;
    +
    +		if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) ||
    +			   snum > ip_local_port_range_1)) {
    +			err = security_port_sid(sk->family, sk->type,
    +						sk->protocol, snum, &sid);
    +			if (err)
    +				return err;
    +			AVC_AUDIT_DATA_INIT(&ad,NET);
    +			ad.u.net.port = snum;
    +			err = avc_has_perm_audit(isec->sid, sid,
    +						 isec->sclass,
    +						 SOCKET__NAME_BIND, &ad);
    +			if (err)
    +				return err;
    +		}
    +	}
    +
    +	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
    +		return -EACCES;
    +
    +	return 0;
    +}
    +
     static void selinux_netdev_unregister(struct net_device *dev)
     {
     	netdev_free_security(dev);
    @@ -3313,43 +3361,6 @@
     	if (err)
     		return err;
     
    -	/*
    -	 * If PF_INET, check name_bind permission for the port.
    -	 */
    -	if (sock->sk->family == PF_INET) {
    -		struct inode_security_struct *isec;
    -		struct task_security_struct *tsec;
    -		avc_audit_data_t ad;
    -		struct sockaddr_in *addr = (struct sockaddr_in *)address;
    -		unsigned short snum = ntohs(addr->sin_port);
    -		struct sock *sk = sock->sk;
    -		security_id_t sid;
    -
    -		err = task_precondition(current);
    -		if (err <= 0)
    -			return err;
    -		tsec = current->security;
    -		err = inode_precondition(SOCK_INODE(sock));
    -		if (err <= 0)
    -			return err;
    -		isec = SOCK_INODE(sock)->i_security;
    -
    -		if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) ||
    -			   snum > ip_local_port_range_1)) {
    -			err = security_port_sid(sk->family, sk->type,
    -						sk->protocol, snum, &sid);
    -			if (err)
    -				return err;
    -			AVC_AUDIT_DATA_INIT(&ad,NET);
    -			ad.u.net.port = snum;
    -			err = avc_has_perm_audit(isec->sid, sid,
    -						 isec->sclass,
    -						 SOCKET__NAME_BIND, &ad);
    -			if (err)
    -				return err;
    -		}
    -	}
    -
     	return 0;
     }
     
    @@ -4814,6 +4825,7 @@
     	ip_encapsulate:			selinux_ip_encapsulate,
     	ip_decapsulate:			selinux_ip_decapsulate,
     	ip_decode_options:		selinux_ip_decode_options,
    +	ip_prot_sock:			selinux_ip_prot_sock,
     	
     	netdev_unregister:		selinux_netdev_unregister,
     	
    _______________________________________________
    linux-security-module mailing list
    linux-security-moduleat_private
    http://mail.wirex.com/mailman/listinfo/linux-security-module
    



    This archive was generated by hypermail 2b30 : Tue Oct 01 2002 - 02:43:31 PDT