Re: [PATCH v2 1/3] selinux: add AF_UNSPEC and INADDR_ANY checks to selinux_socket_bind()

2018-05-11 Thread Richard Haines
On Fri, 2018-05-11 at 20:15 +0300, Alexey Kodanev wrote:
> Commit d452930fd3b9 ("selinux: Add SCTP support") breaks
> compatibility
> with the old programs that can pass sockaddr_in structure with
> AF_UNSPEC
> and INADDR_ANY to bind(). As a result, bind() returns EAFNOSUPPORT
> error.
> This was found with LTP/asapi_01 test.
> 
> Similar to commit 29c486df6a20 ("net: ipv4: relax AF_INET check in
> bind()"), which relaxed AF_INET check for compatibility, add
> AF_UNSPEC
> case to AF_INET and make sure that the address is INADDR_ANY.
> 
> Fixes: d452930fd3b9 ("selinux: Add SCTP support")
> Signed-off-by: Alexey Kodanev 
> ---
> 
> v2: As suggested by Paul:
> * return EINVAL for SCTP socket if sa_family is AF_UNSPEC and
>   address is not INADDR_ANY
> * add new 'sa_family' variable so that it equals either AF_INET
>   or AF_INET6. Besides, it it will be used in the next patch that
>   fixes audit record.
> 
>  security/selinux/hooks.c | 29 +++--
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 4cafe6a..1ed7004 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4576,6 +4576,7 @@ static int selinux_socket_post_create(struct
> socket *sock, int family,
>  static int selinux_socket_bind(struct socket *sock, struct sockaddr
> *address, int addrlen)
>  {
>   struct sock *sk = sock->sk;
> + struct sk_security_struct *sksec = sk->sk_security;
>   u16 family;
>   int err;
>  
> @@ -4587,11 +4588,11 @@ static int selinux_socket_bind(struct socket
> *sock, struct sockaddr *address, in
>   family = sk->sk_family;
>   if (family == PF_INET || family == PF_INET6) {
>   char *addrp;
> - struct sk_security_struct *sksec = sk->sk_security;
>   struct common_audit_data ad;
>   struct lsm_network_audit net = {0,};
>   struct sockaddr_in *addr4 = NULL;
>   struct sockaddr_in6 *addr6 = NULL;
> + u16 family_sa = address->sa_family;
>   unsigned short snum;
>   u32 sid, node_perm;
>  
> @@ -4601,11 +4602,20 @@ static int selinux_socket_bind(struct socket
> *sock, struct sockaddr *address, in
>* need to check address->sa_family as it is
> possible to have
>* sk->sk_family = PF_INET6 with addr->sa_family =
> AF_INET.
>*/
> - switch (address->sa_family) {
> + switch (family_sa) {
> + case AF_UNSPEC:
>   case AF_INET:
>   if (addrlen < sizeof(struct sockaddr_in))
>   return -EINVAL;
>   addr4 = (struct sockaddr_in *)address;
> + if (family_sa == AF_UNSPEC) {
> + /* see __inet_bind(), we only want
> to allow
> +  * AF_UNSPEC if the address is
> INADDR_ANY
> +  */
> + if (addr4->sin_addr.s_addr !=
> htonl(INADDR_ANY))
> + goto err_af;
> + family_sa = AF_INET;
> + }
>   snum = ntohs(addr4->sin_port);
>   addrp = (char *)>sin_addr.s_addr;
>   break;
> @@ -4617,13 +4627,7 @@ static int selinux_socket_bind(struct socket
> *sock, struct sockaddr *address, in
>   addrp = (char *)>sin6_addr.s6_addr;
>   break;
>   default:
> - /* Note that SCTP services expect -EINVAL,
> whereas
> -  * others expect -EAFNOSUPPORT.
> -  */
> - if (sksec->sclass == SECCLASS_SCTP_SOCKET)
> - return -EINVAL;
> - else
> - return -EAFNOSUPPORT;
> + goto err_af;
>   }
>  
>   if (snum) {
> @@ -4681,7 +4685,7 @@ static int selinux_socket_bind(struct socket
> *sock, struct sockaddr *address, in
>   ad.u.net->sport = htons(snum);
>   ad.u.net->family = family;
>  
> - if (address->sa_family == AF_INET)
> + if (family_sa == AF_INET)
>   ad.u.net->v4info.saddr = addr4-
> >sin_addr.s_addr;
>   else
>   ad.u.net->v6info.saddr = addr6->sin6_addr;
> @@ -4694,6 +4698,11 @@ static int selinux_socket_bind(struct socket
> *sock, struct sockaddr *address, in
>   }
>  out:
>   return err;
> +err_af:
> + /* Note that SCTP services expect -EINVAL, others
> -EAFNOSUPPORT. */
> + if (sksec->sclass == SECCLASS_SCTP_SOCKET)
> + return -EINVAL;
> + return -EAFNOSUPPORT;
>  }
>  
>  /* This supports connect(2) and SCTP connect services such as
> sctp_connectx(3)

Tested all 

[PATCH] selinux: Fix ltp test connect-syscall failure

2018-03-02 Thread Richard Haines
Fix the following error when running regression tests using LTP as follows:
cd /opt/ltp/
cat runtest/syscalls |grep connect01>runtest/connect-syscall
./runltp -pq -f connect-syscall

Running tests...
connect011  TPASS  :  bad file descriptor successful
connect012  TPASS  :  invalid socket buffer successful
connect013  TPASS  :  invalid salen successful
connect014  TPASS  :  invalid socket successful
connect015  TPASS  :  already connected successful
connect016  TPASS  :  connection refused successful
connect017  TFAIL  :  connect01.c:146: invalid address family ;
returned -1 (expected -1), errno 22 (expected 97)
INFO: ltp-pan reported some tests FAIL
LTP Version: 20180118

Reported-by: Anders Roxell <anders.rox...@linaro.org>
Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 security/selinux/hooks.c | 42 ++
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 28a5c4e..d614df1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4470,22 +4470,29 @@ static int selinux_socket_bind(struct socket *sock, 
struct sockaddr *address, in
 * need to check address->sa_family as it is possible to have
 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
 */
-   if (address->sa_family == AF_INET) {
-   if (addrlen < sizeof(struct sockaddr_in)) {
-   err = -EINVAL;
-   goto out;
-   }
+   switch (address->sa_family) {
+   case AF_INET:
+   if (addrlen < sizeof(struct sockaddr_in))
+   return -EINVAL;
addr4 = (struct sockaddr_in *)address;
snum = ntohs(addr4->sin_port);
addrp = (char *)>sin_addr.s_addr;
-   } else {
-   if (addrlen < SIN6_LEN_RFC2133) {
-   err = -EINVAL;
-   goto out;
-   }
+   break;
+   case AF_INET6:
+   if (addrlen < SIN6_LEN_RFC2133)
+   return -EINVAL;
addr6 = (struct sockaddr_in6 *)address;
snum = ntohs(addr6->sin6_port);
addrp = (char *)>sin6_addr.s6_addr;
+   break;
+   default:
+   /* Note that SCTP services expect -EINVAL, whereas
+* others expect -EAFNOSUPPORT.
+*/
+   if (sksec->sclass == SECCLASS_SCTP_SOCKET)
+   return -EINVAL;
+   else
+   return -EAFNOSUPPORT;
}
 
if (snum) {
@@ -4589,16 +4596,27 @@ static int selinux_socket_connect_helper(struct socket 
*sock,
 * need to check address->sa_family as it is possible to have
 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
 */
-   if (address->sa_family == AF_INET) {
+   switch (address->sa_family) {
+   case AF_INET:
addr4 = (struct sockaddr_in *)address;
if (addrlen < sizeof(struct sockaddr_in))
return -EINVAL;
snum = ntohs(addr4->sin_port);
-   } else {
+   break;
+   case AF_INET6:
addr6 = (struct sockaddr_in6 *)address;
if (addrlen < SIN6_LEN_RFC2133)
return -EINVAL;
snum = ntohs(addr6->sin6_port);
+   break;
+   default:
+   /* Note that SCTP services expect -EINVAL, whereas
+* others expect -EAFNOSUPPORT.
+*/
+   if (sksec->sclass == SECCLASS_SCTP_SOCKET)
+   return -EINVAL;
+   else
+   return -EAFNOSUPPORT;
}
 
err = sel_netport_sid(sk->sk_protocol, snum, );
-- 
2.14.3



Re: Regression found when running LTP connect01 on next-20180301

2018-03-02 Thread Richard Haines
On Thu, 2018-03-01 at 13:03 -0500, Paul Moore wrote:
> On March 1, 2018 9:36:37 AM Richard Haines <richard_c_haines@btintern
> et.com> wrote:
> > On Thu, 2018-03-01 at 08:42 -0500, Paul Moore wrote:
> > > On Thu, Mar 1, 2018 at 3:33 AM, Anders Roxell <anders.roxell@lina
> > > ro.o
> > > rg> wrote:
> > > > Hi,
> > > > 
> > > > I was running LTP's testcase connect01 [1] and found a
> > > > regression
> > > > in linux-next
> > > > (next-20180301).  Bisect gave me this patch as the problematic
> > > > patch (sha
> > > > d452930fd3b9 "selinux: Add SCTP support") on a x86 target.
> > > > 
> > > > Output from the test(LTP release 20180118):
> > > > $ cd /opt/ltp/
> > > > $ cat runtest/syscalls |grep connect01>runtest/connect-syscall
> > > > $ ./runltp -pq -f connect-syscall
> > > > "
> > > > Running tests...
> > > > connect011  TPASS  :  bad file descriptor successful
> > > > connect012  TPASS  :  invalid socket buffer successful
> > > > connect013  TPASS  :  invalid salen successful
> > > > connect014  TPASS  :  invalid socket successful
> > > > connect015  TPASS  :  already connected successful
> > > > connect016  TPASS  :  connection refused successful
> > > > connect017  TFAIL  :  connect01.c:146: invalid address
> > > > family ;
> > > > returned -1 (expected -1), errno 22 (expected 97)
> > > > INFO: ltp-pan reported some tests FAIL
> > > > LTP Version: 20180118
> > > > "
> > > > 
> > > > The output from the test expected 97 and we received 22, can
> > > > you
> > > > please
> > > > elaborate on what have been changed?
> > > > 
> > > > Cheers,
> > > > Anders
> > > > [1] https://github.com/linux-test-project/ltp/blob/20180118/tes
> > > > tcas
> > > > es/kernel/syscalls/connect/connect01.c#L146
> > > 
> > > Hi Anders,
> > > 
> > > Thanks for the report.  Out of curiosity, we're you running the
> > > full
> > > LTP test suite and this was the only failure, or did you just run
> > > the
> > > connect01 test?  Either answer is fine, I'm just trying to
> > > understand
> > > the scope of the regression.
> > > 
> > > Richard, are you able to look into this?  If not, let me know and
> > > I'll
> > > dig a bit deeper (I'll likely take a quick look today, but if the
> > > failure is subtle it might require some digging).
> > 
> > I'll have a look today.
> 
> One more thing I forgot to mention earlier, if there is a patch to
> fix this, could you please base it on top of the existing
> SELinux/SCTP patches that have already been merged, and not respin an
> earlier patch?
> 
> Thank you.


Just to keep you informed:

It appears that with the original hooks.c selinux_socket_connect()
function check: if (sk->sk_family == PF_INET) {, the test fell through
as sk->sk_family = 2 (AF_INET) with the error being picked up by the
caller - even though the test set an illegal family of 47 - but not on
the sk->sk_family, hence:

With the new check: if (address->sa_family == AF_INET) {, the address-
>sa_family = 47 and therefore treated it as an IPv6 address and failed
with -EINVAL. By a fluke this is what SCTP services expects when
invalid address family, however TCP and DCCP requires -EAFNOSUPPORT.

I can fix this with the following simple patch:
switch (address->sa_family) {
case AF_INET:
addr4 = (struct sockaddr_in *)address;
if (addrlen < sizeof(struct sockaddr_in))
return -EINVAL;
snum = ntohs(addr4->sin_port);
break;
case AF_INET6:
addr6 = (struct sockaddr_in6 *)address;
if (addrlen < SIN6_LEN_RFC2133)
return -EINVAL;
snum = ntohs(addr6->sin6_port);
break;
default:
/* Note that SCTP services expect -EINVAL, whereas
 * others expect -EAFNOSUPPORT.
 */
if (sksec->sclass == SECCLASS_SCTP_SOCKET)
return -EINVAL;
else
return -EAFNOSUPPORT;
}

This will pass the following LTP tests:
./runltp -pq -f connect-syscall
./runltp -pq -f net.sctp

The selinux-testsuite inet_socket and sctp tests all pass as well.

However: The selinux_socket_bind() function has the same issue that can
be fixed by the same type of patch.

So far I've tested three different patches to fix this problem and
this one above seems best. I'll post a patch based on this covering
the bind issue as well once I've done more testing.

I think the SCTP services should return -EAFNOSUPPORT for this (as
their sctp_connectx(3) man page states this), that will require kernel
patch and patches to their test services (plus of course may impact
some apps already out there ??).


> 
> --
> paul moore
> www.paul-moore.com
> 
> 


Re: Regression found when running LTP connect01 on next-20180301

2018-03-01 Thread Richard Haines
On Thu, 2018-03-01 at 08:42 -0500, Paul Moore wrote:
> On Thu, Mar 1, 2018 at 3:33 AM, Anders Roxell  rg> wrote:
> > Hi,
> > 
> > I was running LTP's testcase connect01 [1] and found a regression
> > in linux-next
> > (next-20180301).  Bisect gave me this patch as the problematic
> > patch (sha
> > d452930fd3b9 "selinux: Add SCTP support") on a x86 target.
> > 
> > Output from the test(LTP release 20180118):
> > $ cd /opt/ltp/
> > $ cat runtest/syscalls |grep connect01>runtest/connect-syscall
> > $ ./runltp -pq -f connect-syscall
> > "
> > Running tests...
> > connect011  TPASS  :  bad file descriptor successful
> > connect012  TPASS  :  invalid socket buffer successful
> > connect013  TPASS  :  invalid salen successful
> > connect014  TPASS  :  invalid socket successful
> > connect015  TPASS  :  already connected successful
> > connect016  TPASS  :  connection refused successful
> > connect017  TFAIL  :  connect01.c:146: invalid address family ;
> > returned -1 (expected -1), errno 22 (expected 97)
> > INFO: ltp-pan reported some tests FAIL
> > LTP Version: 20180118
> > "
> > 
> > The output from the test expected 97 and we received 22, can you
> > please
> > elaborate on what have been changed?
> > 
> > Cheers,
> > Anders
> > [1] https://github.com/linux-test-project/ltp/blob/20180118/testcas
> > es/kernel/syscalls/connect/connect01.c#L146
> 
> Hi Anders,
> 
> Thanks for the report.  Out of curiosity, we're you running the full
> LTP test suite and this was the only failure, or did you just run the
> connect01 test?  Either answer is fine, I'm just trying to understand
> the scope of the regression.
> 
> Richard, are you able to look into this?  If not, let me know and
> I'll
> dig a bit deeper (I'll likely take a quick look today, but if the
> failure is subtle it might require some digging).

I'll have a look today.
> 


[PATCH V8 2/4] sctp: Add ip option support

2018-02-24 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.
All "./sctp-tests run" obtained from: https://github.com/sctp/sctp-tests
pass.

V7 Changes:
1) Log when copy ip options fail for IPv4 and IPv6
2) Correct sctp_setsockopt_maxseg() function. Note that the lksctp-tools
func_tests do not test with struct sctp_assoc_value. Just used simple test
and okay.
3) Move calculation of overheads to sctp_packet_config().
NOTE: Initially in sctp_packet_reset() I set packet->size and
packet->overhead to zero (as it is a reset). This was okay for all the
lksctp-tools function tests, however when running "sctp-tests" ndatshched
tests it causes these to fail with an st_s.log entry of:
sid: 3, expected: 3
sid: 3, expected: 3
unexpected sid packet !!!
sid: 1, expected: 3

I then found sctp_packet_transmit() relies on setting
"packet->size = packet->overhead;" to reset size to the current overhead
after sending packets, hence the comment in sctp_packet_reset()

V8 Change:
Fix sparse warning:
net/sctp/protocol.c:269:28: sparse: dereference of noderef expression
highlighted in [1] for sctp_v4_ip_options_len() function.

[1] https://lists.01.org/pipermail/kbuild-all/2018-February/043695.html

 include/net/sctp/sctp.h|  4 +++-
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   | 10 +++---
 net/sctp/ipv6.c| 45 ++---
 net/sctp/output.c  | 34 +-
 net/sctp/protocol.c| 43 +++
 net/sctp/socket.c  | 11 ---
 7 files changed, 122 insertions(+), 27 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index f7ae6b0..25c5c87 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct list_head 
*head)
 static inline int sctp_frag_point(const struct sctp_association *asoc, int 
pmtu)
 {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
+   struct sctp_af *af = sp->pf->af;
int frag = pmtu;
 
-   frag -= sp->pf->af->net_header_len;
+   frag -= af->ip_options_len(asoc->base.sk);
+   frag -= af->net_header_len;
frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
 
if (asoc->user_frag)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 03e92dd..ead5fce 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -491,6 +491,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -515,6 +516,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 991a530..d726d21 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -171,6 +171,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_datamsg *msg;
+   struct sctp_sock *sp;
+   struct sctp_af *af;
int err;
 
msg = sctp_datamsg_new(GFP_KERNEL);
@@ -189,9 +191,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
/* This is the biggest possible DATA chunk that can fit into
 * the packet
 */
-   max_data = asoc->pathmtu -
-  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sctp_datachk_len(>stream);
+   sp = sctp_sk(asoc->base.sk);
+   af = sp->pf->af;
+   max_data = asoc->pathmtu - af->net_header_len -
+  sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
+  af->ip_options_len(asoc->base.sk);
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e35d4f7..30a05a8 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -427,6 +427,41 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{

[PATCH V7 2/4] sctp: Add ip option support

2018-02-20 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.
All "./sctp-tests run" obtained from: https://github.com/sctp/sctp-tests
pass.

V7 Changes:
1) Log when copy ip options fail for IPv4 and IPv6
2) Correct sctp_setsockopt_maxseg() function. Note that the lksctp-tools
func_tests do not test with struct sctp_assoc_value. Just used simple test
and okay.
3) Move calculation of overheads to sctp_packet_config().
NOTE: Initially in sctp_packet_reset() I set packet->size and
packet->overhead to zero (as it is a reset). This was okay for all the
lksctp-tools function tests, however when running "sctp-tests" ndatshched
tests it causes these to fail with an st_s.log entry of:
sid: 3, expected: 3
sid: 3, expected: 3
unexpected sid packet !!!
sid: 1, expected: 3

I then found sctp_packet_transmit() relies on setting
"packet->size = packet->overhead;" to reset size to the current overhead
after sending packets, hence the comment in sctp_packet_reset()

 include/net/sctp/sctp.h|  4 +++-
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   | 10 +++---
 net/sctp/ipv6.c| 45 ++---
 net/sctp/output.c  | 34 +-
 net/sctp/protocol.c| 38 ++
 net/sctp/socket.c  | 11 ---
 7 files changed, 117 insertions(+), 27 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index f7ae6b0..25c5c87 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct list_head 
*head)
 static inline int sctp_frag_point(const struct sctp_association *asoc, int 
pmtu)
 {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
+   struct sctp_af *af = sp->pf->af;
int frag = pmtu;
 
-   frag -= sp->pf->af->net_header_len;
+   frag -= af->ip_options_len(asoc->base.sk);
+   frag -= af->net_header_len;
frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
 
if (asoc->user_frag)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 03e92dd..ead5fce 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -491,6 +491,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -515,6 +516,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 991a530..d726d21 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -171,6 +171,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_datamsg *msg;
+   struct sctp_sock *sp;
+   struct sctp_af *af;
int err;
 
msg = sctp_datamsg_new(GFP_KERNEL);
@@ -189,9 +191,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
/* This is the biggest possible DATA chunk that can fit into
 * the packet
 */
-   max_data = asoc->pathmtu -
-  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sctp_datachk_len(>stream);
+   sp = sctp_sk(asoc->base.sk);
+   af = sp->pf->af;
+   max_data = asoc->pathmtu - af->net_header_len -
+  sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
+  af->ip_options_len(asoc->base.sk);
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e35d4f7..30a05a8 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -427,6 +427,41 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{
+   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+
+   newnp = inet6_sk(newsk);
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt) {
+   opt = ipv6

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-18 Thread Richard Haines
On Fri, 2018-02-16 at 23:28 -0500, Neil Horman wrote:
> On Fri, Feb 16, 2018 at 07:51:02PM -0200, Marcelo Ricardo Leitner
> wrote:
> > On Fri, Feb 16, 2018 at 03:14:35PM -0500, Neil Horman wrote:
> > > On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner
> > > wrote:
> > > > On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > > > > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines
> > > > > wrote:
> > > > > > Add ip option support to allow LSM security modules to
> > > > > > utilise CIPSO/IPv4
> > > > > > and CALIPSO/IPv6 services.
> > > > > > 
> > > > > > Signed-off-by: Richard Haines <richard_c_haines@btinternet.
> > > > > > com>
> > > > > > ---
> > > > > >  include/net/sctp/sctp.h|  4 +++-
> > > > > >  include/net/sctp/structs.h |  2 ++
> > > > > >  net/sctp/chunk.c   | 12 +++-
> > > > > >  net/sctp/ipv6.c| 42
> > > > > > +++---
> > > > > >  net/sctp/output.c  |  5 -
> > > > > >  net/sctp/protocol.c| 36
> > > > > > 
> > > > > >  net/sctp/socket.c  | 14 ++
> > > > > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > > > > 
> > > > > > diff --git a/include/net/sctp/sctp.h
> > > > > > b/include/net/sctp/sctp.h
> > > > > > index f7ae6b0..25c5c87 100644
> > > > > > --- a/include/net/sctp/sctp.h
> > > > > > +++ b/include/net/sctp/sctp.h
> > > > > > @@ -441,9 +441,11 @@ static inline int
> > > > > > sctp_list_single_entry(struct list_head *head)
> > > > > >  static inline int sctp_frag_point(const struct
> > > > > > sctp_association *asoc, int pmtu)
> > > > > >  {
> > > > > > struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > > > > +   struct sctp_af *af = sp->pf->af;
> > > > > > int frag = pmtu;
> > > > > >  
> > > > > > -   frag -= sp->pf->af->net_header_len;
> > > > > > +   frag -= af->ip_options_len(asoc->base.sk);
> > > > > > +   frag -= af->net_header_len;
> > > > > > frag -= sizeof(struct sctphdr) +
> > > > > > sctp_datachk_len(>stream);
> > > > > >  
> > > > > > if (asoc->user_frag)
> > > > > > diff --git a/include/net/sctp/structs.h
> > > > > > b/include/net/sctp/structs.h
> > > > > > index 03e92dd..ead5fce 100644
> > > > > > --- a/include/net/sctp/structs.h
> > > > > > +++ b/include/net/sctp/structs.h
> > > > > > @@ -491,6 +491,7 @@ struct sctp_af {
> > > > > > void(*ecn_capable)(struct sock
> > > > > > *sk);
> > > > > > __u16   net_header_len;
> > > > > > int sockaddr_len;
> > > > > > +   int (*ip_options_len)(struct sock
> > > > > > *sk);
> > > > > > sa_family_t sa_family;
> > > > > > struct list_head list;
> > > > > >  };
> > > > > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > > > > > int (*addr_to_user)(struct sctp_sock *sk, union
> > > > > > sctp_addr *addr);
> > > > > > void (*to_sk_saddr)(union sctp_addr *, struct sock
> > > > > > *sk);
> > > > > > void (*to_sk_daddr)(union sctp_addr *, struct sock
> > > > > > *sk);
> > > > > > +   void (*copy_ip_options)(struct sock *sk, struct
> > > > > > sock *newsk);
> > > > > > struct sctp_af *af;
> > > > > >  };
> > > > > >  
> > > > > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > > > > index 991a530..d5c0ef7 100644
> > > > > > --- a/net/sctp/chunk.c
> > > > > > +++ b/net/sctp/chunk.c
> > > > > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct
> > > > > > sctp_datamsg *msg, struct sctp_chunk *chu
> > > > > > chunk->msg 

[PATCH V6 4/4] selinux: Add SCTP support

2018-02-13 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/SELinux-sctp.rst | 157 ++
 security/selinux/hooks.c| 280 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  21 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 133 +--
 6 files changed, 565 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.rst

diff --git a/Documentation/security/SELinux-sctp.rst 
b/Documentation/security/SELinux-sctp.rst
new file mode 100644
index 000..2f66bf3
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.rst
@@ -0,0 +1,157 @@
+SCTP SELinux Support
+=
+
+Security Hooks
+===
+
+``Documentation/security/LSM-sctp.rst`` describes the following SCTP security
+hooks with the SELinux specifics expanded below::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+security_inet_conn_established()
+
+
+security_sctp_assoc_request()
+-
+Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
+security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+The security module performs the following operations:
+ IF this is the first association on ``@ep->base.sk``, then set the peer
+ sid to that in ``@skb``. This will ensure there is only one peer sid
+ assigned to ``@ep->base.sk`` that may support multiple associations.
+
+ ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
+ to determine whether the association should be allowed or denied.
+
+ Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
+ MLS portion taken from ``@skb peer sid``. This will be used by SCTP
+ TCP style sockets and peeled off connections as they cause a new socket
+ to be generated.
+
+ If IP security options are configured (CIPSO/CALIPSO), then the ip
+ options are set on the socket.
+
+
+security_sctp_bind_connect()
+-
+Checks permissions required for ipv4/ipv6 addresses based on the ``@optname``
+as follows::
+
+  --
+  |   BIND Permission Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+
+``Documentation/security/LSM-sctp.rst`` gives a summary of the ``@optname``
+entries and also describes ASCONF chunk processing when Dynamic Address
+Reconfiguration is enabled.
+
+
+security_sctp_sk_clone()
+-
+Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
+socket) or when a socket is 'peeled off' e.g userspace calls
+**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
+sockets sid and peer sid to that contained in the ``@ep sid`` and
+``@ep peer sid`` respectively.
+::
+
+@ep - pointer to current sctp endpoint structure.
+@sk - pointer to current sock structure.
+@sk - pointer to new sock structure.
+
+
+security_inet_conn_established()
+-
+Called when a COOKIE ACK is received where it sets the connection's peer sid
+to that in ``@skb``::
+
+@sk  - pointer to sock structure.
+@skb - pointer to skbuff of the COOKIE ACK packet.
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel::
+
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy capability is enabled::
+
+policycap extended_socket_class;
+
+SELinux SCTP support adds the ``name_connect`` perm

[PATCH V6 3/4] sctp: Add LSM hooks

2018-02-13 Thread Richard Haines
Add security hooks allowing security modules to exercise access control
over SCTP.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h | 10 
 include/uapi/linux/sctp.h  |  1 +
 net/sctp/sm_make_chunk.c   | 12 +
 net/sctp/sm_statefuns.c| 18 ++
 net/sctp/socket.c  | 62 +-
 5 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index ead5fce..7a23896 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1318,6 +1318,16 @@ struct sctp_endpoint {
  reconf_enable:1;
 
__u8  strreset_enable;
+
+   /* Security identifiers from incoming (INIT). These are set by
+* security_sctp_assoc_request(). These will only be used by
+* SCTP TCP type sockets and peeled off connections as they
+* cause a new socket to be generated. security_sctp_sk_clone()
+* will then plug these into the new socket.
+*/
+
+   u32 secid;
+   u32 peer_secid;
 };
 
 /* Recover the outter endpoint structure. */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 4c4db14..64736ed 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -126,6 +126,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_STREAM_SCHEDULER  123
 #define SCTP_STREAM_SCHEDULER_VALUE124
 #define SCTP_INTERLEAVING_SUPPORTED125
+#define SCTP_SENDMSG_CONNECT   126
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE  0x
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index d01475f..70274ae 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3071,6 +3071,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, >source, sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_ADD_IP,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
 * request and does not have the local resources to add this
 * new address to the association, it MUST return an Error
@@ -3137,6 +3143,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, sctp_source(asconf), sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_SET_PRIMARY,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
peer = sctp_assoc_lookup_paddr(asoc, );
if (!peer)
return SCTP_ERROR_DNS_FAILED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index eb7905f..42659ab 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -321,6 +321,11 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
struct sctp_packet *packet;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -908,6 +913,9 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
 */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
 
+   /* Set peer label for connection. */
+   security_inet_conn_established(ep->base.sk, chunk->skb);
+
/* RFC 2960 5.1 Normal Establishment of an Association
 *
 * E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -1436,6 +1444,11 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
struct sctp_packet *packet;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -2106,6 +2119,11 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
}
}
 
+

[PATCH V6 2/4] sctp: Add ip option support

2018-02-13 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/sctp.h|  4 +++-
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   | 12 +++-
 net/sctp/ipv6.c| 42 +++---
 net/sctp/output.c  |  5 -
 net/sctp/protocol.c| 36 
 net/sctp/socket.c  | 14 ++
 7 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index f7ae6b0..25c5c87 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct list_head 
*head)
 static inline int sctp_frag_point(const struct sctp_association *asoc, int 
pmtu)
 {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
+   struct sctp_af *af = sp->pf->af;
int frag = pmtu;
 
-   frag -= sp->pf->af->net_header_len;
+   frag -= af->ip_options_len(asoc->base.sk);
+   frag -= af->net_header_len;
frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
 
if (asoc->user_frag)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 03e92dd..ead5fce 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -491,6 +491,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -515,6 +516,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 991a530..d5c0ef7 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, 
struct sctp_chunk *chu
chunk->msg = msg;
 }
 
-
 /* A data chunk can have a maximum payload of (2^16 - 20).  Break
  * down any such message into smaller chunks.  Opportunistically, fragment
  * the chunks down to the current MTU constraints.  We may get refragmented
@@ -171,6 +170,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_datamsg *msg;
+   struct sctp_sock *sp;
+   struct sctp_af *af;
int err;
 
msg = sctp_datamsg_new(GFP_KERNEL);
@@ -189,9 +190,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
/* This is the biggest possible DATA chunk that can fit into
 * the packet
 */
-   max_data = asoc->pathmtu -
-  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sctp_datachk_len(>stream);
+   sp = sctp_sk(asoc->base.sk);
+   af = sp->pf->af;
+   max_data = asoc->pathmtu - af->net_header_len -
+  sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
+  af->ip_options_len(asoc->base.sk);
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
@@ -211,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
 
/* Set first_len and then account for possible bundles on first frag */
first_len = max_data;
-
/* Check to see if we have a pending SACK and try to let it be bundled
 * with this message.  Do this if we don't have any data queued already.
 * To check that, look at out_qlen and retransmit list.
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e35d4f7..0b0f895 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -427,6 +427,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{
+   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+
+   newnp = inet6_sk(newsk);
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt)
+   opt = ipv6_dup_options(newsk, opt);
+   RCU_INIT_POINTER(newnp->opt, opt);
+   rcu_read_unlock();
+}
+
+/* Account for the IP options */
+static int sctp_v6_ip_options_len(struct sock *sk)
+{
+   struct ipv6_pinfo *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+   int l

[PATCH V6 0/4] Add SELinux SCTP protocol support

2018-02-13 Thread Richard Haines
These patches have been built on Fedora 27 with kernel-4.16.0-0.rc1 plus
the following userspace patches to enable testing:

1) Updates to libsepol 2.7 to support the sctp portcon statement.
   The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-Add-support-for-the-SCTP-portcon-keyword.patch

2) Updates to the SELinux Test Suite adding SCTP tests. Please read the
   selinux-testsuite/README.sctp for details. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-testsuite-Add-SCTP-test-support.patch

3) Updates to lksctp-tools that show SELinux info in sctp_darn and
   sctp_test. It also contains a minor patch for test_1_to_1_connect.c
   as when CIPSO/CALIPSO configured, NetLabel returns a different error
   code for illegal addresses in test 5. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 lksctp-tools-Add-SELinux-support-to-sctp_test-and-sc.patch

All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.

All SCTP regression tests "./sctp-tests run" run correctly in enforcing
mode. These tests are obtained from: https://github.com/sctp/sctp-tests

The selinux-testsuite patch also adds remote tests (that need some manual
configuration). These are useful for testing CIPSO/CALIPSO over a network
with a number of categories to produce large ip option fields with various
message sizes forcing fragmentation etc..

Changes since RFC Patch:
Removed the NetLabel patch (was [RFC PATCH 4/5] netlabel: Add SCTP support)
as re-engineered. However this patchset will require the NetLabel
patch at [1] to fully run the SCTP selinux-testsuite.

V1 Changes:
PATCH 1/4
Remove unused parameter from security_sctp_assoc_request().
Reformat and update LSM-sctp.rst documentation.
PATCH 2/4
Add variables and RCU locks as requested in [2] to support IP options.
PATCH 3/4
Added security_sctp_assoc_request() hook to sctp_sf_do_unexpected_init()
and sctp_sf_do_5_2_4_dupcook().
Removed security_sctp_assoc_request() hook from sctp_sf_do_5_1C_ack() as
no longer required.
PATCH 4/4
Reformat and update SELinux-sctp.rst documentation.
Remove bindx and connectx permissions.
Rework selinux_socket_connect() and selinux_netlbl_socket_connect() to
utilise helpers for code reuse.
Add spinlock to selinux_sctp_assoc_request().
Remove unused parameter from security_sctp_assoc_request().
Use address->sa_family == AF_INET in *_bind and *_connect to ensure
correct address type.
Minor cleanups.

V2 Changes:
PATCH 4/4 - Remove spin lock from selinux_sctp_assoc_request()
PATCH 4/4 - Fix selinux_sctp_sk_clone() kbuild test robot catch [3]

V3 Changes:
PATCH 2/4 - Account for IP options length in sctp.h sctp_frag_point() by
Marcelo

V4 Changes:
PATCH 1/4 - Move specific SELinux descriptions from LSM-sctp.rst and
lsm_hooks.h to SELinux-sctp.rst in PATCH 4/4
PATCH 4/4 - Rename selinux_netlbl_sctp_socket_connect() to
selinux_netlbl_socket_connect_locked() and move description comments to
selinux_sctp_bind_connect()

V5 Change: Rework selinux_netlbl_socket_connect() and
selinux_netlbl_socket_connect_locked as requested by Paul.

V6 Changes:
Rework SCTP patches 2/4 and 3/4 as there have been major SCTP updates since
kernel 4.14.

[1] https://marc.info/?l=selinux=151061619115945=2
[2] https://marc.info/?l=selinux=150962470215797=2
[3] https://marc.info/?l=selinux=151198281817779=2

Richard Haines (4):
  security: Add support for SCTP security hooks
  sctp: Add ip option support
  sctp: Add LSM hooks
  selinux: Add SCTP support

 Documentation/security/LSM-sctp.rst | 175 
 Documentation/security/SELinux-sctp.rst | 157 ++
 include/linux/lsm_hooks.h   |  36 
 include/linux/security.h|  25 +++
 include/net/sctp/sctp.h |   4 +-
 include/net/sctp/structs.h  |  12 ++
 include/uapi/linux/sctp.h   |   1 +
 net/sctp/chunk.c|  12 +-
 net/sctp/ipv6.c |  42 -
 net/sctp/output.c   |   5 +-
 net/sctp/protocol.c |  36 
 net/sctp/sm_make_chunk.c|  12 ++
 net/sctp/sm_statefuns.c |  18 ++
 net/sctp/socket.c   |  76 -
 security/security.c |  22 +++
 security/selinux/hooks.c| 280 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  21 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 133 +--
 20 files changed, 1022 insertions(+), 51 deletions(-)
 create mode 100644 Documentation/security/LSM-sctp.rst
 create mode 100644 Documentation/security/SELinux-sctp.rst

-- 
2.14.3



[PATCH V6 1/4] security: Add support for SCTP security hooks

2018-02-13 Thread Richard Haines
The SCTP security hooks are explained in:
Documentation/security/LSM-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/LSM-sctp.rst | 175 
 include/linux/lsm_hooks.h   |  36 
 include/linux/security.h|  25 ++
 security/security.c |  22 +
 4 files changed, 258 insertions(+)
 create mode 100644 Documentation/security/LSM-sctp.rst

diff --git a/Documentation/security/LSM-sctp.rst 
b/Documentation/security/LSM-sctp.rst
new file mode 100644
index 000..6e5a392
--- /dev/null
+++ b/Documentation/security/LSM-sctp.rst
@@ -0,0 +1,175 @@
+SCTP LSM Support
+
+
+For security module support, three SCTP specific hooks have been implemented::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+
+Also the following security hook has been utilised::
+
+security_inet_conn_established()
+
+The usage of these hooks are described below with the SELinux implementation
+described in ``Documentation/security/SELinux-sctp.rst``
+
+
+security_sctp_assoc_request()
+-
+Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
+security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+
+security_sctp_bind_connect()
+-
+Passes one or more ipv4/ipv6 addresses to the security module for validation
+based on the ``@optname`` that will result in either a bind or connect
+service as shown in the permission check tables below.
+Returns 0 on success, error on failure.
+::
+
+@sk  - Pointer to sock structure.
+@optname - Name of the option to validate.
+@address - One or more ipv4 / ipv6 addresses.
+@addrlen - The total length of address(s). This is calculated on each
+   ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
+   sizeof(struct sockaddr_in6).
+
+  --
+  | BIND Type Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  |   CONNECT Type Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+A summary of the ``@optname`` entries is as follows::
+
+SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be
+ associated after (optionally) calling
+ bind(3).
+ sctp_bindx(3) adds a set of bind
+ addresses on a socket.
+
+SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple
+addresses for reaching a peer
+(multi-homed).
+sctp_connectx(3) initiates a connection
+on an SCTP socket using multiple
+destination addresses.
+
+SCTP_SENDMSG_CONNECT  - Initiate a connection that is generated by a
+sendmsg(2) or sctp_sendmsg(3) on a new asociation.
+
+SCTP_PRIMARY_ADDR - Set local primary address.
+
+SCTP_SET_PEER_PRIMARY_ADDR - Request peer sets address as
+ association primary.
+
+SCTP_PARAM_ADD_IP  - These are used when Dynamic Address
+SCTP_PARAM_SET_PRIMARY - Reconfiguration is enabled as explained below.
+
+
+To support Dynamic Address Reconfiguration the following parameters must be
+enabled on both endpoints (or use the appropriate **setsockopt**\(2))::
+
+/proc/sys/net/sctp/addip_enable
+/proc/sys/net/sctp/addip_noauth_enable
+
+then the following *_PARAM_*'s are sent to the peer in an
+ASCONF chunk when the corresponding ``@optname``'s are present::
+
+  @optname  ASCONF Parameter
+ ----
+SCTP_SOCKOPT_

PATCH V5 4/4] selinux: Add SCTP support

2018-01-11 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
V5 Change: Rework selinux_netlbl_socket_connect() and
selinux_netlbl_socket_connect_locked as requested by Paul.

 Documentation/security/SELinux-sctp.rst | 157 ++
 security/selinux/hooks.c| 280 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  21 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 133 +--
 6 files changed, 565 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.rst

diff --git a/Documentation/security/SELinux-sctp.rst 
b/Documentation/security/SELinux-sctp.rst
new file mode 100644
index 000..2f66bf3
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.rst
@@ -0,0 +1,157 @@
+SCTP SELinux Support
+=
+
+Security Hooks
+===
+
+``Documentation/security/LSM-sctp.rst`` describes the following SCTP security
+hooks with the SELinux specifics expanded below::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+security_inet_conn_established()
+
+
+security_sctp_assoc_request()
+-
+Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
+security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+The security module performs the following operations:
+ IF this is the first association on ``@ep->base.sk``, then set the peer
+ sid to that in ``@skb``. This will ensure there is only one peer sid
+ assigned to ``@ep->base.sk`` that may support multiple associations.
+
+ ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
+ to determine whether the association should be allowed or denied.
+
+ Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
+ MLS portion taken from ``@skb peer sid``. This will be used by SCTP
+ TCP style sockets and peeled off connections as they cause a new socket
+ to be generated.
+
+ If IP security options are configured (CIPSO/CALIPSO), then the ip
+ options are set on the socket.
+
+
+security_sctp_bind_connect()
+-
+Checks permissions required for ipv4/ipv6 addresses based on the ``@optname``
+as follows::
+
+  --
+  |   BIND Permission Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+
+``Documentation/security/LSM-sctp.rst`` gives a summary of the ``@optname``
+entries and also describes ASCONF chunk processing when Dynamic Address
+Reconfiguration is enabled.
+
+
+security_sctp_sk_clone()
+-
+Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
+socket) or when a socket is 'peeled off' e.g userspace calls
+**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
+sockets sid and peer sid to that contained in the ``@ep sid`` and
+``@ep peer sid`` respectively.
+::
+
+@ep - pointer to current sctp endpoint structure.
+@sk - pointer to current sock structure.
+@sk - pointer to new sock structure.
+
+
+security_inet_conn_established()
+-
+Called when a COOKIE ACK is received where it sets the connection's peer sid
+to that in ``@skb``::
+
+@sk  - pointer to sock structure.
+@skb - pointer to skbuff of the COOKIE ACK packet.
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel::
+
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy 

Re: [PATCH V4 4/4] selinux: Add SCTP support

2018-01-10 Thread Richard Haines
On Wed, 2018-01-10 at 11:37 -0500, Paul Moore wrote:
> On Sat, Dec 30, 2017 at 12:20 PM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > The SELinux SCTP implementation is explained in:
> > Documentation/security/SELinux-sctp.rst
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  Documentation/security/SELinux-sctp.rst | 157 ++
> >  security/selinux/hooks.c| 280
> > +---
> >  security/selinux/include/classmap.h |   2 +-
> >  security/selinux/include/netlabel.h |  21 ++-
> >  security/selinux/include/objsec.h   |   4 +
> >  security/selinux/netlabel.c | 138 ++--
> >  6 files changed, 570 insertions(+), 32 deletions(-)
> >  create mode 100644 Documentation/security/SELinux-sctp.rst
> 
> ...
> 
> > +/**
> > + * selinux_netlbl_socket_connect - Label a client-side socket on
> > connect
> > + * @sk: the socket to label
> > + * @addr: the destination address
> > + *
> > + * Description:
> > + * Attempt to label a connected socket with NetLabel using the
> > given address.
> > + * Returns zero values on success, negative values on failure.
> > + *
> > + */
> > +int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr
> > *addr)
> > +{
> > +   int rc;
> > +   struct sk_security_struct *sksec = sk->sk_security;
> > +
> > +   if (sksec->nlbl_state != NLBL_REQSKB &&
> > +   sksec->nlbl_state != NLBL_CONNLABELED)
> > +   return 0;
> > +
> > +   lock_sock(sk);
> > +   rc = selinux_netlbl_socket_connect_helper(sk, addr);
> > release_sock(sk);
> > +
> > return rc;
> >  }
> > +
> > +/**
> > + * selinux_netlbl_socket_connect_locked - Label a client-side
> > socket on
> > + * connect
> > + * @sk: the socket to label
> > + * @addr: the destination address
> > + *
> > + * Description:
> > + * Attempt to label a connected socket that already has the socket
> > locked
> > + * with NetLabel using the given address.
> > + * Returns zero values on success, negative values on failure.
> > + *
> > + */
> > +int selinux_netlbl_socket_connect_locked(struct sock *sk,
> > +struct sockaddr *addr)
> > +{
> > +   struct sk_security_struct *sksec = sk->sk_security;
> > +
> > +   if (sksec->nlbl_state != NLBL_REQSKB &&
> > +   sksec->nlbl_state != NLBL_CONNLABELED)
> > +   return 0;
> > +
> > +   return selinux_netlbl_socket_connect_helper(sk, addr);
> > +}
> 
> [Sorry for the review delay, the holidays and some associated travel
> made it hard to find some quiet time to look at the latest patches.]
> 
> I probably should have been a bit more clear in my last comment, but
> what I had in mind was something like the following:
> 
> int selinux_netlbl_socket_connect_locked(...)
> {
> if (sksec->nlbl_state ...)
> return 0;
> 
> return selinux_netlbl_socket_connect_helper();
> }
> 
> int selinux_netlbl_socket_connect(...)
> {
> int rc;
> 
> lock_sock();
> rc = selinux_netlbl_socket_connect_locked();
> release_sock();
> 
> return rc;
> }
> 
> Yes, you do end up checking nlbl_state while the socket lock is held,
> but I believe the benefit of consolidating the code outweighs any
> additional overhead (I believe it would be "noise" anyway).

Okay I'll send an updated [PATCH V5 4/4] tomorrow.

> 
> Otherwise, this all looks good to me.
> 


[PATCH V4 1/4] security: Add support for SCTP security hooks

2017-12-30 Thread Richard Haines
The SCTP security hooks are explained in:
Documentation/security/LSM-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/LSM-sctp.rst | 175 
 include/linux/lsm_hooks.h   |  36 
 include/linux/security.h|  25 ++
 security/security.c |  22 +
 4 files changed, 258 insertions(+)
 create mode 100644 Documentation/security/LSM-sctp.rst

diff --git a/Documentation/security/LSM-sctp.rst 
b/Documentation/security/LSM-sctp.rst
new file mode 100644
index 000..6e5a392
--- /dev/null
+++ b/Documentation/security/LSM-sctp.rst
@@ -0,0 +1,175 @@
+SCTP LSM Support
+
+
+For security module support, three SCTP specific hooks have been implemented::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+
+Also the following security hook has been utilised::
+
+security_inet_conn_established()
+
+The usage of these hooks are described below with the SELinux implementation
+described in ``Documentation/security/SELinux-sctp.rst``
+
+
+security_sctp_assoc_request()
+-
+Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
+security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+
+security_sctp_bind_connect()
+-
+Passes one or more ipv4/ipv6 addresses to the security module for validation
+based on the ``@optname`` that will result in either a bind or connect
+service as shown in the permission check tables below.
+Returns 0 on success, error on failure.
+::
+
+@sk  - Pointer to sock structure.
+@optname - Name of the option to validate.
+@address - One or more ipv4 / ipv6 addresses.
+@addrlen - The total length of address(s). This is calculated on each
+   ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
+   sizeof(struct sockaddr_in6).
+
+  --
+  | BIND Type Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  |   CONNECT Type Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+A summary of the ``@optname`` entries is as follows::
+
+SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be
+ associated after (optionally) calling
+ bind(3).
+ sctp_bindx(3) adds a set of bind
+ addresses on a socket.
+
+SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple
+addresses for reaching a peer
+(multi-homed).
+sctp_connectx(3) initiates a connection
+on an SCTP socket using multiple
+destination addresses.
+
+SCTP_SENDMSG_CONNECT  - Initiate a connection that is generated by a
+sendmsg(2) or sctp_sendmsg(3) on a new asociation.
+
+SCTP_PRIMARY_ADDR - Set local primary address.
+
+SCTP_SET_PEER_PRIMARY_ADDR - Request peer sets address as
+ association primary.
+
+SCTP_PARAM_ADD_IP  - These are used when Dynamic Address
+SCTP_PARAM_SET_PRIMARY - Reconfiguration is enabled as explained below.
+
+
+To support Dynamic Address Reconfiguration the following parameters must be
+enabled on both endpoints (or use the appropriate **setsockopt**\(2))::
+
+/proc/sys/net/sctp/addip_enable
+/proc/sys/net/sctp/addip_noauth_enable
+
+then the following *_PARAM_*'s are sent to the peer in an
+ASCONF chunk when the corresponding ``@optname``'s are present::
+
+  @optname  ASCONF Parameter
+ ----
+SCTP_SOCKOPT_

[PATCH V4 4/4] selinux: Add SCTP support

2017-12-30 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/SELinux-sctp.rst | 157 ++
 security/selinux/hooks.c| 280 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  21 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 138 ++--
 6 files changed, 570 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.rst

diff --git a/Documentation/security/SELinux-sctp.rst 
b/Documentation/security/SELinux-sctp.rst
new file mode 100644
index 000..2f66bf3
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.rst
@@ -0,0 +1,157 @@
+SCTP SELinux Support
+=
+
+Security Hooks
+===
+
+``Documentation/security/LSM-sctp.rst`` describes the following SCTP security
+hooks with the SELinux specifics expanded below::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+security_inet_conn_established()
+
+
+security_sctp_assoc_request()
+-
+Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
+security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+The security module performs the following operations:
+ IF this is the first association on ``@ep->base.sk``, then set the peer
+ sid to that in ``@skb``. This will ensure there is only one peer sid
+ assigned to ``@ep->base.sk`` that may support multiple associations.
+
+ ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
+ to determine whether the association should be allowed or denied.
+
+ Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
+ MLS portion taken from ``@skb peer sid``. This will be used by SCTP
+ TCP style sockets and peeled off connections as they cause a new socket
+ to be generated.
+
+ If IP security options are configured (CIPSO/CALIPSO), then the ip
+ options are set on the socket.
+
+
+security_sctp_bind_connect()
+-
+Checks permissions required for ipv4/ipv6 addresses based on the ``@optname``
+as follows::
+
+  --
+  |   BIND Permission Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+
+``Documentation/security/LSM-sctp.rst`` gives a summary of the ``@optname``
+entries and also describes ASCONF chunk processing when Dynamic Address
+Reconfiguration is enabled.
+
+
+security_sctp_sk_clone()
+-
+Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
+socket) or when a socket is 'peeled off' e.g userspace calls
+**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
+sockets sid and peer sid to that contained in the ``@ep sid`` and
+``@ep peer sid`` respectively.
+::
+
+@ep - pointer to current sctp endpoint structure.
+@sk - pointer to current sock structure.
+@sk - pointer to new sock structure.
+
+
+security_inet_conn_established()
+-
+Called when a COOKIE ACK is received where it sets the connection's peer sid
+to that in ``@skb``::
+
+@sk  - pointer to sock structure.
+@skb - pointer to skbuff of the COOKIE ACK packet.
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel::
+
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy capability is enabled::
+
+policycap extended_socket_class;
+
+SELinux SCTP support adds the ``name_connect`` perm

[PATCH V4 2/4] sctp: Add ip option support

2017-12-30 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/sctp.h|  4 +++-
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   | 13 -
 net/sctp/ipv6.c| 42 +++---
 net/sctp/output.c  |  5 -
 net/sctp/protocol.c| 36 
 net/sctp/socket.c  |  9 +++--
 7 files changed, 95 insertions(+), 16 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d7d8cba..1b2f40a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -436,9 +436,11 @@ static inline int sctp_list_single_entry(struct list_head 
*head)
 static inline int sctp_frag_point(const struct sctp_association *asoc, int 
pmtu)
 {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
+   struct sctp_af *af = sp->pf->af;
int frag = pmtu;
 
-   frag -= sp->pf->af->net_header_len;
+   frag -= af->ip_options_len(asoc->base.sk);
+   frag -= af->net_header_len;
frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk);
 
if (asoc->user_frag)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 0477945..9942ed5 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -461,6 +461,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -485,6 +486,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 3afac27..9d130f4 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -153,7 +153,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, 
struct sctp_chunk *chu
chunk->msg = msg;
 }
 
-
 /* A data chunk can have a maximum payload of (2^16 - 20).  Break
  * down any such message into smaller chunks.  Opportunistically, fragment
  * the chunks down to the current MTU constraints.  We may get refragmented
@@ -170,6 +169,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_datamsg *msg;
+   struct sctp_sock *sp;
+   struct sctp_af *af;
int err;
 
msg = sctp_datamsg_new(GFP_KERNEL);
@@ -188,9 +189,12 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
/* This is the biggest possible DATA chunk that can fit into
 * the packet
 */
-   max_data = asoc->pathmtu -
-  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
+   sp = sctp_sk(asoc->base.sk);
+   af = sp->pf->af;
+   max_data = asoc->pathmtu - af->net_header_len -
+  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk) -
+  af->ip_options_len(asoc->base.sk);
+
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
@@ -210,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
 
/* Set first_len and then account for possible bundles on first frag */
first_len = max_data;
-
/* Check to see if we have a pending SACK and try to let it be bundled
 * with this message.  Do this if we don't have any data queued already.
 * To check that, look at out_qlen and retransmit list.
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 3b18085..b06dc81 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -423,6 +423,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{
+   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+
+   newnp = inet6_sk(newsk);
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt)
+   opt = ipv6_dup_options(newsk, opt);
+   RCU_INIT_POINTER(newnp->opt, opt);
+   rcu_read_unlock();
+}
+
+/* Account for the IP options */
+static int sctp_v6_ip_options_len(struct sock *sk)
+{
+   struct ipv6_pinfo *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+   

[PATCH V4 3/4] sctp: Add LSM hooks

2017-12-30 Thread Richard Haines
Add security hooks to allow security modules to exercise access control
over SCTP.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h | 10 
 include/uapi/linux/sctp.h  |  1 +
 net/sctp/sm_make_chunk.c   | 12 +
 net/sctp/sm_statefuns.c| 18 ++
 net/sctp/socket.c  | 61 +-
 5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 9942ed5..2ca0a3f 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1271,6 +1271,16 @@ struct sctp_endpoint {
  reconf_enable:1;
 
__u8  strreset_enable;
+
+   /* Security identifiers from incoming (INIT). These are set by
+* security_sctp_assoc_request(). These will only be used by
+* SCTP TCP type sockets and peeled off connections as they
+* cause a new socket to be generated. security_sctp_sk_clone()
+* will then plug these into the new socket.
+*/
+
+   u32 secid;
+   u32 peer_secid;
 };
 
 /* Recover the outter endpoint structure. */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index cfe9712..cafac36 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -123,6 +123,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_RESET_ASSOC   120
 #define SCTP_ADD_STREAMS   121
 #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
+#define SCTP_SENDMSG_CONNECT   123
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE  0x
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 514465b..269fd3d 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3054,6 +3054,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, >source, sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_ADD_IP,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
 * request and does not have the local resources to add this
 * new address to the association, it MUST return an Error
@@ -3120,6 +3126,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, sctp_source(asconf), sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_SET_PRIMARY,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
peer = sctp_assoc_lookup_paddr(asoc, );
if (!peer)
return SCTP_ERROR_DNS_FAILED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8f8ccde..a2dfc5a 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -318,6 +318,11 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
struct sctp_packet *packet;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -905,6 +910,9 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
 */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
 
+   /* Set peer label for connection. */
+   security_inet_conn_established(ep->base.sk, chunk->skb);
+
/* RFC 2960 5.1 Normal Establishment of an Association
 *
 * E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -1433,6 +1441,11 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
struct sctp_packet *packet;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -2103,6 +2116,11 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
}
}
 
+   /* Update socket peer label if first 

[PATCH V4 0/4] Add SELinux SCTP protocol support

2017-12-30 Thread Richard Haines
Note: Some conflicts are expected when merging with current net-next due to
Interleaving Data (I-DATA) sets of patches:
PATCH 2/4 - Where 'sctp_datachk_len(>stream)' has replaced
'sizeof(struct sctp_data_chunk)' in include/net/sctp/sctp.h, 
net/sctp/chunk.c and net/sctp/socket.c 
PATCH 3/4 - Where include/uapi/linux/sctp.h requires a fix to update the
#define SCTP_SENDMSG_CONNECT to a higher number.

These patches have been built on Fedora 27 with kernel 4.14.8 plus
the following userspace patches to enable testing:

1) Updates to libsepol 2.7 to support the sctp portcon statement.
   The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-Add-support-for-the-SCTP-portcon-keyword.patch

2) Updates to the SELinux Test Suite adding SCTP tests. Please read the
   selinux-testsuite/README.sctp for details. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-testsuite-Add-SCTP-test-support.patch

3) Updates to lksctp-tools that show SELinux info in sctp_darn and
   sctp_test. It also contains a minor patch for test_1_to_1_connect.c
   as when CIPSO/CALIPSO configured, NetLabel returns a different error
   code for illegal addresses in test 5. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 lksctp-tools-Add-SELinux-support-to-sctp_test-and-sc.patch

All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.

All SCTP regression tests "./sctp-tests run" run correctly in enforcing
mode. These tests are obtained from: https://github.com/sctp/sctp-tests

The selinux-testsuite patch also adds remote tests (that need some manual
configuration). These are useful for testing CIPSO/CALIPSO over a network
with a number of categories to produce large ip option fields with various
message sizes forcing fragmentation etc..

Changes since RFC Patch:
Removed the NetLabel patch (was [RFC PATCH 4/5] netlabel: Add SCTP support)
as re-engineered. However this patchset will require the NetLabel
patch at [1] to fully run the SCTP selinux-testsuite.

V1 Changes:
PATCH 1/4
Remove unused parameter from security_sctp_assoc_request().
Reformat and update LSM-sctp.rst documentation.
PATCH 2/4
Add variables and RCU locks as requested in [2] to support IP options.
PATCH 3/4
Added security_sctp_assoc_request() hook to sctp_sf_do_unexpected_init()
and sctp_sf_do_5_2_4_dupcook().
Removed security_sctp_assoc_request() hook from sctp_sf_do_5_1C_ack() as
no longer required.
PATCH 4/4
Reformat and update SELinux-sctp.rst documentation.
Remove bindx and connectx permissions.
Rework selinux_socket_connect() and selinux_netlbl_socket_connect() to
utilise helpers for code reuse.
Add spinlock to selinux_sctp_assoc_request().
Remove unused parameter from security_sctp_assoc_request().
Use address->sa_family == AF_INET in *_bind and *_connect to ensure
correct address type.
Minor cleanups.

V2 Changes:
PATCH 4/4 - Remove spin lock from selinux_sctp_assoc_request()
PATCH 4/4 - Fix selinux_sctp_sk_clone() kbuild test robot catch [3]

V3 Changes:
PATCH 2/4 - Account for IP options length in sctp.h sctp_frag_point() by
Marcelo

V4 Changes:
PATCH 1/4 - Move specific SELinux descriptions from LSM-sctp.rst and
lsm_hooks.h to SELinux-sctp.rst in PATCH 4/4
PATCH 4/4 - Rename selinux_netlbl_sctp_socket_connect() to
selinux_netlbl_socket_connect_locked() and move description comments to
selinux_sctp_bind_connect()

[1] https://marc.info/?l=selinux=151061619115945=2
[2] https://marc.info/?l=selinux=150962470215797=2
[3] https://marc.info/?l=selinux=151198281817779=2


Richard Haines (4):
  security: Add support for SCTP security hooks
  sctp: Add ip option support
  sctp: Add LSM hooks
  selinux: Add SCTP support

 Documentation/security/LSM-sctp.rst | 175 
 Documentation/security/SELinux-sctp.rst | 157 ++
 include/linux/lsm_hooks.h   |  36 
 include/linux/security.h|  25 +++
 include/net/sctp/sctp.h |   4 +-
 include/net/sctp/structs.h  |  12 ++
 include/uapi/linux/sctp.h   |   1 +
 net/sctp/chunk.c|  13 +-
 net/sctp/ipv6.c |  42 -
 net/sctp/output.c   |   5 +-
 net/sctp/protocol.c |  36 
 net/sctp/sm_make_chunk.c|  12 ++
 net/sctp/sm_statefuns.c |  18 ++
 net/sctp/socket.c   |  70 +++-
 security/security.c |  22 +++
 security/selinux/hooks.c| 280 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  21 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 138 ++--
 20 files changed, 1024 insertions(+), 49 deletions(-)
 create mode 100644 Documentat

Re: [PATCH v3 1/4] security: Add support for SCTP security hooks

2017-12-27 Thread Richard Haines
On Fri, 2017-12-22 at 15:45 -0200, Marcelo Ricardo Leitner wrote:
> On Fri, Dec 22, 2017 at 09:20:45AM -0800, Casey Schaufler wrote:
> > On 12/22/2017 5:05 AM, Marcelo Ricardo Leitner wrote:
> > > From: Richard Haines <richard_c_hai...@btinternet.com>
> > > 
> > > The SCTP security hooks are explained in:
> > > Documentation/security/LSM-sctp.rst
> 
> Thanks Casey for your comments. However, I'm not that acquainted with
> these area of codes and I cannot work on them. I'll just wait for
> Richard then.

I'm back online and will post a V4 set of patches within a week. These
will address Paul's comments as per [1] and Casey's regarding the
documentation.
Sorry for the delay


[1] https://marc.info/?l=selinux=151274018809822=2

> 
>   Marcelo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" 
> in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2] selinux: Add SCTP support

2017-12-06 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
V2 Changes
Remove lock from selinux_sctp_assoc_request()
Fix selinux_sctp_sk_clone() kbuild test robot catch [1]

[1] https://marc.info/?l=selinux=151198281817779=2

 Documentation/security/SELinux-sctp.rst | 104 
 security/selinux/hooks.c| 270 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  20 ++-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 144 +++--
 6 files changed, 512 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.rst

diff --git a/Documentation/security/SELinux-sctp.rst 
b/Documentation/security/SELinux-sctp.rst
new file mode 100644
index 000..f6a9162
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.rst
@@ -0,0 +1,104 @@
+SCTP SELinux Support
+=
+
+Security Hooks
+===
+
+The ``Documentation/security/LSM-sctp.rst`` document describes how the
+following sctp security hooks are utilised::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+security_inet_conn_established()
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel::
+
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy capability is enabled::
+
+policycap extended_socket_class;
+
+SELinux SCTP support adds the ``name_connect`` permission for connecting
+to a specific port type and the ``association`` permission that is explained
+in the section below.
+
+If userspace tools have been updated, SCTP will support the ``portcon``
+statement as shown in the following example::
+
+portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
+
+
+SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
+
+The hook ``security_sctp_bind_connect()`` is called by SCTP to check
+permissions required for ipv4/ipv6 addresses based on the ``@optname`` as
+follows::
+
+  --
+  |   BIND Permission Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+
+SCTP Peer Labeling
+===
+An SCTP socket will only have one peer label assigned to it. This will be
+assigned during the establishment of the first association. Once the peer
+label has been assigned, any new associations will have the ``association``
+permission validated by checking the socket peer sid against the received
+packets peer sid to determine whether the association should be allowed or
+denied.
+
+NOTES:
+   1) If peer labeling is not enabled, then the peer context will always be
+  ``SECINITSID_UNLABELED`` (``unlabeled_t`` in Reference Policy).
+
+   2) As SCTP can support more than one transport address per endpoint
+  (multi-homing) on a single socket, it is possible to configure policy
+  and NetLabel to provide different peer labels for each of these. As the
+  socket peer label is determined by the first associations transport
+  address, it is recommended that all peer labels are consistent.
+
+   3) **getpeercon**\(3) may be used by userspace to retrieve the sockets peer
+  context.
+
+   4) While not SCTP specific, be aware when using NetLabel that if a label
+  is assigned to a specific interface, and that interface 'goes down',
+  then the NetLabel service will remove the entry. Therefore ensure that
+  the network startup scripts call **netlabelctl**\(8) to set the required
+  label (see **netlabel-config**\(8) helper script for details).
+
+   5) The NetLabel SCTP peer labeling rules apply as dis

Re: [PATCH 4/4] selinux: Add SCTP support

2017-12-04 Thread Richard Haines
On Tue, 2017-11-28 at 14:59 -0500, Stephen Smalley wrote:
> On Tue, 2017-11-28 at 14:39 -0500, Stephen Smalley wrote:
> > On Mon, 2017-11-27 at 19:32 +, Richard Haines wrote:
> > > The SELinux SCTP implementation is explained in:
> > > Documentation/security/SELinux-sctp.rst
> > > 
> > > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > > ---
> > >  Documentation/security/SELinux-sctp.rst | 104 
> > >  security/selinux/hooks.c| 278
> > > +---
> > >  security/selinux/include/classmap.h |   2 +-
> > >  security/selinux/include/netlabel.h |  15 +-
> > >  security/selinux/include/objsec.h   |   4 +
> > >  security/selinux/netlabel.c | 128 +--
> > >  6 files changed, 499 insertions(+), 32 deletions(-)
> > >  create mode 100644 Documentation/security/SELinux-sctp.rst
> > > 
> > > diff --git a/Documentation/security/SELinux-sctp.rst
> > > b/Documentation/security/SELinux-sctp.rst
> > > new file mode 100644
> > > index 000..f6a9162
> > > --- /dev/null
> > > +++ b/Documentation/security/SELinux-sctp.rst
> > > @@ -0,0 +1,104 @@
> > > +SCTP SELinux Support
> > > +=
> > > +
> > > +Security Hooks
> > > +===
> > > +
> > > +The ``Documentation/security/LSM-sctp.rst`` document describes
> > > how
> > > the
> > > +following sctp security hooks are utilised::
> > > +
> > > +security_sctp_assoc_request()
> > > +security_sctp_bind_connect()
> > > +security_sctp_sk_clone()
> > > +security_inet_conn_established()
> > > +
> > > +
> > > +Policy Statements
> > > +==
> > > +The following class and permissions to support SCTP are
> > > available
> > > within the
> > > +kernel::
> > > +
> > > +class sctp_socket inherits socket { node_bind }
> > > +
> > > +whenever the following policy capability is enabled::
> > > +
> > > +policycap extended_socket_class;
> > > +
> > > +SELinux SCTP support adds the ``name_connect`` permission for
> > > connecting
> > > +to a specific port type and the ``association`` permission that
> > > is
> > > explained
> > > +in the section below.
> > > +
> > > +If userspace tools have been updated, SCTP will support the
> > > ``portcon``
> > > +statement as shown in the following example::
> > > +
> > > +portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
> > > +
> > > +
> > > +SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
> > > +
> > > +The hook ``security_sctp_bind_connect()`` is called by SCTP to
> > > check
> > > +permissions required for ipv4/ipv6 addresses based on the ``@opt
> > > na
> > > me
> > > `` as
> > > +follows::
> > > +
> > > +  --
> > > 
> > > +  |   BIND Permission
> > > Checks   |
> > > +  |   @optname | @address
> > > contains |
> > > +  ||
> > > ---|
> > > +  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6
> > > addresses
> > > > 
> > > 
> > > +  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6
> > > address   |
> > > +  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6
> > > address   |
> > > +  --
> > > 
> > > +
> > > +  --
> > > 
> > > +  | CONNECT Permission
> > > Checks  |
> > > +  |   @optname | @address
> > > contains |
> > > +  ||
> > > ---|
> > > +  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6
> > > addresses
> > > > 
> > > 
> > > +  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6
> > > addresses
> > > > 
> > > 
> > &g

[PATCH 2/4] sctp: Add ip option support

2017-11-27 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   | 13 -
 net/sctp/ipv6.c| 42 +++---
 net/sctp/output.c  |  5 -
 net/sctp/protocol.c| 36 
 net/sctp/socket.c  |  8 ++--
 6 files changed, 91 insertions(+), 15 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5ab29af..7767577 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -461,6 +461,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -485,6 +486,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 1323d41..ba15a72 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -153,7 +153,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, 
struct sctp_chunk *chu
chunk->msg = msg;
 }
 
-
 /* A data chunk can have a maximum payload of (2^16 - 20).  Break
  * down any such message into smaller chunks.  Opportunistically, fragment
  * the chunks down to the current MTU constraints.  We may get refragmented
@@ -170,6 +169,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_datamsg *msg;
+   struct sctp_sock *sp;
+   struct sctp_af *af;
int err;
 
msg = sctp_datamsg_new(GFP_KERNEL);
@@ -188,9 +189,12 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
/* This is the biggest possible DATA chunk that can fit into
 * the packet
 */
-   max_data = asoc->pathmtu -
-  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
+   sp = sctp_sk(asoc->base.sk);
+   af = sp->pf->af;
+   max_data = asoc->pathmtu - af->net_header_len -
+  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk) -
+  af->ip_options_len(asoc->base.sk);
+
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
@@ -210,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
 
/* Set first_len and then account for possible bundles on first frag */
first_len = max_data;
-
/* Check to see if we have a pending SACK and try to let it be bundled
 * with this message.  Do this if we don't have any data queued already.
 * To check that, look at out_qlen and retransmit list.
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a4b6ffb..cddd237 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -423,6 +423,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{
+   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+
+   newnp = inet6_sk(newsk);
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt)
+   opt = ipv6_dup_options(newsk, opt);
+   RCU_INIT_POINTER(newnp->opt, opt);
+   rcu_read_unlock();
+}
+
+/* Account for the IP options */
+static int sctp_v6_ip_options_len(struct sock *sk)
+{
+   struct ipv6_pinfo *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+   int len = 0;
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt)
+   len = opt->opt_flen + opt->opt_nflen;
+
+   rcu_read_unlock();
+   return len;
+}
+
 /* Initialize a sockaddr_storage from in incoming skb. */
 static void sctp_v6_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 int is_saddr)
