diff mbox

[v4] Classify AF_ALG sockets

Message ID 1471899875.19333.3.camel@trentalancia.net (mailing list archive)
State Superseded
Headers show

Commit Message

Guido Trentalancia Aug. 22, 2016, 9:04 p.m. UTC
Modify the SELinux kernel code so that it is able to classify sockets with
the new AF_ALG namespace (used for the user-space interface to the kernel
Crypto API).

A companion patch has been created for the Reference Policy and it will be
posted to its mailing list, once this patch is merged.

Signed-off-by: Guido Trentalancia <guido@trentalancia.net>
---
 security/selinux/hooks.c            |    5 +++++
 security/selinux/include/classmap.h |    2 ++
 security/selinux/include/security.h |    2 ++
 security/selinux/ss/services.c      |    3 +++
 4 files changed, 12 insertions(+)

Comments

Paul Moore Aug. 22, 2016, 10:36 p.m. UTC | #1
On Mon, Aug 22, 2016 at 5:04 PM, Guido Trentalancia
<guido@trentalancia.net> wrote:
> Modify the SELinux kernel code so that it is able to classify sockets with
> the new AF_ALG namespace (used for the user-space interface to the kernel
> Crypto API).
>
> A companion patch has been created for the Reference Policy and it will be
> posted to its mailing list, once this patch is merged.
>
> Signed-off-by: Guido Trentalancia <guido@trentalancia.net>
> ---
>  security/selinux/hooks.c            |    5 +++++
>  security/selinux/include/classmap.h |    2 ++
>  security/selinux/include/security.h |    2 ++
>  security/selinux/ss/services.c      |    3 +++
>  4 files changed, 12 insertions(+)

You are still missing the policy capability code for
security/selinux/selinuxfs.c.  I think it would also be a good idea to
write a test for this and add it to the selinux-testsuite; not only
will this help us confirm this code works as expected, but it will
demonstrate what the new policy would look like and help establish a
regression test for future use.

 * https://github.com/SELinuxProject/selinux-testsuite

