ANDROID: selinux: modify RTM_GETNEIGH [1/1]
authorpengzhao.liu <pengzhao.liu@amlogic.com>
Tue, 22 Mar 2022 06:03:33 +0000 (14:03 +0800)
committerChristian Hoffmann <chrmhoffmann@gmail.com>
Sun, 12 Feb 2023 08:13:13 +0000 (09:13 +0100)
PD#SWPL-71742
Bug: 171572148

Problem:
Map the permission gating RTM_GETNEIGH/RTM_GETNEIGHTBL messages to a
new permission so that it can be distinguished from the other netlink
route permissions in selinux policy. The new permission is triggered by
a flag set in system images T and up.

Solution:
This change is intended to be backported to all kernels that a T system
image can run on top of.

Verify:
on adt3-t kernel

Test: ateddst NetworkInterfaceTest
Test: atest CtsSelinuxTargetSdkCurrentTestCases
Test: atest bionic-unit-tests-static
Test: On Cuttlefish, run combinations of:
    - Policy bit set or omitted (see https://r.android.com/1701847)
    - This patch applied or omitted
    - App having nlmsg_readneigh permission or not
  Verify that only the combination of this patch + the policy bit being
  set + the app not having the nlmsg_readneigh permission prevents the
  app from sending RTM_GETNEIGH messages.

Change-Id: I4bcfce4decb34ea9388eeedfc4be67403de8a980
Signed-off-by: Bram Bonné <brambonne@google.com>
Signed-off-by: pengzhao.liu <pengzhao.liu@amlogic.com>
Change-Id: Ic9d51cebab8c195537d54a28a23a7e93f09ba0b3

security/selinux/include/classmap.h
security/selinux/include/security.h
security/selinux/nlmsgtab.c
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c

index 1764b221d545d6c290fe5a6bdf678e00c0321872..3742d8788224e66b279eea0ca38a9fa9a8b59482 100644 (file)
@@ -105,7 +105,8 @@ struct security_class_mapping secclass_map[] = {
          { COMMON_IPC_PERMS, NULL } },
        { "netlink_route_socket",
          { COMMON_SOCK_PERMS,
-           "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", NULL } },
+               "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", "nlmsg_getneigh",
+           NULL } },
        { "netlink_tcpdiag_socket",
          { COMMON_SOCK_PERMS,
            "nlmsg_read", "nlmsg_write", NULL } },
index 2775170b526f5f6ede40ecf242bba50ff6057b81..ea3c8a35f045b9de8b81b629624a4fbd102ed605 100644 (file)
@@ -79,6 +79,7 @@ extern int selinux_android_netlink_route;
 extern int selinux_policycap_netpeer;
 extern int selinux_policycap_openperm;
 extern int selinux_policycap_alwaysnetwork;
+extern int selinux_android_netlink_getneigh;
 
 /*
  * type_datum properties
index 697785cec7f6bb85abb0c591b3993c82e33f2597..957e37041ea745c26b8b671840c7e62124b8e558 100644 (file)
@@ -194,26 +194,43 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
        return err;
 }
 
-static void nlmsg_set_getlink_perm(u32 perm)
+
+static void nlmsg_set_perm_for_type(u32 perm, u16 type)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(nlmsg_route_perms); i++) {
-               if (nlmsg_route_perms[i].nlmsg_type == RTM_GETLINK) {
+               if (nlmsg_route_perms[i].nlmsg_type == type) {
                        nlmsg_route_perms[i].perm = perm;
                        break;
                }
        }
 }
-
 /**
  * Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the
  * netlink_route_getlink policy capability is set. Otherwise use nlmsg_read.
+ * Similarly, use nlmsg_getneigh for RTM_GETNEIGH and RTM_GETNEIGHTBL if the
+ * netlink_route_getneigh policy capability is set. Otherwise use nlmsg_read.
  */
 void selinux_nlmsg_init(void)
 {
-       if (selinux_android_netlink_route)
-               nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV);
-       else
-               nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READ);
+       if (selinux_android_netlink_route) {
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV,
+                                       RTM_GETLINK);
+       } else {
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ,
+                                       RTM_GETLINK);
+       }
+
+       if (selinux_android_netlink_getneigh) {
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH,
+                                       RTM_GETNEIGH);
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH,
+                                       RTM_GETNEIGHTBL);
+       } else {
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ,
+                                       RTM_GETNEIGH);
+               nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ,
+                                       RTM_GETNEIGHTBL);
+       }
 }
index 62518b031e5e43229909937672bd608be565cd0e..12553cbe0b4832c06ecdab5031fd20ca554c0e1f 100644 (file)
@@ -2335,6 +2335,10 @@ int policydb_read(struct policydb *p, void *fp)
        if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE)) {
                p->android_netlink_route = 1;
        }
+       if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH)) {
+               p->android_netlink_getneigh = 1;
+       }
+
 
        if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
                rc = ebitmap_read(&p->policycaps, fp);
index 0d511cf3c1e99af3d4996c71c758ff6d7509a580..45698f754766fabe78dc7bf8f2de8bd07d953247 100644 (file)
@@ -228,6 +228,7 @@ struct genfs {
 struct policydb {
        int mls_enabled;
        int android_netlink_route;
+       int android_netlink_getneigh;
 
        /* symbol tables */
        struct symtab symtab[SYM_NUM];
@@ -315,6 +316,7 @@ extern int policydb_write(struct policydb *p, void *fp);
 
 #define POLICYDB_CONFIG_MLS    1
 #define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE    (1 << 31)
+#define POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH (1 << 30)
 
 /* the config flags related to unknown classes/perms are bits 2 and 3 */
 #define REJECT_UNKNOWN 0x00000002
index 14bbea8ad5968ae53e442697f5248ed3322a6f1d..66a8a6f67fb12d17c16210560401a95644a5f9b2 100644 (file)
@@ -74,6 +74,7 @@ int selinux_android_netlink_route;
 int selinux_policycap_netpeer;
 int selinux_policycap_openperm;
 int selinux_policycap_alwaysnetwork;
+int selinux_android_netlink_getneigh;
 
 static DEFINE_RWLOCK(policy_rwlock);
 
@@ -1994,6 +1995,7 @@ static void security_load_policycaps(void)
                                                  POLICYDB_CAPABILITY_ALWAYSNETWORK);
 
        selinux_android_netlink_route = policydb.android_netlink_route;
+       selinux_android_netlink_getneigh = policydb.android_netlink_getneigh;
        selinux_nlmsg_init();
 }