@@ -662,7 +694,6 @@ static struct sock *sctp_v6_create_accept_sk(struct sock 
*sk,
struct sock *newsk;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
-   struct ipv6_txoptions *opt;
 
newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern);
if (!newsk)
@@ -685,12 +716,7 @

[PATCH 4/4] selinux: Add SCTP support

2017-11-27 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/SELinux-sctp.rst | 104 
 security/selinux/hooks.c| 278 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  15 +-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 128 +--
 6 files changed, 499 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.rst

diff --git a/Documentation/security/SELinux-sctp.rst 
b/Documentation/security/SELinux-sctp.rst
new file mode 100644
index 000..f6a9162
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.rst
@@ -0,0 +1,104 @@
+SCTP SELinux Support
+=
+
+Security Hooks
+===
+
+The ``Documentation/security/LSM-sctp.rst`` document describes how the
+following sctp security hooks are utilised::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+security_inet_conn_established()
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel::
+
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy capability is enabled::
+
+policycap extended_socket_class;
+
+SELinux SCTP support adds the ``name_connect`` permission for connecting
+to a specific port type and the ``association`` permission that is explained
+in the section below.
+
+If userspace tools have been updated, SCTP will support the ``portcon``
+statement as shown in the following example::
+
+portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
+
+
+SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
+
+The hook ``security_sctp_bind_connect()`` is called by SCTP to check
+permissions required for ipv4/ipv6 addresses based on the ``@optname`` as
+follows::
+
+  --
+  |   BIND Permission Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+
+SCTP Peer Labeling
+===
+An SCTP socket will only have one peer label assigned to it. This will be
+assigned during the establishment of the first association. Once the peer
+label has been assigned, any new associations will have the ``association``
+permission validated by checking the socket peer sid against the received
+packets peer sid to determine whether the association should be allowed or
+denied.
+
+NOTES:
+   1) If peer labeling is not enabled, then the peer context will always be
+  ``SECINITSID_UNLABELED`` (``unlabeled_t`` in Reference Policy).
+
+   2) As SCTP can support more than one transport address per endpoint
+  (multi-homing) on a single socket, it is possible to configure policy
+  and NetLabel to provide different peer labels for each of these. As the
+  socket peer label is determined by the first associations transport
+  address, it is recommended that all peer labels are consistent.
+
+   3) **getpeercon**\(3) may be used by userspace to retrieve the sockets peer
+  context.
+
+   4) While not SCTP specific, be aware when using NetLabel that if a label
+  is assigned to a specific interface, and that interface 'goes down',
+  then the NetLabel service will remove the entry. Therefore ensure that
+  the network startup scripts call **netlabelctl**\(8) to set the required
+  label (see **netlabel-config**\(8) helper script for details).
+
+   5) The NetLabel SCTP peer labeling rules apply as discussed in the following
+  set of posts tagged "netlabel" at: http://www.paul-moore.com/blog/t.
+
+   6) CIPSO is only supported for IPv4 addressing: 

