ANDROID: selinux: modify RTM_GETNEIGH{TBL}
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. This change is intended to be backported to all kernels that a T system image can run on top of. Bug: 171572148 Test: atest 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> (cherry picked from commit fac07550bdac9adea0dbe3edbdbec7a9a690a178)
This commit is contained in:
@@ -117,7 +117,8 @@ struct security_class_mapping secclass_map[] = {
|
|||||||
{ COMMON_IPC_PERMS, NULL } },
|
{ COMMON_IPC_PERMS, NULL } },
|
||||||
{ "netlink_route_socket",
|
{ "netlink_route_socket",
|
||||||
{ COMMON_SOCK_PERMS,
|
{ COMMON_SOCK_PERMS,
|
||||||
"nlmsg_read", "nlmsg_write", "nlmsg_readpriv", NULL } },
|
"nlmsg_read", "nlmsg_write", "nlmsg_readpriv", "nlmsg_getneigh",
|
||||||
|
NULL } },
|
||||||
{ "netlink_tcpdiag_socket",
|
{ "netlink_tcpdiag_socket",
|
||||||
{ COMMON_SOCK_PERMS,
|
{ COMMON_SOCK_PERMS,
|
||||||
"nlmsg_read", "nlmsg_write", NULL } },
|
"nlmsg_read", "nlmsg_write", NULL } },
|
||||||
|
@@ -98,6 +98,7 @@ struct selinux_state {
|
|||||||
bool initialized;
|
bool initialized;
|
||||||
bool policycap[__POLICYDB_CAPABILITY_MAX];
|
bool policycap[__POLICYDB_CAPABILITY_MAX];
|
||||||
bool android_netlink_route;
|
bool android_netlink_route;
|
||||||
|
bool android_netlink_getneigh;
|
||||||
|
|
||||||
struct page *status_page;
|
struct page *status_page;
|
||||||
struct mutex status_lock;
|
struct mutex status_lock;
|
||||||
@@ -227,6 +228,13 @@ static inline bool selinux_android_nlroute_getlink(void)
|
|||||||
return state->android_netlink_route;
|
return state->android_netlink_route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_android_nlroute_getneigh(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->android_netlink_getneigh;
|
||||||
|
}
|
||||||
|
|
||||||
struct selinux_policy_convert_data;
|
struct selinux_policy_convert_data;
|
||||||
|
|
||||||
struct selinux_load_state {
|
struct selinux_load_state {
|
||||||
|
@@ -212,12 +212,12 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nlmsg_set_getlink_perm(u32 perm)
|
static void nlmsg_set_perm_for_type(u32 perm, u16 type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nlmsg_route_perms); 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;
|
nlmsg_route_perms[i].perm = perm;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -227,11 +227,27 @@ static void nlmsg_set_getlink_perm(u32 perm)
|
|||||||
/**
|
/**
|
||||||
* Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the
|
* Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the
|
||||||
* netlink_route_getlink policy capability is set. Otherwise use nlmsg_read.
|
* 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)
|
void selinux_nlmsg_init(void)
|
||||||
{
|
{
|
||||||
if (selinux_android_nlroute_getlink())
|
if (selinux_android_nlroute_getlink())
|
||||||
nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV);
|
nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV,
|
||||||
|
RTM_GETLINK);
|
||||||
else
|
else
|
||||||
nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READ);
|
nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ,
|
||||||
|
RTM_GETLINK);
|
||||||
|
|
||||||
|
if (selinux_android_nlroute_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2497,6 +2497,10 @@ int policydb_read(struct policydb *p, void *fp)
|
|||||||
p->android_netlink_route = 1;
|
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) {
|
if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
|
||||||
rc = ebitmap_read(&p->policycaps, fp);
|
rc = ebitmap_read(&p->policycaps, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@@ -239,6 +239,7 @@ struct genfs {
|
|||||||
struct policydb {
|
struct policydb {
|
||||||
int mls_enabled;
|
int mls_enabled;
|
||||||
int android_netlink_route;
|
int android_netlink_route;
|
||||||
|
int android_netlink_getneigh;
|
||||||
|
|
||||||
/* symbol tables */
|
/* symbol tables */
|
||||||
struct symtab symtab[SYM_NUM];
|
struct symtab symtab[SYM_NUM];
|
||||||
@@ -336,6 +337,7 @@ extern struct role_trans_datum *policydb_roletr_search(
|
|||||||
|
|
||||||
#define POLICYDB_CONFIG_MLS 1
|
#define POLICYDB_CONFIG_MLS 1
|
||||||
#define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE (1 << 31)
|
#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 */
|
/* the config flags related to unknown classes/perms are bits 2 and 3 */
|
||||||
#define REJECT_UNKNOWN 0x00000002
|
#define REJECT_UNKNOWN 0x00000002
|
||||||
|
@@ -2162,6 +2162,7 @@ static void security_load_policycaps(struct selinux_state *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
state->android_netlink_route = p->android_netlink_route;
|
state->android_netlink_route = p->android_netlink_route;
|
||||||
|
state->android_netlink_getneigh = p->android_netlink_getneigh;
|
||||||
selinux_nlmsg_init();
|
selinux_nlmsg_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user