> diff -pru linux-4.7.2-orig/security/selinux/hooks.c linux-4.7.2/security/selinux/hooks.c
> --- linux-4.7.2-orig/security/selinux/hooks.c   2016-08-22 22:31:27.737767819 +0200
> +++ linux-4.7.2/security/selinux/hooks.c        2016-08-22 22:40:29.102526024 +0200
> @@ -1315,6 +1315,11 @@ static inline u16 socket_type_to_securit
>                 return SECCLASS_KEY_SOCKET;
>         case PF_APPLETALK:
>                 return SECCLASS_APPLETALK_SOCKET;
> +       case PF_ALG:
> +               if (selinux_policycap_algsocket)
> +                       return SECCLASS_ALG_SOCKET;
> +               else
> +                       return SECCLASS_SOCKET;
>         }
>
>         return SECCLASS_SOCKET;
> diff -pru linux-4.7.2-orig/security/selinux/include/classmap.h linux-4.7.2/security/selinux/include/classmap.h
> --- linux-4.7.2-orig/security/selinux/include/classmap.h        2016-08-22 22:31:27.754768030 +0200
> +++ linux-4.7.2/security/selinux/include/classmap.h     2016-08-22 22:32:14.795355585 +0200
> @@ -144,6 +144,8 @@ struct security_class_mapping secclass_m
>           { COMMON_SOCK_PERMS, NULL } },
>         { "appletalk_socket",
>           { COMMON_SOCK_PERMS, NULL } },
> +       { "alg_socket",
> +         { COMMON_SOCK_PERMS, NULL } },
>         { "packet",
>           { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
>         { "key",
> diff -pru linux-4.7.2-orig/security/selinux/include/security.h linux-4.7.2/security/selinux/include/security.h
> --- linux-4.7.2-orig/security/selinux/include/security.h        2016-03-14 05:28:54.000000000 +0100
> +++ linux-4.7.2/security/selinux/include/security.h     2016-08-22 22:53:57.911660238 +0200
> @@ -75,6 +75,7 @@ enum {
>         POLICYDB_CAPABILITY_OPENPERM,
>         POLICYDB_CAPABILITY_REDHAT1,
>         POLICYDB_CAPABILITY_ALWAYSNETWORK,
> +       POLICYDB_CAPABILITY_ALGSOCKET,
>         __POLICYDB_CAPABILITY_MAX
>  };
>  #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> @@ -82,6 +83,7 @@ enum {
>  extern int selinux_policycap_netpeer;
>  extern int selinux_policycap_openperm;
>  extern int selinux_policycap_alwaysnetwork;
> +extern int selinux_policycap_algsocket;
>
>  /*
>   * type_datum properties
> diff -pru linux-4.7.2-orig/security/selinux/ss/services.c linux-4.7.2/security/selinux/ss/services.c
> --- linux-4.7.2-orig/security/selinux/ss/services.c     2016-08-05 21:27:22.275588616 +0200
> +++ linux-4.7.2/security/selinux/ss/services.c  2016-08-22 22:56:58.616187510 +0200
> @@ -73,6 +73,7 @@
>  int selinux_policycap_netpeer;
>  int selinux_policycap_openperm;
>  int selinux_policycap_alwaysnetwork;
> +int selinux_policycap_algsocket;
>
>  static DEFINE_RWLOCK(policy_rwlock);
>
> @@ -2016,6 +2017,8 @@ static void security_load_policycaps(voi
>                                                   POLICYDB_CAPABILITY_OPENPERM);
>         selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
>                                                   POLICYDB_CAPABILITY_ALWAYSNETWORK);
> +       selinux_policycap_algsocket = ebitmap_get_bit(&policydb.policycaps,
> +                                                 POLICYDB_CAPABILITY_ALGSOCKET);
>  }
>
>  static int security_preserve_bools(struct policydb *p);
Stephen Smalley Aug. 23, 2016, 1:05 p.m. UTC | #2
On 08/22/2016 06:36 PM, Paul Moore wrote:
> On Mon, Aug 22, 2016 at 5:04 PM, Guido Trentalancia
> <guido@trentalancia.net> wrote:
>> Modify the SELinux kernel code so that it is able to classify sockets with
>> the new AF_ALG namespace (used for the user-space interface to the kernel
>> Crypto API).
>>
>> A companion patch has been created for the Reference Policy and it will be
>> posted to its mailing list, once this patch is merged.
>>
>> Signed-off-by: Guido Trentalancia <guido@trentalancia.net>
>> ---
>>  security/selinux/hooks.c            |    5 +++++
>>  security/selinux/include/classmap.h |    2 ++
>>  security/selinux/include/security.h |    2 ++
>>  security/selinux/ss/services.c      |    3 +++
>>  4 files changed, 12 insertions(+)
> 
> You are still missing the policy capability code for
> security/selinux/selinuxfs.c.  I think it would also be a good idea to
> write a test for this and add it to the selinux-testsuite; not only
> will this help us confirm this code works as expected, but it will
> demonstrate what the new policy would look like and help establish a
> regression test for future use.
> 
>  * https://github.com/SELinuxProject/selinux-testsuite

I also think that if we are going to go to the trouble of adding a new
policy capability for this (versus just relying on
handle_unknown=allow), then we ought to identify and define all socket
classes that we think we might want.  Otherwise we'll end up with 50
different policy capabilities, one for each new socket class.  This is
already on the kernel todo list,
https://github.com/SELinuxProject/selinux/wiki/Kernel-Todo

* Improve support for the different network address families with more
socket classes

    Extend SELinux to support distinctions among more (all?) address
families by defining new socket security classes in policy and updating
the kernel logic to map them correctly. In the kernel, add the classes
to security/selinux/include/classmap.h and update
security/selinux/hooks.c:socket_type_to_security_class() to map the
socket domain to its class. In the policy, add the classes to
security_classes and access_vectors and add allow rules as appropriate.
Otherwise, many sockets get mapped to the generic socket class and are
indistinguishable in policy. Example: bluetooth sockets.

> 
>> diff -pru linux-4.7.2-orig/security/selinux/hooks.c linux-4.7.2/security/selinux/hooks.c
>> --- linux-4.7.2-orig/security/selinux/hooks.c   2016-08-22 22:31:27.737767819 +0200
>> +++ linux-4.7.2/security/selinux/hooks.c        2016-08-22 22:40:29.102526024 +0200
>> @@ -1315,6 +1315,11 @@ static inline u16 socket_type_to_securit
>>                 return SECCLASS_KEY_SOCKET;
>>         case PF_APPLETALK:
>>                 return SECCLASS_APPLETALK_SOCKET;
>> +       case PF_ALG:
>> +               if (selinux_policycap_algsocket)
>> +                       return SECCLASS_ALG_SOCKET;
>> +               else
>> +                       return SECCLASS_SOCKET;
>>         }
>>
>>         return SECCLASS_SOCKET;
>> diff -pru linux-4.7.2-orig/security/selinux/include/classmap.h linux-4.7.2/security/selinux/include/classmap.h
>> --- linux-4.7.2-orig/security/selinux/include/classmap.h        2016-08-22 22:31:27.754768030 +0200
>> +++ linux-4.7.2/security/selinux/include/classmap.h     2016-08-22 22:32:14.795355585 +0200
>> @@ -144,6 +144,8 @@ struct security_class_mapping secclass_m
>>           { COMMON_SOCK_PERMS, NULL } },
>>         { "appletalk_socket",
>>           { COMMON_SOCK_PERMS, NULL } },
>> +       { "alg_socket",
>> +         { COMMON_SOCK_PERMS, NULL } },
>>         { "packet",
>>           { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
>>         { "key",
>> diff -pru linux-4.7.2-orig/security/selinux/include/security.h linux-4.7.2/security/selinux/include/security.h
>> --- linux-4.7.2-orig/security/selinux/include/security.h        2016-03-14 05:28:54.000000000 +0100
>> +++ linux-4.7.2/security/selinux/include/security.h     2016-08-22 22:53:57.911660238 +0200
>> @@ -75,6 +75,7 @@ enum {
>>         POLICYDB_CAPABILITY_OPENPERM,
>>         POLICYDB_CAPABILITY_REDHAT1,
>>         POLICYDB_CAPABILITY_ALWAYSNETWORK,
>> +       POLICYDB_CAPABILITY_ALGSOCKET,
>>         __POLICYDB_CAPABILITY_MAX
>>  };
>>  #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
>> @@ -82,6 +83,7 @@ enum {
>>  extern int selinux_policycap_netpeer;
>>  extern int selinux_policycap_openperm;
>>  extern int selinux_policycap_alwaysnetwork;
>> +extern int selinux_policycap_algsocket;
>>
>>  /*
>>   * type_datum properties
>> diff -pru linux-4.7.2-orig/security/selinux/ss/services.c linux-4.7.2/security/selinux/ss/services.c
>> --- linux-4.7.2-orig/security/selinux/ss/services.c     2016-08-05 21:27:22.275588616 +0200
>> +++ linux-4.7.2/security/selinux/ss/services.c  2016-08-22 22:56:58.616187510 +0200
>> @@ -73,6 +73,7 @@
>>  int selinux_policycap_netpeer;
>>  int selinux_policycap_openperm;
>>  int selinux_policycap_alwaysnetwork;
>> +int selinux_policycap_algsocket;
>>
>>  static DEFINE_RWLOCK(policy_rwlock);
>>
>> @@ -2016,6 +2017,8 @@ static void security_load_policycaps(voi
>>                                                   POLICYDB_CAPABILITY_OPENPERM);
>>         selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
>>                                                   POLICYDB_CAPABILITY_ALWAYSNETWORK);
>> +       selinux_policycap_algsocket = ebitmap_get_bit(&policydb.policycaps,
>> +                                                 POLICYDB_CAPABILITY_ALGSOCKET);
>>  }
>>
>>  static int security_preserve_bools(struct policydb *p);
>
Paul Moore Aug. 23, 2016, 1:35 p.m. UTC | #3
On Tue, Aug 23, 2016 at 9:05 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On 08/22/2016 06:36 PM, Paul Moore wrote:
>> On Mon, Aug 22, 2016 at 5:04 PM, Guido Trentalancia
>> <guido@trentalancia.net> wrote:
>>> Modify the SELinux kernel code so that it is able to classify sockets with
>>> the new AF_ALG namespace (used for the user-space interface to the kernel
>>> Crypto API).
>>>
>>> A companion patch has been created for the Reference Policy and it will be
>>> posted to its mailing list, once this patch is merged.
>>>
>>> Signed-off-by: Guido Trentalancia <guido@trentalancia.net>
>>> ---
>>>  security/selinux/hooks.c            |    5 +++++
>>>  security/selinux/include/classmap.h |    2 ++
>>>  security/selinux/include/security.h |    2 ++
>>>  security/selinux/ss/services.c      |    3 +++
>>>  4 files changed, 12 insertions(+)
>>
>> You are still missing the policy capability code for
>> security/selinux/selinuxfs.c.  I think it would also be a good idea to
>> write a test for this and add it to the selinux-testsuite; not only
>> will this help us confirm this code works as expected, but it will
>> demonstrate what the new policy would look like and help establish a
>> regression test for future use.
>>
>>  * https://github.com/SELinuxProject/selinux-testsuite
>
> I also think that if we are going to go to the trouble of adding a new
> policy capability for this (versus just relying on
> handle_unknown=allow), then we ought to identify and define all socket
> classes that we think we might want.  Otherwise we'll end up with 50
> different policy capabilities, one for each new socket class.

To be clear, we can't rely only on the new/unknown object class
handling for this particular case since this change would convert some
of the existing generic socket access checks to the algsocket access
checks which could result in undesired access for policies which set
handle_unknown=allow.  The new/unknown object class handling works
well for new access controls, but sometimes has problems with modified
access controls.

As far as additional socket classes are concerned, it does some
reasonable to add more than just AF_ALG in an effort to try and
consolidate things.  Guido, is this something you would be willing to
work on?
diff mbox

Patch

diff -pru linux-4.7.2-orig/security/selinux/hooks.c linux-4.7.2/security/selinux/hooks.c
--- linux-4.7.2-orig/security/selinux/hooks.c	2016-08-22 22:31:27.737767819 +0200
+++ linux-4.7.2/security/selinux/hooks.c	2016-08-22 22:40:29.102526024 +0200
@@ -1315,6 +1315,11 @@  static inline u16 socket_type_to_securit
 		return SECCLASS_KEY_SOCKET;
 	case PF_APPLETALK:
 		return SECCLASS_APPLETALK_SOCKET;
+	case PF_ALG:
+		if (selinux_policycap_algsocket)
+			return SECCLASS_ALG_SOCKET;
+		else
+			return SECCLASS_SOCKET;
 	}
 
 	return SECCLASS_SOCKET;
diff -pru linux-4.7.2-orig/security/selinux/include/classmap.h linux-4.7.2/security/selinux/include/classmap.h
--- linux-4.7.2-orig/security/selinux/include/classmap.h	2016-08-22 22:31:27.754768030 +0200
+++ linux-4.7.2/security/selinux/include/classmap.h	2016-08-22 22:32:14.795355585 +0200
@@ -144,6 +144,8 @@  struct security_class_mapping secclass_m
 	  { COMMON_SOCK_PERMS, NULL } },
 	{ "appletalk_socket",
 	  { COMMON_SOCK_PERMS, NULL } },
+	{ "alg_socket",
+	  { COMMON_SOCK_PERMS, NULL } },
 	{ "packet",
 	  { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
 	{ "key",
diff -pru linux-4.7.2-orig/security/selinux/include/security.h linux-4.7.2/security/selinux/include/security.h
--- linux-4.7.2-orig/security/selinux/include/security.h	2016-03-14 05:28:54.000000000 +0100
+++ linux-4.7.2/security/selinux/include/security.h	2016-08-22 22:53:57.911660238 +0200
@@ -75,6 +75,7 @@  enum {
 	POLICYDB_CAPABILITY_OPENPERM,
 	POLICYDB_CAPABILITY_REDHAT1,
 	POLICYDB_CAPABILITY_ALWAYSNETWORK,
+	POLICYDB_CAPABILITY_ALGSOCKET,
 	__POLICYDB_CAPABILITY_MAX
 };
 #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
@@ -82,6 +83,7 @@  enum {
 extern int selinux_policycap_netpeer;
 extern int selinux_policycap_openperm;
 extern int selinux_policycap_alwaysnetwork;
+extern int selinux_policycap_algsocket;
 
 /*
  * type_datum properties
diff -pru linux-4.7.2-orig/security/selinux/ss/services.c linux-4.7.2/security/selinux/ss/services.c
--- linux-4.7.2-orig/security/selinux/ss/services.c	2016-08-05 21:27:22.275588616 +0200
+++ linux-4.7.2/security/selinux/ss/services.c	2016-08-22 22:56:58.616187510 +0200
@@ -73,6 +73,7 @@ 
 int selinux_policycap_netpeer;
 int selinux_policycap_openperm;
 int selinux_policycap_alwaysnetwork;
+int selinux_policycap_algsocket;
 
 static DEFINE_RWLOCK(policy_rwlock);
 
@@ -2016,6 +2017,8 @@  static void security_load_policycaps(voi
 						  POLICYDB_CAPABILITY_OPENPERM);
 	selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
 						  POLICYDB_CAPABILITY_ALWAYSNETWORK);
+	selinux_policycap_algsocket = ebitmap_get_bit(&policydb.policycaps,
+						  POLICYDB_CAPABILITY_ALGSOCKET);
 }
 
 static int security_preserve_bools(struct policydb *p);