[PATCH 3/4] sctp: Add LSM hooks

2017-11-27 Thread Richard Haines
Add security hooks to allow security modules to exercise access control
over SCTP.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h | 10 
 include/uapi/linux/sctp.h  |  1 +
 net/sctp/sm_make_chunk.c   | 12 +
 net/sctp/sm_statefuns.c| 18 ++
 net/sctp/socket.c  | 61 +-
 5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 7767577..6e72e3e 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1270,6 +1270,16 @@ struct sctp_endpoint {
  reconf_enable:1;
 
__u8  strreset_enable;
+
+   /* Security identifiers from incoming (INIT). These are set by
+* security_sctp_assoc_request(). These will only be used by
+* SCTP TCP type sockets and peeled off connections as they
+* cause a new socket to be generated. security_sctp_sk_clone()
+* will then plug these into the new socket.
+*/
+
+   u32 secid;
+   u32 peer_secid;
 };
 
 /* Recover the outter endpoint structure. */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 6217ff8..c04812f 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -122,6 +122,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_RESET_ASSOC   120
 #define SCTP_ADD_STREAMS   121
 #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
+#define SCTP_SENDMSG_CONNECT   123
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE  0x
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 6110447..ca4705b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3059,6 +3059,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, >source, sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_ADD_IP,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
 * request and does not have the local resources to add this
 * new address to the association, it MUST return an Error
@@ -3125,6 +3131,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, sctp_source(asconf), sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_SET_PRIMARY,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
peer = sctp_assoc_lookup_paddr(asoc, );
if (!peer)
return SCTP_ERROR_DNS_FAILED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b2a74c3..67c6a7d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -314,6 +314,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
sctp_unrecognized_param_t *unk_param;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -899,6 +904,9 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
 */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
 
+   /* Set peer label for connection. */
+   security_inet_conn_established(ep->base.sk, chunk->skb);
+
/* RFC 2960 5.1 Normal Establishment of an Association
 *
 * E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -1428,6 +1436,11 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sctp_unrecognized_param_t *unk_param;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -2089,6 +2102,11 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net 
*net,
}
}
 
+

[PATCH 0/4] Add SELinux SCTP protocol support

2017-11-27 Thread Richard Haines
The kernel patches have been built on Fedora 27 with kernel 4.13.12 plus
the following userspace patches to enable testing:

1) Updates to libsepol 2.7 to support the sctp portcon statement.
   The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-Add-support-for-the-SCTP-portcon-keyword.patch

2) Updates to the SELinux Test Suite adding SCTP tests. Please read the
   selinux-testsuite/README.sctp for details. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-testsuite-Add-SCTP-test-support.patch

3) Updates to lksctp-tools that show SELinux info in sctp_darn and
   sctp_test. It also contains a minor patch for test_1_to_1_connect.c
   as when CIPSO/CALIPSO configured, NetLabel returns a different error
   code for illegal addresses in test 5. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 lksctp-tools-Add-SELinux-support-to-sctp_test-and-sc.patch

All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.

All SCTP regression tests "./sctp-tests run" run correctly in enforcing
mode. These tests are obtained from: https://github.com/sctp/sctp-tests

The selinux-testsuite patch also adds remote tests (that need some manual
configuration). These are useful for testing CIPSO/CALIPSO over a network
with a number of categories to produce large ip option fields with various
message sizes forcing fragmentation etc..

Changes since RFC Patch:
Removed the NetLabel patch (was [RFC PATCH 4/5] netlabel: Add SCTP support)
as re-engineered. However this patchset will require the NetLabel
patch at [1] to fully run the SCTP selinux-testsuite.

PATCH 1/4
Remove unused parameter from security_sctp_assoc_request().
Reformat and update LSM-sctp.rst documentation.
PATCH 2/4
Add variables and RCU locks as requested in [2] to support IP options.
PATCH 3/4
Added security_sctp_assoc_request() hook to sctp_sf_do_unexpected_init()
and sctp_sf_do_5_2_4_dupcook().
Removed security_sctp_assoc_request() hook from sctp_sf_do_5_1C_ack() as
no longer required.
PATCH 4/4
Reformat and update SELinux-sctp.rst documentation.
Remove bindx and connectx permissions.
Rework selinux_socket_connect() and selinux_netlbl_socket_connect() to
utilise helpers for code reuse.
Add spinlock to selinux_sctp_assoc_request().
Remove unused parameter from security_sctp_assoc_request().
Use address->sa_family == AF_INET in *_bind and *_connect to ensure
correct address type.
Minor cleanups.

[1] https://marc.info/?l=selinux=151061619115945=2
[2] https://marc.info/?l=selinux=150962470215797=2

Richard Haines (4):
  security: Add support for SCTP security hooks
  sctp: Add ip option support
  sctp: Add LSM hooks
  selinux: Add SCTP support

 Documentation/security/LSM-sctp.rst | 194 ++
 Documentation/security/SELinux-sctp.rst | 104 
 include/linux/lsm_hooks.h   |  35 
 include/linux/security.h|  25 +++
 include/net/sctp/structs.h  |  12 ++
 include/uapi/linux/sctp.h   |   1 +
 net/sctp/chunk.c|  13 +-
 net/sctp/ipv6.c |  42 -
 net/sctp/output.c   |   5 +-
 net/sctp/protocol.c |  36 +
 net/sctp/sm_make_chunk.c|  12 ++
 net/sctp/sm_statefuns.c |  18 +++
 net/sctp/socket.c   |  69 +++-
 security/security.c |  22 +++
 security/selinux/hooks.c| 278 +---
 security/selinux/include/classmap.h |   2 +-
 security/selinux/include/netlabel.h |  15 +-
 security/selinux/include/objsec.h   |   4 +
 security/selinux/netlabel.c | 128 +--
 19 files changed, 967 insertions(+), 48 deletions(-)
 create mode 100644 Documentation/security/LSM-sctp.rst
 create mode 100644 Documentation/security/SELinux-sctp.rst

-- 
2.14.3



[PATCH 1/4] security: Add support for SCTP security hooks

2017-11-27 Thread Richard Haines
The SCTP security hooks are explained in:
Documentation/security/LSM-sctp.rst

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/LSM-sctp.rst | 194 
 include/linux/lsm_hooks.h   |  35 +++
 include/linux/security.h|  25 +
 security/security.c |  22 
 4 files changed, 276 insertions(+)
 create mode 100644 Documentation/security/LSM-sctp.rst

diff --git a/Documentation/security/LSM-sctp.rst 
b/Documentation/security/LSM-sctp.rst
new file mode 100644
index 000..6137367
--- /dev/null
+++ b/Documentation/security/LSM-sctp.rst
@@ -0,0 +1,194 @@
+SCTP LSM Support
+
+
+For security module support, three sctp specific hooks have been implemented::
+
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+
+Also the following security hook has been utilised::
+
+security_inet_conn_established()
+
+The usage of these hooks are described below with the SELinux implementation
+described in ``Documentation/security/SELinux-sctp.rst``
+
+
+security_sctp_assoc_request()
+-
+This new hook passes the ``@ep`` and ``@chunk->skb`` (the association INIT
+packet) to the security module. Returns 0 on success, error on failure.
+::
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+
+The security module performs the following operations:
+ IF this is the first association on ``@ep->base.sk``, then set the peer
+ sid to that in ``@skb``. This will ensure there is only one peer sid
+ assigned to ``@ep->base.sk`` that may support multiple associations.
+
+ ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
+ to determine whether the association should be allowed or denied.
+
+ Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
+ MLS portion taken from ``@skb peer sid``. This will be used by SCTP
+ TCP style sockets and peeled off connections as they cause a new socket
+ to be generated.
+
+ If IP security options are configured (CIPSO/CALIPSO), then the ip
+ options are set on the socket.
+
+
+security_sctp_bind_connect()
+-
+This new hook passes one or more ipv4/ipv6 addresses to the security module
+for validation based on the ``@optname`` that will result in either a bind or
+connect service as shown in the permission check tables below.
+Returns 0 on success, error on failure.
+::
+
+@sk  - Pointer to sock structure.
+@optname - Name of the option to validate.
+@address - One or more ipv4 / ipv6 addresses.
+@addrlen - The total length of address(s). This is calculated on each
+   ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
+   sizeof(struct sockaddr_in6).
+
+  --
+  | BIND Type Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  |   CONNECT Type Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+A summary of the ``@optname`` entries is as follows::
+
+SCTP_SOCKOPT_BINDX_ADD - Allows additional bind addresses to be
+ associated after (optionally) calling
+ bind(3).
+ sctp_bindx(3) adds a set of bind
+ addresses on a socket.
+
+SCTP_SOCKOPT_CONNECTX - Allows the allocation of multiple
+addresses for reaching a peer
+(multi-homed).
+sctp_connectx(3) initiates a connection
+on an SCTP socket using multiple
+destination addresses.
+
+SCTP_SENDMSG_CONNECT  - Initiate a connection that is generated by a
+sendmsg(2) or sctp_sendmsg(3) on a new asociation.
+
+

Re: [RFC PATCH 5/5] selinux: Add SCTP support

2017-11-21 Thread Richard Haines
On Mon, 2017-11-20 at 16:55 -0500, Paul Moore wrote:
> On Tue, Nov 14, 2017 at 4:52 PM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > On Mon, 2017-11-13 at 17:40 -0500, Paul Moore wrote:
> > > On Mon, Nov 13, 2017 at 5:05 PM, Richard Haines
> > > <richard_c_hai...@btinternet.com> wrote:
> > > > On Mon, 2017-11-06 at 19:09 -0500, Paul Moore wrote:
> > > > > On Tue, Oct 17, 2017 at 9:59 AM, Richard Haines
> > > > > <richard_c_hai...@btinternet.com> wrote:
> > > > > > The SELinux SCTP implementation is explained in:
> > > > > > Documentation/security/SELinux-sctp.txt
> > > > > > 
> > > > > > Signed-off-by: Richard Haines <richard_c_haines@btinternet.
> > > > > > com>
> > > > > > ---
> > > > > >  Documentation/security/SELinux-sctp.txt | 108
> > > > > > +
> > > > > >  security/selinux/hooks.c| 268
> > > > > > ++--
> > > > > >  security/selinux/include/classmap.h |   3 +-
> > > > > >  security/selinux/include/netlabel.h |   9 +-
> > > > > >  security/selinux/include/objsec.h   |   5 +
> > > > > >  security/selinux/netlabel.c |  52 ++-
> > > > > >  6 files changed, 427 insertions(+), 18 deletions(-)
> > > > > >  create mode 100644 Documentation/security/SELinux-sctp.txt
> > > 
> > > ...
> > > 
> > > > > > +Policy Statements
> > > > > > +==
> > > > > > +The following class and permissions to support SCTP are
> > > > > > available
> > > > > > within the
> > > > > > +kernel:
> > > > > > +class sctp_socket inherits socket { node_bind }
> > > > > > +
> > > > > > +whenever the following policy capability is enabled:
> > > > > > +policycap extended_socket_class;
> > > > > > +
> > > > > > +The SELinux SCTP support adds the additional permissions
> > > > > > that
> > > > > > are
> > > > > > explained
> > > > > > +in the sections below:
> > > > > > +association bindx connectx
> > > > > 
> > > > > Is the distinction between bind and bindx significant?  The
> > > > > same
> > > > > question applies to connect/connectx.  I think we can
> > > > > probably
> > > > > just
> > > > > reuse bind and connect in these cases.
> > > > 
> > > > This has been discussed before with Marcelo and keeping
> > > > bindx/connectx
> > > > is a useful distinction.
> > > 
> > > My apologies, I must have forgotten/missed that discussion.  Do
> > > you
> > > have an archive pointer?
> > 
> > No this was off list, however I've copied the relevant bits:
> > 
> > > SCTP Socket Option Permissions
> > > ===
> > > Permissions that are validated on setsockopt(2) calls (note that
> > > the
> > > sctp_socket SETOPT permission must be allowed):
> > > 
> > > This option requires the BINDX_ADDR permission:
> > > SCTP_SOCKOPT_BINDX_REM - Remove additional bind address.
> > 
> > Can't see an usage for this one.
> > 
> > > 
> > > These options require the SET_PARAMS permission:
> > > SCTP_PEER_ADDR_PARAMS  - Set heartbeats and address max
> > > retransmissions.
> > > SCTP_PEER_ADDR_THLDS  - Set thresholds.
> > > SCTP_ASSOCINFO- Set association / endpoint parameters.
> > 
> > Also for these, considering we are not willing to go as deep as to
> > only
> > allow these if within a given threshold. But still even then,
> > sounds
> > like too much.
> > 
> > > 
> > > 
> > > SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
> > > ==
> > > The hook security_sctp_addr_list() is called by SCTP when
> > > processing
> > > various options (@optname) to check permissions required for the
> > > list
> > > of ipv4/ipv6 addresses (@address) as follows:
> > > 

Re: [RFC PATCH 5/5] selinux: Add SCTP support

2017-11-14 Thread Richard Haines
On Mon, 2017-11-13 at 17:40 -0500, Paul Moore wrote:
> On Mon, Nov 13, 2017 at 5:05 PM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > On Mon, 2017-11-06 at 19:09 -0500, Paul Moore wrote:
> > > On Tue, Oct 17, 2017 at 9:59 AM, Richard Haines
> > > <richard_c_hai...@btinternet.com> wrote:
> > > > The SELinux SCTP implementation is explained in:
> > > > Documentation/security/SELinux-sctp.txt
> > > > 
> > > > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > > > ---
> > > >  Documentation/security/SELinux-sctp.txt | 108 +
> > > >  security/selinux/hooks.c| 268
> > > > ++--
> > > >  security/selinux/include/classmap.h |   3 +-
> > > >  security/selinux/include/netlabel.h |   9 +-
> > > >  security/selinux/include/objsec.h   |   5 +
> > > >  security/selinux/netlabel.c |  52 ++-
> > > >  6 files changed, 427 insertions(+), 18 deletions(-)
> > > >  create mode 100644 Documentation/security/SELinux-sctp.txt
> 
> ...
> 
> > > > +Policy Statements
> > > > +==
> > > > +The following class and permissions to support SCTP are
> > > > available
> > > > within the
> > > > +kernel:
> > > > +class sctp_socket inherits socket { node_bind }
> > > > +
> > > > +whenever the following policy capability is enabled:
> > > > +policycap extended_socket_class;
> > > > +
> > > > +The SELinux SCTP support adds the additional permissions that
> > > > are
> > > > explained
> > > > +in the sections below:
> > > > +association bindx connectx
> > > 
> > > Is the distinction between bind and bindx significant?  The same
> > > question applies to connect/connectx.  I think we can probably
> > > just
> > > reuse bind and connect in these cases.
> > 
> > This has been discussed before with Marcelo and keeping
> > bindx/connectx
> > is a useful distinction.
> 
> My apologies, I must have forgotten/missed that discussion.  Do you
> have an archive pointer?

No this was off list, however I've copied the relevant bits:

> SCTP Socket Option Permissions
> ===
> Permissions that are validated on setsockopt(2) calls (note that the
> sctp_socket SETOPT permission must be allowed):
>
> This option requires the BINDX_ADDR permission:
> SCTP_SOCKOPT_BINDX_REM - Remove additional bind address.

Can't see an usage for this one.

>
> These options require the SET_PARAMS permission:
> SCTP_PEER_ADDR_PARAMS  - Set heartbeats and address max
> retransmissions.
> SCTP_PEER_ADDR_THLDS  - Set thresholds.
> SCTP_ASSOCINFO- Set association / endpoint parameters.

Also for these, considering we are not willing to go as deep as to only
allow these if within a given threshold. But still even then, sounds
like too much.

>
>
> SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
> ==
> The hook security_sctp_addr_list() is called by SCTP when processing
> various options (@optname) to check permissions required for the list
> of ipv4/ipv6 addresses (@address) as follows:
> 
> |sctp_socket BIND type permission checks  |
> |(The socket must also have the BIND permission)  |
> |  @optname| Permission  |  @address  |
> |--|-|-|
> |SCTP_SOCKOPT_BINDX_ADD|BINDX_ADDRS  |One or more ipv4/ipv6 adr|

This one can be useful, for that privilege-dropping case.

Paul note: I later changed BINDX_ADDRS to just BINDX

> |SCTP_PRIMARY_ADDR|SET_PRI_ADDR |Single ipv4 or ipv6 adr  |
> |SCTP_SET_PEER_PRIMARY_ADDR|SET_PEER_ADDR|Single ipv4 or ipv6 adr  |

But these, can't use an use-case.

> 
> 
> |sctp_socket CONNECT type permission checks|
> |(The socket must also have the CONNECT permission)|
> |  @optname| Permission  |  @address  |
> |--|-|-|
> |SCTP_SOCKOPT_CONNECTX|CONNECTX|One or more ipv4/ipv6 adr|
> |SCTP_PARAM_ADD_IP|BINDX_ADDRS  |One or more ipv4/ip

Re: [RFC PATCH 5/5] selinux: Add SCTP support

2017-11-13 Thread Richard Haines
On Mon, 2017-11-06 at 19:09 -0500, Paul Moore wrote:
> On Tue, Oct 17, 2017 at 9:59 AM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > The SELinux SCTP implementation is explained in:
> > Documentation/security/SELinux-sctp.txt
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  Documentation/security/SELinux-sctp.txt | 108 +
> >  security/selinux/hooks.c| 268
> > ++--
> >  security/selinux/include/classmap.h |   3 +-
> >  security/selinux/include/netlabel.h |   9 +-
> >  security/selinux/include/objsec.h   |   5 +
> >  security/selinux/netlabel.c |  52 ++-
> >  6 files changed, 427 insertions(+), 18 deletions(-)
> >  create mode 100644 Documentation/security/SELinux-sctp.txt
> > 
> > diff --git a/Documentation/security/SELinux-sctp.txt
> > b/Documentation/security/SELinux-sctp.txt
> > new file mode 100644
> > index 000..32e0255
> > --- /dev/null
> > +++ b/Documentation/security/SELinux-sctp.txt
> > @@ -0,0 +1,108 @@
> 
> See my previous comments about moving to reStructuredText for these
> docs.

Done
> 
> > +   SCTP SELinux Support
> > +  ==
> > +
> > +Security Hooks
> > +===
> > +
> > +The Documentation/security/LSM-sctp.txt document describes how the
> > following
> > +sctp security hooks are utilised:
> > +security_sctp_assoc_request()
> > +security_sctp_bind_connect()
> > +security_sctp_sk_clone()
> > +
> > +security_inet_conn_established()
> > +
> > +
> > +Policy Statements
> > +==
> > +The following class and permissions to support SCTP are available
> > within the
> > +kernel:
> > +class sctp_socket inherits socket { node_bind }
> > +
> > +whenever the following policy capability is enabled:
> > +policycap extended_socket_class;
> > +
> > +The SELinux SCTP support adds the additional permissions that are
> > explained
> > +in the sections below:
> > +association bindx connectx
> 
> Is the distinction between bind and bindx significant?  The same
> question applies to connect/connectx.  I think we can probably just
> reuse bind and connect in these cases.

This has been discussed before with Marcelo and keeping bindx/connectx
is a useful distinction.
> 
> See my question on sctp_socket:association below.
> 
> > +If userspace tools have been updated, SCTP will support the
> > portcon
> > +statement as shown in the following example:
> > +portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
> > +
> > +
> > +SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
> > +
> > +The hook security_sctp_bind_connect() is called by SCTP to check
> > permissions
> > +required for ipv4/ipv6 addresses based on the @optname as follows:
> > +
> > +  --
> > 
> > +  |  BINDX Permission
> > Check|
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses
> > |
> > +  --
> > 
> > +
> > +  --
> > 
> > +  |  BIND Permission
> > Checks|
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6
> > address   |
> > +  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6
> > address   |
> > +  --
> > 
> > +
> > +  --
> > 
> > +  | CONNECTX Permission
> > Check  |
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_SOCKOPT_CONNECTX  | One or 

[PATCH] netlabel: If PF_INET6, check sk_buff ip header version

2017-11-13 Thread Richard Haines
When resolving a fallback label, check the sk_buff version as it
is possible (e.g. SCTP) to have family = PF_INET6 while
receiving ip_hdr(skb)->version = 4.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 net/netlabel/netlabel_unlabeled.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 22dc1b9..c070dfc 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1472,6 +1472,16 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
iface = rcu_dereference(netlbl_unlhsh_def);
if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel;
+
+#if IS_ENABLED(CONFIG_IPV6)
+   /* When resolving a fallback label, check the sk_buff version as
+* it is possible (e.g. SCTP) to have family = PF_INET6 while
+* receiving ip_hdr(skb)->version = 4.
+*/
+   if (family == PF_INET6 && ip_hdr(skb)->version == 4)
+   family = PF_INET;
+#endif /* IPv6 */
+
switch (family) {
case PF_INET: {
struct iphdr *hdr4;
-- 
2.13.6



Re: [RFC PATCH 4/5] netlabel: Add SCTP support

2017-11-13 Thread Richard Haines
On Mon, 2017-11-06 at 18:15 -0500, Paul Moore wrote:
> On Tue, Oct 17, 2017 at 9:58 AM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > Add support to label SCTP associations and cater for a situation
> > where
> > family = PF_INET6 with an ip_hdr(skb)->version = 4.
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  include/net/netlabel.h|  3 ++
> >  net/netlabel/netlabel_kapi.c  | 80
> > +++
> >  net/netlabel/netlabel_unlabeled.c | 10 +
> >  3 files changed, 93 insertions(+)
> > 
> > diff --git a/include/net/netlabel.h b/include/net/netlabel.h
> > index 72d6435..7348966 100644
> > --- a/include/net/netlabel.h
> > +++ b/include/net/netlabel.h
> > @@ -494,6 +494,9 @@ int netlbl_conn_setattr(struct sock *sk,
> > const struct netlbl_lsm_secattr *secattr);
> >  int netlbl_req_setattr(struct request_sock *req,
> >const struct netlbl_lsm_secattr *secattr);
> > +int netlbl_sctp_setattr(struct sock *sk,
> > +   struct sk_buff *skb,
> > +   const struct netlbl_lsm_secattr *secattr);
> >  void netlbl_req_delattr(struct request_sock *req);
> >  int netlbl_skbuff_setattr(struct sk_buff *skb,
> >   u16 family,
> > diff --git a/net/netlabel/netlabel_kapi.c
> > b/net/netlabel/netlabel_kapi.c
> > index ea7c670..1c82bbe 100644
> > --- a/net/netlabel/netlabel_kapi.c
> > +++ b/net/netlabel/netlabel_kapi.c
> > @@ -1121,6 +1121,7 @@ int netlbl_conn_setattr(struct sock *sk,
> > switch (addr->sa_family) {
> > case AF_INET:
> > addr4 = (struct sockaddr_in *)addr;
> > +
> 
> I'm guessing this bit of extra whitespace was an accident; but just
> in
> case, drop it from this patch please.
Done
> 
> > entry = netlbl_domhsh_getentry_af4(secattr->domain,
> >addr4-
> > >sin_addr.s_addr);
> > if (entry == NULL) {
> > @@ -1177,6 +1178,85 @@ int netlbl_conn_setattr(struct sock *sk,
> >  }
> > 
> >  /**
> > + * netlbl_sctp_setattr - Label an incoming sctp association socket
> > using
> > + * the correct protocol
> > + * @sk: the socket to label
> > + * @skb: the packet
> > + * @secattr: the security attributes
> > + *
> > + * Description:
> > + * Attach the correct label to the given socket using the security
> > attributes
> > + * specified in @secattr.  Returns zero on success, negative
> > values on failure.
> > + *
> > + */
> > +int netlbl_sctp_setattr(struct sock *sk,
> > +   struct sk_buff *skb,
> > +   const struct netlbl_lsm_secattr *secattr)
> > +{
> > +   int ret_val = -EINVAL;
> > +   struct netlbl_dommap_def *entry;
> > +   struct iphdr *hdr4;
> > +#if IS_ENABLED(CONFIG_IPV6)
> > +   struct ipv6hdr *hdr6;
> > +#endif
> > +
> > +   rcu_read_lock();
> > +   switch (sk->sk_family) {
> > +   case AF_INET:
> > +   hdr4 = ip_hdr(skb);
> > +
> > +   entry = netlbl_domhsh_getentry_af4(secattr->domain,
> > +  hdr4->saddr);
> > +   if (entry == NULL) {
> > +   ret_val = -ENOENT;
> > +   goto sctp_setattr_return;
> > +   }
> > +   switch (entry->type) {
> > +   case NETLBL_NLTYPE_CIPSOV4:
> > +   ret_val = cipso_v4_sock_setattr(sk, entry-
> > >cipso,
> > +   secattr);
> > +   break;
> > +   case NETLBL_NLTYPE_UNLABELED:
> > +   netlbl_sock_delattr(sk);
> > +   ret_val = 0;
> > +   break;
> > +   default:
> > +   ret_val = -ENOENT;
> > +   }
> > +   break;
> > +#if IS_ENABLED(CONFIG_IPV6)
> > +   case AF_INET6:
> > +   hdr6 = ipv6_hdr(skb);
> > +   entry = netlbl_domhsh_getentry_af6(secattr->domain,
> > +  >saddr);
> > +   if (entry == NULL) {
> > +   ret_val = -ENOENT;
> > +  

Re: [RFC PATCH 1/5] security: Add support for SCTP security hooks

2017-11-01 Thread Richard Haines
On Tue, 2017-10-31 at 14:41 -0200, Marcelo Ricardo Leitner wrote:
> On Tue, Oct 17, 2017 at 03:02:47PM +0100, Richard Haines wrote:
> > The SCTP security hooks are explained in:
> > Documentation/security/LSM-sctp.txt
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  Documentation/security/LSM-sctp.txt | 212
> > 
> >  include/linux/lsm_hooks.h   |  37 +++
> >  include/linux/security.h|  27 +
> >  security/security.c |  23 
> >  4 files changed, 299 insertions(+)
> >  create mode 100644 Documentation/security/LSM-sctp.txt
> > 
> > diff --git a/Documentation/security/LSM-sctp.txt
> > b/Documentation/security/LSM-sctp.txt
> > new file mode 100644
> > index 000..30fe9b5
> > --- /dev/null
> > +++ b/Documentation/security/LSM-sctp.txt
> > @@ -0,0 +1,212 @@
> > +   SCTP LSM Support
> > +  ==
> > +
> > +For security module support, three sctp specific hooks have been
> > implemented:
> > +security_sctp_assoc_request()
> > +security_sctp_bind_connect()
> > +security_sctp_sk_clone()
> > +
> > +Also the following security hook has been utilised:
> > +security_inet_conn_established()
> > +
> > +The usage of these hooks are described below with the SELinux
> > implementation
> > +described in Documentation/security/SELinux-sctp.txt
> > +
> > +
> > +security_sctp_assoc_request()
> > +--
> > +This new hook has been added to net/sctp/sm_statefuns.c where it
> > passes the
> > +@ep and @chunk->skb (the association INIT or INIT ACK packet) to
> > the security
> > +module. Returns 0 on success, error on failure.
> > +
> > +@ep - pointer to sctp endpoint structure.
> > +@skb - pointer to skbuff of association packet.
> > +@sctp_cid - set to sctp packet type (SCTP_CID_INIT or
> > SCTP_CID_INIT_ACK).
> > +
> > +The security module performs the following operations:
> > +  1) If this is the first association on @ep->base.sk, then set
> > the peer sid
> > + to that in @skb. This will ensure there is only one peer sid
> > assigned
> > + to @ep->base.sk that may support multiple associations.
> > +
> > +  2) If not the first association, validate the @ep->base.sk
> > peer_sid against
> > + the @skb peer sid to determine whether the association should
> > be allowed
> > + or denied.
> > +
> > +  3) If @sctp_cid = SCTP_CID_INIT, then set the sctp @ep sid to
> > socket's sid
> > + (from ep->base.sk) with MLS portion taken from @skb peer sid.
> > This will
> > + only be used by SCTP TCP style sockets and peeled off
> > connections as they
> > + cause a new socket to be generated.
> > +
> > + If IP security options are configured (CIPSO/CALIPSO), then
> > the ip options
> > + are set on the socket.
> > +
> > + To support this hook include/net/sctp/structs.h "struct
> > sctp_endpoint"
> > + has been updated with the following:
> > +
> > +   /* Security identifiers from incoming (INIT). These are
> > set by
> > +* security_sctp_assoc_request(). These will only be used
> > by
> > +* SCTP TCP type sockets and peeled off connections as
> > they
> > +* cause a new socket to be generated.
> > security_sctp_sk_clone()
> > +* will then plug these into the new socket.
> > +*/
> > +   u32 secid;
> > +   u32 peer_secid;
> > +
> > +
> > +security_sctp_bind_connect()
> > +-
> > +This new hook has been added to net/sctp/socket.c and
> > net/sctp/sm_make_chunk.c.
> > +It passes one or more ipv4/ipv6 addresses to the security module
> > for
> > +validation based on the @optname that will result in either a bind
> > or connect
> > +service as shown in the permission check tables below.
> > +Returns 0 on success, error on failure.
> > +
> > +@sk  - Pointer to sock structure.
> > +@optname - Name of the option to validate.
> > +@address - One or more ipv4 / ipv6 addresses.
> > +@addrlen - The total length of address(s). This is calculated
> 

Re: [RFC PATCH 2/5] sctp: Add ip option support

2017-11-01 Thread Richard Haines
On Tue, 2017-10-31 at 15:06 -0200, Marcelo Ricardo Leitner wrote:
> Hello,
> 
> On Tue, Oct 17, 2017 at 02:58:06PM +0100, Richard Haines wrote:
> > Add ip option support to allow LSM security modules to utilise
> > CIPSO/IPv4
> > and CALIPSO/IPv6 services.
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  include/net/sctp/structs.h |  2 ++
> >  net/sctp/chunk.c   |  7 ---
> >  net/sctp/ipv6.c| 37 ++--
> > -
> >  net/sctp/output.c  |  3 ++-
> >  net/sctp/protocol.c| 36
> > 
> >  net/sctp/socket.c  |  5 -
> >  6 files changed, 78 insertions(+), 12 deletions(-)
> > 
> > diff --git a/include/net/sctp/structs.h
> > b/include/net/sctp/structs.h
> > index 5ab29af..7767577 100644
> > --- a/include/net/sctp/structs.h
> > +++ b/include/net/sctp/structs.h
> > @@ -461,6 +461,7 @@ struct sctp_af {
> > void(*ecn_capable)(struct sock *sk);
> > __u16   net_header_len;
> > int sockaddr_len;
> > +   int (*ip_options_len)(struct sock *sk);
> > sa_family_t sa_family;
> > struct list_head list;
> >  };
> > @@ -485,6 +486,7 @@ struct sctp_pf {
> > int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr
> > *addr);
> > void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
> > void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> > +   void (*copy_ip_options)(struct sock *sk, struct sock
> > *newsk);
> > struct sctp_af *af;
> >  };
> >  
> > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > index 1323d41..e49e240 100644
> > --- a/net/sctp/chunk.c
> > +++ b/net/sctp/chunk.c
> > @@ -153,7 +153,6 @@ static void sctp_datamsg_assign(struct
> > sctp_datamsg *msg, struct sctp_chunk *chu
> > chunk->msg = msg;
> >  }
> >  
> > -
> >  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
> >   * down any such message into smaller chunks.  Opportunistically,
> > fragment
> >   * the chunks down to the current MTU constraints.  We may get
> > refragmented
> > @@ -190,7 +189,10 @@ struct sctp_datamsg
> > *sctp_datamsg_from_user(struct sctp_association *asoc,
> >  */
> > max_data = asoc->pathmtu -
> >sctp_sk(asoc->base.sk)->pf->af->net_header_len
> > -
> 
> 
> > -  sizeof(struct sctphdr) - sizeof(struct
> > sctp_data_chunk);
> > +  sizeof(struct sctphdr) - sizeof(struct
> > sctp_data_chunk) -
> > +  sctp_sk(asoc->base.sk)->pf->af->
> 
> 
> > +  ip_options_len(asoc->base.sk);
> 
> Please add a var for sctp_sk(asoc->base.sk)->pf->af. That should also
> help to not break the dereferencing into multiple lines.
DONE
> 
> > +
> > max_data = SCTP_TRUNC4(max_data);
> >  
> > /* If the the peer requested that we authenticate DATA
> > chunks
> > @@ -210,7 +212,6 @@ struct sctp_datamsg
> > *sctp_datamsg_from_user(struct sctp_association *asoc,
> >  
> > /* Set first_len and then account for possible bundles on
> > first frag */
> > first_len = max_data;
> > -
> > /* Check to see if we have a pending SACK and try to let
> > it be bundled
> >  * with this message.  Do this if we don't have any data
> > queued already.
> >  * To check that, look at out_qlen and retransmit list.
> > diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> > index a4b6ffb..49c9011 100644
> > --- a/net/sctp/ipv6.c
> > +++ b/net/sctp/ipv6.c
> > @@ -423,6 +423,33 @@ static void sctp_v6_copy_addrlist(struct
> > list_head *addrlist,
> > rcu_read_unlock();
> >  }
> >  
> > +/* Copy over any ip options */
> > +static void sctp_v6_copy_ip_options(struct sock *sk, struct sock
> > *newsk)
> > +{
> > +   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
> > +   struct ipv6_txoptions *opt;
> > +
> > +   newnp = inet6_sk(newsk);
> > +
> > +   rcu_read_lock();
> > +   opt = rcu_dereference(np->opt);
> > +   if (opt)
> > +   opt = ipv6_dup_options(newsk, opt);
> > +   RCU_INIT_POINTER(newnp->opt, opt);
> > +   rcu_read_unlock();
> > +}
> > +
> > +/* Account for the IP options */
>

Re: [RFC PATCH 5/5] selinux: Add SCTP support

2017-11-01 Thread Richard Haines
On Tue, 2017-10-31 at 15:16 -0200, Marcelo Ricardo Leitner wrote:
> On Tue, Oct 17, 2017 at 02:59:53PM +0100, Richard Haines wrote:
> > The SELinux SCTP implementation is explained in:
> > Documentation/security/SELinux-sctp.txt
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> 
> ...
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 33fd061..c3e9600 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> 
> ...
> > @@ -4521,7 +4565,14 @@ static int selinux_socket_connect(struct
> > socket *sock, struct sockaddr *address,
> > unsigned short snum;
> > u32 sid, perm;
> >  
> > -   if (sk->sk_family == PF_INET) {
> > +   /* sctp_connectx(3) calls via
> > +*selinux_sctp_bind_connect() that validates
> > multiple
> > +* connect addresses. Because of this need to
> > check
> > +* address->sa_family as it is possible to have
> > +* sk->sk_family = PF_INET6 with addr->sa_family =
> > AF_INET.
> > +*/
> > +   if (sk->sk_family == PF_INET ||
> > +   address->sa_family ==
> > AF_INET) {
> 
> Not sure which code style applies on this file but the if () above
> looks odd. At least, checkpatch.pl complained about it.
Changed to read:
if (sk->sk_family == PF_INET ||
address->sa_family == AF_INET) {

> 
>   Marcelo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> security-module" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 3/5] sctp: Add LSM hooks

2017-10-24 Thread Richard Haines
On Fri, 2017-10-20 at 21:14 +0800, Xin Long wrote:
> On Fri, Oct 20, 2017 at 8:04 PM, Richard Haines
> <richard_c_hai...@btinternet.com> wrote:
> > On Fri, 2017-10-20 at 07:16 -0400, Neil Horman wrote:
> > > On Wed, Oct 18, 2017 at 11:05:09PM +0800, Xin Long wrote:
> > > > On Tue, Oct 17, 2017 at 9:58 PM, Richard Haines
> > > > <richard_c_hai...@btinternet.com> wrote:
> > > > > Add security hooks to allow security modules to exercise
> > > > > access
> > > > > control
> > > > > over SCTP.
> > > > > 
> > > > > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.co
> > > > > m>
> > > > > ---
> > > > >  include/net/sctp/structs.h | 10 
> > > > >  include/uapi/linux/sctp.h  |  1 +
> > > > >  net/sctp/sm_make_chunk.c   | 12 +
> > > > >  net/sctp/sm_statefuns.c| 14 ++-
> > > > >  net/sctp/socket.c  | 61
> > > > > +-
> > > > >  5 files changed, 96 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/include/net/sctp/structs.h
> > > > > b/include/net/sctp/structs.h
> > > > > index 7767577..6e72e3e 100644
> > > > > --- a/include/net/sctp/structs.h
> > > > > +++ b/include/net/sctp/structs.h
> > > > > @@ -1270,6 +1270,16 @@ struct sctp_endpoint {
> > > > >   reconf_enable:1;
> > > > > 
> > > > > __u8  strreset_enable;
> > > > > +
> > > > > +   /* Security identifiers from incoming (INIT). These
> > > > > are
> > > > > set by
> > > > > +* security_sctp_assoc_request(). These will only be
> > > > > used
> > > > > by
> > > > > +* SCTP TCP type sockets and peeled off connections
> > > > > as
> > > > > they
> > > > > +* cause a new socket to be generated.
> > > > > security_sctp_sk_clone()
> > > > > +* will then plug these into the new socket.
> > > > > +*/
> > > > > +
> > > > > +   u32 secid;
> > > > > +   u32 peer_secid;
> > > > >  };
> > > > > 
> > > > >  /* Recover the outter endpoint structure. */
> > > > > diff --git a/include/uapi/linux/sctp.h
> > > > > b/include/uapi/linux/sctp.h
> > > > > index 6217ff8..c04812f 100644
> > > > > --- a/include/uapi/linux/sctp.h
> > > > > +++ b/include/uapi/linux/sctp.h
> > > > > @@ -122,6 +122,7 @@ typedef __s32 sctp_assoc_t;
> > > > >  #define SCTP_RESET_ASSOC   120
> > > > >  #define SCTP_ADD_STREAMS   121
> > > > >  #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
> > > > > +#define SCTP_SENDMSG_CONNECT   123
> > > > > 
> > > > >  /* PR-SCTP policies */
> > > > >  #define SCTP_PR_SCTP_NONE  0x
> > > > > diff --git a/net/sctp/sm_make_chunk.c
> > > > > b/net/sctp/sm_make_chunk.c
> > > > > index 6110447..ca4705b 100644
> > > > > --- a/net/sctp/sm_make_chunk.c
> > > > > +++ b/net/sctp/sm_make_chunk.c
> > > > > @@ -3059,6 +3059,12 @@ static __be16
> > > > > sctp_process_asconf_param(struct sctp_association *asoc,
> > > > > if (af->is_any())
> > > > > memcpy(, >source,
> > > > > sizeof(addr));
> > > > > 
> > > > > +   if (security_sctp_bind_connect(asoc->ep-
> > > > > >base.sk,
> > > > > +  SCTP_PARAM_ADD
> > > > > _IP,
> > > > > +  (struct
> > > > > sockaddr
> > > > > *),
> > > > > +  af-
> > > > > >sockaddr_len))
> > > > > +   return SCTP_ERROR_REQ_REFUSED;
> > > > > +
> > > > > /* ADDIP 4.3 D9) If an endpoint receives an
> > > > > ADD
> > > > > IP address
> > > > >  * request and does not have the local
> > > > > resources
> &

Re: [RFC PATCH 5/5] selinux: Add SCTP support

2017-10-24 Thread Richard Haines
On Fri, 2017-10-20 at 15:00 -0400, Stephen Smalley wrote:
> On Tue, 2017-10-17 at 14:59 +0100, Richard Haines wrote:
> > The SELinux SCTP implementation is explained in:
> > Documentation/security/SELinux-sctp.txt
> > 
> > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > ---
> >  Documentation/security/SELinux-sctp.txt | 108 +
> >  security/selinux/hooks.c| 268
> > ++--
> >  security/selinux/include/classmap.h |   3 +-
> >  security/selinux/include/netlabel.h |   9 +-
> >  security/selinux/include/objsec.h   |   5 +
> >  security/selinux/netlabel.c |  52 ++-
> >  6 files changed, 427 insertions(+), 18 deletions(-)
> >  create mode 100644 Documentation/security/SELinux-sctp.txt
> > 
> > diff --git a/Documentation/security/SELinux-sctp.txt
> > b/Documentation/security/SELinux-sctp.txt
> > new file mode 100644
> > index 000..32e0255
> > --- /dev/null
> > +++ b/Documentation/security/SELinux-sctp.txt
> > @@ -0,0 +1,108 @@
> > +   SCTP SELinux Support
> > +  ==
> > +
> > +Security Hooks
> > +===
> > +
> > +The Documentation/security/LSM-sctp.txt document describes how the
> > following
> > +sctp security hooks are utilised:
> > +security_sctp_assoc_request()
> > +security_sctp_bind_connect()
> > +security_sctp_sk_clone()
> > +
> > +security_inet_conn_established()
> > +
> > +
> > +Policy Statements
> > +==
> > +The following class and permissions to support SCTP are available
> > within the
> > +kernel:
> > +class sctp_socket inherits socket { node_bind }
> > +
> > +whenever the following policy capability is enabled:
> > +policycap extended_socket_class;
> > +
> > +The SELinux SCTP support adds the additional permissions that are
> > explained
> > +in the sections below:
> > +association bindx connectx
> > +
> > +If userspace tools have been updated, SCTP will support the
> > portcon
> > +statement as shown in the following example:
> > +portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
> > +
> > +
> > +SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
> > +
> > +The hook security_sctp_bind_connect() is called by SCTP to check
> > permissions
> > +required for ipv4/ipv6 addresses based on the @optname as follows:
> > +
> > +  --
> > 
> > +  |  BINDX Permission
> > Check|
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses
> > |
> > +  --
> > 
> > +
> > +  --
> > 
> > +  |  BIND Permission
> > Checks|
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6
> > address   |
> > +  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6
> > address   |
> > +  --
> > 
> > +
> > +  --
> > 
> > +  | CONNECTX Permission
> > Check  |
> > +  |   @optname | @address
> > contains |
> > +  ||
> > ---|
> > +  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses
> > |
> > +  --
> > 
> > +
> > +  --
> > 
> > +  | CONNECT Permission
> > Checks  |
> > +  |   @optname | @address
> > contains |
> > +  ||
> >

Re: [RFC PATCH 3/5] sctp: Add LSM hooks

2017-10-20 Thread Richard Haines
On Fri, 2017-10-20 at 07:16 -0400, Neil Horman wrote:
> On Wed, Oct 18, 2017 at 11:05:09PM +0800, Xin Long wrote:
> > On Tue, Oct 17, 2017 at 9:58 PM, Richard Haines
> > <richard_c_hai...@btinternet.com> wrote:
> > > Add security hooks to allow security modules to exercise access
> > > control
> > > over SCTP.
> > > 
> > > Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
> > > ---
> > >  include/net/sctp/structs.h | 10 
> > >  include/uapi/linux/sctp.h  |  1 +
> > >  net/sctp/sm_make_chunk.c   | 12 +
> > >  net/sctp/sm_statefuns.c| 14 ++-
> > >  net/sctp/socket.c  | 61
> > > +-
> > >  5 files changed, 96 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/include/net/sctp/structs.h
> > > b/include/net/sctp/structs.h
> > > index 7767577..6e72e3e 100644
> > > --- a/include/net/sctp/structs.h
> > > +++ b/include/net/sctp/structs.h
> > > @@ -1270,6 +1270,16 @@ struct sctp_endpoint {
> > >   reconf_enable:1;
> > > 
> > > __u8  strreset_enable;
> > > +
> > > +   /* Security identifiers from incoming (INIT). These are
> > > set by
> > > +* security_sctp_assoc_request(). These will only be used
> > > by
> > > +* SCTP TCP type sockets and peeled off connections as
> > > they
> > > +* cause a new socket to be generated.
> > > security_sctp_sk_clone()
> > > +* will then plug these into the new socket.
> > > +*/
> > > +
> > > +   u32 secid;
> > > +   u32 peer_secid;
> > >  };
> > > 
> > >  /* Recover the outter endpoint structure. */
> > > diff --git a/include/uapi/linux/sctp.h
> > > b/include/uapi/linux/sctp.h
> > > index 6217ff8..c04812f 100644
> > > --- a/include/uapi/linux/sctp.h
> > > +++ b/include/uapi/linux/sctp.h
> > > @@ -122,6 +122,7 @@ typedef __s32 sctp_assoc_t;
> > >  #define SCTP_RESET_ASSOC   120
> > >  #define SCTP_ADD_STREAMS   121
> > >  #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
> > > +#define SCTP_SENDMSG_CONNECT   123
> > > 
> > >  /* PR-SCTP policies */
> > >  #define SCTP_PR_SCTP_NONE  0x
> > > diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> > > index 6110447..ca4705b 100644
> > > --- a/net/sctp/sm_make_chunk.c
> > > +++ b/net/sctp/sm_make_chunk.c
> > > @@ -3059,6 +3059,12 @@ static __be16
> > > sctp_process_asconf_param(struct sctp_association *asoc,
> > > if (af->is_any())
> > > memcpy(, >source,
> > > sizeof(addr));
> > > 
> > > +   if (security_sctp_bind_connect(asoc->ep->base.sk,
> > > +  SCTP_PARAM_ADD_IP,
> > > +  (struct sockaddr
> > > *),
> > > +  af->sockaddr_len))
> > > +   return SCTP_ERROR_REQ_REFUSED;
> > > +
> > > /* ADDIP 4.3 D9) If an endpoint receives an ADD
> > > IP address
> > >  * request and does not have the local resources
> > > to add this
> > >  * new address to the association, it MUST return
> > > an Error
> > > @@ -3125,6 +3131,12 @@ static __be16
> > > sctp_process_asconf_param(struct sctp_association *asoc,
> > > if (af->is_any())
> > > memcpy(, sctp_source(asconf),
> > > sizeof(addr));
> > > 
> > > +   if (security_sctp_bind_connect(asoc->ep->base.sk,
> > > +  SCTP_PARAM_SET_PRI
> > > MARY,
> > > +  (struct sockaddr
> > > *),
> > > +  af->sockaddr_len))
> > > +   return SCTP_ERROR_REQ_REFUSED;
> > > +
> > > peer = sctp_assoc_lookup_paddr(asoc, );
> > > if (!peer)
> > > return SCTP_ERROR_DNS_FAILED;
> > > diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
> > > index b2a74c3..4ba5805 100644
> > > --- a/net/sctp/sm_statefuns.c
> > &

[RFC PATCH 1/5] security: Add support for SCTP security hooks

2017-10-17 Thread Richard Haines
The SCTP security hooks are explained in:
Documentation/security/LSM-sctp.txt

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/LSM-sctp.txt | 212 
 include/linux/lsm_hooks.h   |  37 +++
 include/linux/security.h|  27 +
 security/security.c |  23 
 4 files changed, 299 insertions(+)
 create mode 100644 Documentation/security/LSM-sctp.txt

diff --git a/Documentation/security/LSM-sctp.txt 
b/Documentation/security/LSM-sctp.txt
new file mode 100644
index 000..30fe9b5
--- /dev/null
+++ b/Documentation/security/LSM-sctp.txt
@@ -0,0 +1,212 @@
+   SCTP LSM Support
+  ==
+
+For security module support, three sctp specific hooks have been implemented:
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+
+Also the following security hook has been utilised:
+security_inet_conn_established()
+
+The usage of these hooks are described below with the SELinux implementation
+described in Documentation/security/SELinux-sctp.txt
+
+
+security_sctp_assoc_request()
+--
+This new hook has been added to net/sctp/sm_statefuns.c where it passes the
+@ep and @chunk->skb (the association INIT or INIT ACK packet) to the security
+module. Returns 0 on success, error on failure.
+
+@ep - pointer to sctp endpoint structure.
+@skb - pointer to skbuff of association packet.
+@sctp_cid - set to sctp packet type (SCTP_CID_INIT or SCTP_CID_INIT_ACK).
+
+The security module performs the following operations:
+  1) If this is the first association on @ep->base.sk, then set the peer sid
+ to that in @skb. This will ensure there is only one peer sid assigned
+ to @ep->base.sk that may support multiple associations.
+
+  2) If not the first association, validate the @ep->base.sk peer_sid against
+ the @skb peer sid to determine whether the association should be allowed
+ or denied.
+
+  3) If @sctp_cid = SCTP_CID_INIT, then set the sctp @ep sid to socket's sid
+ (from ep->base.sk) with MLS portion taken from @skb peer sid. This will
+ only be used by SCTP TCP style sockets and peeled off connections as they
+ cause a new socket to be generated.
+
+ If IP security options are configured (CIPSO/CALIPSO), then the ip options
+ are set on the socket.
+
+ To support this hook include/net/sctp/structs.h "struct sctp_endpoint"
+ has been updated with the following:
+
+   /* Security identifiers from incoming (INIT). These are set by
+* security_sctp_assoc_request(). These will only be used by
+* SCTP TCP type sockets and peeled off connections as they
+* cause a new socket to be generated. security_sctp_sk_clone()
+* will then plug these into the new socket.
+*/
+   u32 secid;
+   u32 peer_secid;
+
+
+security_sctp_bind_connect()
+-
+This new hook has been added to net/sctp/socket.c and net/sctp/sm_make_chunk.c.
+It passes one or more ipv4/ipv6 addresses to the security module for
+validation based on the @optname that will result in either a bind or connect
+service as shown in the permission check tables below.
+Returns 0 on success, error on failure.
+
+@sk  - Pointer to sock structure.
+@optname - Name of the option to validate.
+@address - One or more ipv4 / ipv6 addresses.
+@addrlen - The total length of address(s). This is calculated on each
+   ipv4 or ipv6 address using sizeof(struct sockaddr_in) or
+   sizeof(struct sockaddr_in6).
+
+  --
+  | BIND Type Checks   |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  |   CONNECT Type Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+A summary of the @optname entries is as follows

[RFC PATCH 0/5] Add SELinux SCTP protocol support

2017-10-17 Thread Richard Haines
This patch set adds SELinux support to SCTP and incorporates all the
comments received from my previous attemps (thanks to all who responded).
There are also other changes mainly supporting ip options so that CIPSO
and CALIPSO work over SCTP.

The kernel patches have been built on Fedora 26 with kernel 4.13.4 plus the
following userspace patches to enable testing:

1) Updates to libsepol 2.7 to support the sctp portcon statement.
   The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-Add-support-for-the-SCTP-portcon-keyword.patch

2) Updates to the SELinux Test Suite adding SCTP tests. Please read the
   selinux-testsuite/README.sctp for details. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 selinux-testsuite-Add-SCTP-test-support.patch

3) Updates to lksctp-tools that show SELinux info in sctp_darn and
   sctp_test. It also contains a minor patch for test_1_to_1_connect.c
   as when CIPSO/CALIPSO configured, NetLabel returns a different error
   code for illegal addresses in test 5. The patch is available from:
 http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
 lksctp-tools-Add-SELinux-support-to-sctp_test-and-sc.patch

All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.

All SCTP regression tests "./sctp-tests run" run correctly in enforcing
mode. These tests are obtained from: https://github.com/sctp/sctp-tests

The selinux-testsuite patch also adds remote tests (that need some manual
configuration). These are useful for testing CIPSO/CALIPSO over a network
with a number of categories to produce large ip option fields with various
message sizes forcing fragmentation etc..


Richard Haines (5):
  security: Add support for SCTP security hooks
  sctp: Add ip option support
  sctp: Add LSM hooks
  netlabel: Add SCTP support
  selinux: Add SCTP support

 Documentation/security/LSM-sctp.txt | 212 +
 Documentation/security/SELinux-sctp.txt | 108 +
 include/linux/lsm_hooks.h   |  37 +
 include/linux/security.h|  27 
 include/net/netlabel.h  |   3 +
 include/net/sctp/structs.h  |  12 ++
 include/uapi/linux/sctp.h   |   1 +
 net/netlabel/netlabel_kapi.c|  80 ++
 net/netlabel/netlabel_unlabeled.c   |  10 ++
 net/sctp/chunk.c|   7 +-
 net/sctp/ipv6.c |  37 -
 net/sctp/output.c   |   3 +-
 net/sctp/protocol.c |  36 +
 net/sctp/sm_make_chunk.c|  12 ++
 net/sctp/sm_statefuns.c |  14 +-
 net/sctp/socket.c   |  66 +++-
 security/security.c |  23 +++
 security/selinux/hooks.c| 268 ++--
 security/selinux/include/classmap.h |   3 +-
 security/selinux/include/netlabel.h |   9 +-
 security/selinux/include/objsec.h   |   5 +
 security/selinux/netlabel.c |  52 ++-
 22 files changed, 993 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/security/LSM-sctp.txt
 create mode 100644 Documentation/security/SELinux-sctp.txt

-- 
2.13.6



[RFC PATCH 3/5] sctp: Add LSM hooks

2017-10-17 Thread Richard Haines
Add security hooks to allow security modules to exercise access control
over SCTP.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h | 10 
 include/uapi/linux/sctp.h  |  1 +
 net/sctp/sm_make_chunk.c   | 12 +
 net/sctp/sm_statefuns.c| 14 ++-
 net/sctp/socket.c  | 61 +-
 5 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 7767577..6e72e3e 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1270,6 +1270,16 @@ struct sctp_endpoint {
  reconf_enable:1;
 
__u8  strreset_enable;
+
+   /* Security identifiers from incoming (INIT). These are set by
+* security_sctp_assoc_request(). These will only be used by
+* SCTP TCP type sockets and peeled off connections as they
+* cause a new socket to be generated. security_sctp_sk_clone()
+* will then plug these into the new socket.
+*/
+
+   u32 secid;
+   u32 peer_secid;
 };
 
 /* Recover the outter endpoint structure. */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 6217ff8..c04812f 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -122,6 +122,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_RESET_ASSOC   120
 #define SCTP_ADD_STREAMS   121
 #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
+#define SCTP_SENDMSG_CONNECT   123
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE  0x
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 6110447..ca4705b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3059,6 +3059,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, >source, sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_ADD_IP,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
 * request and does not have the local resources to add this
 * new address to the association, it MUST return an Error
@@ -3125,6 +3131,12 @@ static __be16 sctp_process_asconf_param(struct 
sctp_association *asoc,
if (af->is_any())
memcpy(, sctp_source(asconf), sizeof(addr));
 
+   if (security_sctp_bind_connect(asoc->ep->base.sk,
+  SCTP_PARAM_SET_PRIMARY,
+  (struct sockaddr *),
+  af->sockaddr_len))
+   return SCTP_ERROR_REQ_REFUSED;
+
peer = sctp_assoc_lookup_paddr(asoc, );
if (!peer)
return SCTP_ERROR_DNS_FAILED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b2a74c3..4ba5805 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -314,6 +314,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
sctp_unrecognized_param_t *unk_param;
int len;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb, SCTP_CID_INIT))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* 6.10 Bundling
 * An endpoint MUST NOT bundle INIT, INIT ACK or
 * SHUTDOWN COMPLETE with any other chunks.
@@ -446,7 +451,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
}
 
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
-
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 
/*
@@ -507,6 +511,11 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
struct sctp_chunk *err_chunk;
struct sctp_packet *packet;
 
+   /* Update socket peer label if first association. */
+   if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
+   chunk->skb, SCTP_CID_INIT_ACK))
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 
@@ -899,6 +908,9 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net,
 */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
 
+   /* Set peer label for connection. */
+   security_inet_conn_established(ep->base.sk, chunk->skb);
+

[RFC PATCH 4/5] netlabel: Add SCTP support

2017-10-17 Thread Richard Haines
Add support to label SCTP associations and cater for a situation where
family = PF_INET6 with an ip_hdr(skb)->version = 4.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/netlabel.h|  3 ++
 net/netlabel/netlabel_kapi.c  | 80 +++
 net/netlabel/netlabel_unlabeled.c | 10 +
 3 files changed, 93 insertions(+)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 72d6435..7348966 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -494,6 +494,9 @@ int netlbl_conn_setattr(struct sock *sk,
const struct netlbl_lsm_secattr *secattr);
 int netlbl_req_setattr(struct request_sock *req,
   const struct netlbl_lsm_secattr *secattr);
+int netlbl_sctp_setattr(struct sock *sk,
+   struct sk_buff *skb,
+   const struct netlbl_lsm_secattr *secattr);
 void netlbl_req_delattr(struct request_sock *req);
 int netlbl_skbuff_setattr(struct sk_buff *skb,
  u16 family,
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index ea7c670..1c82bbe 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -1121,6 +1121,7 @@ int netlbl_conn_setattr(struct sock *sk,
switch (addr->sa_family) {
case AF_INET:
addr4 = (struct sockaddr_in *)addr;
+
entry = netlbl_domhsh_getentry_af4(secattr->domain,
   addr4->sin_addr.s_addr);
if (entry == NULL) {
@@ -1177,6 +1178,85 @@ int netlbl_conn_setattr(struct sock *sk,
 }
 
 /**
+ * netlbl_sctp_setattr - Label an incoming sctp association socket using
+ * the correct protocol
+ * @sk: the socket to label
+ * @skb: the packet
+ * @secattr: the security attributes
+ *
+ * Description:
+ * Attach the correct label to the given socket using the security attributes
+ * specified in @secattr.  Returns zero on success, negative values on failure.
+ *
+ */
+int netlbl_sctp_setattr(struct sock *sk,
+   struct sk_buff *skb,
+   const struct netlbl_lsm_secattr *secattr)
+{
+   int ret_val = -EINVAL;
+   struct netlbl_dommap_def *entry;
+   struct iphdr *hdr4;
+#if IS_ENABLED(CONFIG_IPV6)
+   struct ipv6hdr *hdr6;
+#endif
+
+   rcu_read_lock();
+   switch (sk->sk_family) {
+   case AF_INET:
+   hdr4 = ip_hdr(skb);
+
+   entry = netlbl_domhsh_getentry_af4(secattr->domain,
+  hdr4->saddr);
+   if (entry == NULL) {
+   ret_val = -ENOENT;
+   goto sctp_setattr_return;
+   }
+   switch (entry->type) {
+   case NETLBL_NLTYPE_CIPSOV4:
+   ret_val = cipso_v4_sock_setattr(sk, entry->cipso,
+   secattr);
+   break;
+   case NETLBL_NLTYPE_UNLABELED:
+   netlbl_sock_delattr(sk);
+   ret_val = 0;
+   break;
+   default:
+   ret_val = -ENOENT;
+   }
+   break;
+#if IS_ENABLED(CONFIG_IPV6)
+   case AF_INET6:
+   hdr6 = ipv6_hdr(skb);
+   entry = netlbl_domhsh_getentry_af6(secattr->domain,
+  >saddr);
+   if (entry == NULL) {
+   ret_val = -ENOENT;
+   goto sctp_setattr_return;
+   }
+   switch (entry->type) {
+   case NETLBL_NLTYPE_CALIPSO:
+   ret_val = calipso_sock_setattr(sk, entry->calipso,
+  secattr);
+   break;
+   case NETLBL_NLTYPE_UNLABELED:
+   netlbl_sock_delattr(sk);
+   ret_val = 0;
+   break;
+   default:
+   ret_val = -ENOENT;
+   }
+   break;
+#endif /* IPv6 */
+   default:
+   ret_val = -EPROTONOSUPPORT;
+   }
+
+sctp_setattr_return:
+   rcu_read_unlock();
+   return ret_val;
+}
+
+/**
  * netlbl_req_setattr - Label a request socket using the correct protocol
  * @req: the request socket to label
  * @secattr: the security attributes
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 22dc1b9..c070dfc 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1472,6 +1472,16 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
iface = rcu_dereference(netlbl_unlhsh_def);
if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel

[RFC PATCH 2/5] sctp: Add ip option support

2017-10-17 Thread Richard Haines
Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
and CALIPSO/IPv6 services.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 include/net/sctp/structs.h |  2 ++
 net/sctp/chunk.c   |  7 ---
 net/sctp/ipv6.c| 37 ++---
 net/sctp/output.c  |  3 ++-
 net/sctp/protocol.c| 36 
 net/sctp/socket.c  |  5 -
 6 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 5ab29af..7767577 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -461,6 +461,7 @@ struct sctp_af {
void(*ecn_capable)(struct sock *sk);
__u16   net_header_len;
int sockaddr_len;
+   int (*ip_options_len)(struct sock *sk);
sa_family_t sa_family;
struct list_head list;
 };
@@ -485,6 +486,7 @@ struct sctp_pf {
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
struct sctp_af *af;
 };
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 1323d41..e49e240 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -153,7 +153,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, 
struct sctp_chunk *chu
chunk->msg = msg;
 }
 
-
 /* A data chunk can have a maximum payload of (2^16 - 20).  Break
  * down any such message into smaller chunks.  Opportunistically, fragment
  * the chunks down to the current MTU constraints.  We may get refragmented
@@ -190,7 +189,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
 */
max_data = asoc->pathmtu -
   sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
+  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk) -
+  sctp_sk(asoc->base.sk)->pf->af->
+  ip_options_len(asoc->base.sk);
+
max_data = SCTP_TRUNC4(max_data);
 
/* If the the peer requested that we authenticate DATA chunks
@@ -210,7 +212,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
sctp_association *asoc,
 
/* Set first_len and then account for possible bundles on first frag */
first_len = max_data;
-
/* Check to see if we have a pending SACK and try to let it be bundled
 * with this message.  Do this if we don't have any data queued already.
 * To check that, look at out_qlen and retransmit list.
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a4b6ffb..49c9011 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -423,6 +423,33 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
rcu_read_unlock();
 }
 
+/* Copy over any ip options */
+static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
+{
+   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+   struct ipv6_txoptions *opt;
+
+   newnp = inet6_sk(newsk);
+
+   rcu_read_lock();
+   opt = rcu_dereference(np->opt);
+   if (opt)
+   opt = ipv6_dup_options(newsk, opt);
+   RCU_INIT_POINTER(newnp->opt, opt);
+   rcu_read_unlock();
+}
+
+/* Account for the IP options */
+static int sctp_v6_ip_options_len(struct sock *sk)
+{
+   struct ipv6_pinfo *inet6 = inet6_sk(sk);
+
+   if (inet6->opt)
+   return inet6->opt->opt_flen + inet6->opt->opt_nflen;
+   else
+   return 0;
+}
+
 /* Initialize a sockaddr_storage from in incoming skb. */
 static void sctp_v6_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 int is_saddr)
@@ -662,7 +689,6 @@ static struct sock *sctp_v6_create_accept_sk(struct sock 
*sk,
struct sock *newsk;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
-   struct ipv6_txoptions *opt;
 
newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern);
if (!newsk)
@@ -685,12 +711,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock 
*sk,
newnp->ipv6_ac_list = NULL;
newnp->ipv6_fl_list = NULL;
 
-   rcu_read_lock();
-   opt = rcu_dereference(np->opt);
-   if (opt)
-   opt = ipv6_dup_options(newsk, opt);
-   RCU_INIT_POINTER(newnp->opt, opt);
-   rcu_read_unlock();
+   sctp_v6_copy_ip_options(sk, newsk);
 
/* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
 * and getpeername().
@@ -1033,6 +1054,7 @@ static struct sctp_af sctp_af_inet6 = {
.ecn_capable 

[RFC PATCH 5/5] selinux: Add SCTP support

2017-10-17 Thread Richard Haines
The SELinux SCTP implementation is explained in:
Documentation/security/SELinux-sctp.txt

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 Documentation/security/SELinux-sctp.txt | 108 +
 security/selinux/hooks.c| 268 ++--
 security/selinux/include/classmap.h |   3 +-
 security/selinux/include/netlabel.h |   9 +-
 security/selinux/include/objsec.h   |   5 +
 security/selinux/netlabel.c |  52 ++-
 6 files changed, 427 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/security/SELinux-sctp.txt

diff --git a/Documentation/security/SELinux-sctp.txt 
b/Documentation/security/SELinux-sctp.txt
new file mode 100644
index 000..32e0255
--- /dev/null
+++ b/Documentation/security/SELinux-sctp.txt
@@ -0,0 +1,108 @@
+   SCTP SELinux Support
+  ==
+
+Security Hooks
+===
+
+The Documentation/security/LSM-sctp.txt document describes how the following
+sctp security hooks are utilised:
+security_sctp_assoc_request()
+security_sctp_bind_connect()
+security_sctp_sk_clone()
+
+security_inet_conn_established()
+
+
+Policy Statements
+==
+The following class and permissions to support SCTP are available within the
+kernel:
+class sctp_socket inherits socket { node_bind }
+
+whenever the following policy capability is enabled:
+policycap extended_socket_class;
+
+The SELinux SCTP support adds the additional permissions that are explained
+in the sections below:
+association bindx connectx
+
+If userspace tools have been updated, SCTP will support the portcon
+statement as shown in the following example:
+portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0
+
+
+SCTP Bind, Connect and ASCONF Chunk Parameter Permission Checks
+
+The hook security_sctp_bind_connect() is called by SCTP to check permissions
+required for ipv4/ipv6 addresses based on the @optname as follows:
+
+  --
+  |  BINDX Permission Check|
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses |
+  --
+
+  --
+  |  BIND Permission Checks|
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_PRIMARY_ADDR  | Single ipv4 or ipv6 address   |
+  | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address   |
+  --
+
+  --
+  | CONNECTX Permission Check  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SOCKOPT_CONNECTX  | One or more ipv4 / ipv6 addresses |
+  --
+
+  --
+  | CONNECT Permission Checks  |
+  |   @optname | @address contains |
+  ||---|
+  | SCTP_SENDMSG_CONNECT   | Single ipv4 or ipv6 address   |
+  | SCTP_PARAM_ADD_IP  | One or more ipv4 / ipv6 addresses |
+  | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address   |
+  --
+
+SCTP Peer Labeling
+===
+An SCTP socket will only have one peer label assigned to it. This will be
+assigned during the establishment of the first association. Once the peer
+label has been assigned, any new associations will have the "association"
+permission validated by checking the socket peer sid against the received
+packets peer sid to determine whether the association should be allowed or
+denied.
+
+NOTES:
+   1) If peer labeling is not enabled, then the peer context will always be
+  SECINITSID_UNLABELED (unlabeled_t in Reference Policy).
+
+   2) As SCTP supports multiple endpoints with multi-homing on a single socket
+  it is recommended that peer labels are consistent.
+
+   3) getpeercon(3) may be used by userspace to retrieve the sockets peer
+   context.
+
+   4) If using NetLabel be aware that if a label is assigned to a specific
+  interface, and that interface 'goes down', then the NetLabel service
+  will 

[PATCH] net/ipv6: Fix CALIPSO causing GPF with datagram support

2017-06-05 Thread Richard Haines
When using CALIPSO with IPPROTO_UDP it is possible to trigger a GPF as the
IP header may have moved.

Also update the payload length after adding the CALIPSO option.

Signed-off-by: Richard Haines <richard_c_hai...@btinternet.com>
---
 net/ipv6/calipso.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index 37ac9de..8d772fe 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -1319,7 +1319,7 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
struct ipv6hdr *ip6_hdr;
struct ipv6_opt_hdr *hop;
unsigned char buf[CALIPSO_MAX_BUFFER];
-   int len_delta, new_end, pad;
+   int len_delta, new_end, pad, payload;
unsigned int start, end;
 
ip6_hdr = ipv6_hdr(skb);
@@ -1346,6 +1346,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
if (ret_val < 0)
return ret_val;
 
+   ip6_hdr = ipv6_hdr(skb); /* Reset as skb_cow() may have moved it */
+
if (len_delta) {
if (len_delta > 0)
skb_push(skb, len_delta);
@@ -1355,6 +1357,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
sizeof(*ip6_hdr) + start);
skb_reset_network_header(skb);
ip6_hdr = ipv6_hdr(skb);
+   payload = ntohs(ip6_hdr->payload_len);
+   ip6_hdr->payload_len = htons(payload + len_delta);
}
 
hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
-- 
2.9.4