Update netlink_route_socket for nlmsg xperm

Translate the netlink_route_socket rules for the new extended permission.
This policy is updated to support kernel with or without the new nlmsg
permission.

Bug: 353255679
Test: CtsSelinuxTargetSdk25TestCases
Test: CtsSelinuxTargetSdk27TestCases
Test: CtsSelinuxTargetSdk28TestCases
Test: CtsSelinuxTargetSdk29TestCases
Test: CtsSelinuxTargetSdk30TestCases
Test: CtsSelinuxTargetSdkCurrentTestCases
Test: CtsLibcoreTestCases
Change-Id: Idf9eeded4f6dbb2711af34f01643a6d025d89c79
diff --git a/private/access_vectors b/private/access_vectors
index 2779926..1ad1885 100644
--- a/private/access_vectors
+++ b/private/access_vectors
@@ -398,6 +398,7 @@
 	nlmsg_write
 	nlmsg_readpriv
 	nlmsg_getneigh
+	nlmsg
 }
 
 class netlink_tcpdiag_socket
diff --git a/private/app_neverallows.te b/private/app_neverallows.te
index 0e2b01c..1f6a06e 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -148,7 +148,7 @@
 
 # Disallow sending RTM_GETLINK messages on netlink sockets.
 neverallow all_untrusted_apps domain:netlink_route_socket { bind nlmsg_readpriv };
-neverallow priv_app domain:netlink_route_socket { bind nlmsg_readpriv };
+neverallowxperm all_untrusted_apps domain:netlink_route_socket nlmsg RTM_GETLINK;
 
 # Disallow sending RTM_GETNEIGH{TBL} messages on netlink sockets.
 neverallow {
@@ -158,6 +158,13 @@
   -untrusted_app_29
   -untrusted_app_30
 } domain:netlink_route_socket nlmsg_getneigh;
+neverallowxperm {
+  all_untrusted_apps
+  -untrusted_app_25
+  -untrusted_app_27
+  -untrusted_app_29
+  -untrusted_app_30
+} domain:netlink_route_socket nlmsg RTM_GETNEIGH;
 
 # Do not allow untrusted apps access to /cache
 neverallow { all_untrusted_apps -mediaprovider } { cache_file cache_recovery_file }:dir ~{ r_dir_perms };
diff --git a/private/dhcp.te b/private/dhcp.te
index ce4fef1..437fa0c 100644
--- a/private/dhcp.te
+++ b/private/dhcp.te
@@ -13,6 +13,7 @@
 allow dhcp self:global_capability_class_set { setgid setuid net_admin net_raw net_bind_service };
 allow dhcp self:packet_socket create_socket_perms_no_ioctl;
 allow dhcp self:netlink_route_socket nlmsg_write;
+allowxperm dhcp self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 allow dhcp shell_exec:file rx_file_perms;
 allow dhcp system_file:file rx_file_perms;
 not_full_treble(`allow dhcp vendor_file:file rx_file_perms;')
diff --git a/private/hal_nlinterceptor.te b/private/hal_nlinterceptor.te
index 1a738a5..9004613 100644
--- a/private/hal_nlinterceptor.te
+++ b/private/hal_nlinterceptor.te
@@ -5,4 +5,8 @@
 
 allow hal_nlinterceptor self:global_capability_class_set net_admin;
 allow hal_nlinterceptor self:netlink_generic_socket create_socket_perms_no_ioctl;
-allow hal_nlinterceptor self:netlink_route_socket { create_socket_perms_no_ioctl nlmsg_readpriv nlmsg_write };
+allow hal_nlinterceptor self:netlink_route_socket create_socket_perms_no_ioctl;
+# For kernel < 6.13
+allow hal_nlinterceptor self:netlink_route_socket { nlmsg_readpriv nlmsg_write };
+# For kernel >= 6.13
+allow hal_nlinterceptor self:netlink_route_socket nlmsg;
diff --git a/private/hal_telephony.te b/private/hal_telephony.te
index 306d459..c44f748 100644
--- a/private/hal_telephony.te
+++ b/private/hal_telephony.te
@@ -8,6 +8,7 @@
 allowxperm hal_telephony_server self:udp_socket ioctl priv_sock_ioctls;
 
 allow hal_telephony_server self:netlink_route_socket nlmsg_write;
+allowxperm hal_telephony_server self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 allow hal_telephony_server self:global_capability_class_set { setpcap setgid setuid net_admin net_raw };
 allow hal_telephony_server cgroup:dir create_dir_perms;
 allow hal_telephony_server cgroup:{ file lnk_file } r_file_perms;
diff --git a/private/hal_wifi_hostapd.te b/private/hal_wifi_hostapd.te
index eeb72ba..f5dbfb9 100644
--- a/private/hal_wifi_hostapd.te
+++ b/private/hal_wifi_hostapd.te
@@ -22,6 +22,7 @@
 allow hal_wifi_hostapd_server self:netlink_generic_socket create_socket_perms_no_ioctl;
 allow hal_wifi_hostapd_server self:packet_socket create_socket_perms_no_ioctl;
 allow hal_wifi_hostapd_server self:netlink_route_socket nlmsg_write;
+allowxperm hal_wifi_hostapd_server self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 
 ###
 ### neverallow rules
diff --git a/private/hal_wifi_supplicant.te b/private/hal_wifi_supplicant.te
index 498469d..d2e59e6 100644
--- a/private/hal_wifi_supplicant.te
+++ b/private/hal_wifi_supplicant.te
@@ -15,6 +15,7 @@
 allow hal_wifi_supplicant cgroup:dir create_dir_perms;
 allow hal_wifi_supplicant cgroup_v2:dir create_dir_perms;
 allow hal_wifi_supplicant self:netlink_route_socket nlmsg_write;
+allowxperm hal_wifi_supplicant self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 allow hal_wifi_supplicant self:netlink_socket create_socket_perms_no_ioctl;
 allow hal_wifi_supplicant self:netlink_generic_socket create_socket_perms_no_ioctl;
 allow hal_wifi_supplicant self:packet_socket create_socket_perms;
diff --git a/private/net.te b/private/net.te
index 2c2f091..3e44b2d 100644
--- a/private/net.te
+++ b/private/net.te
@@ -3,11 +3,14 @@
 allow {netdomain -ephemeral_app -sdk_sandbox_all} port_type:udp_socket name_bind;
 allow {netdomain -ephemeral_app -sdk_sandbox_all} port_type:tcp_socket name_bind;
 
-# b/141455849 gate RTM_GETLINK with a new permission nlmsg_readpriv and block access from
-# untrusted_apps.
-# b/171572148 gate RTM_GETNEIGH{TBL} with a new permission nlmsg_getneigh and block access from
-# untrusted_apps. Some untrusted apps (e.g. untrusted_app_25-30) are granted access elsewhere
-# to avoid app-compat breakage.
+# RTM_GETLINK, RTM_GETNEIGH and RTM_GETNEIGHTBL are not accessible to
+# untrusted_app (as these can be abused to recover the MAC address). See
+# b/141455849 and b/171572148. Some untrusted apps (e.g. untrusted_app_25-30)
+# are granted access elsewhere to avoid app-compat breakage. On kernel before
+# 6.13, Android-specific permissions were defined to implement this restriction
+# (nlmsg_readpriv and nlmsg_getneigh). From kernal 6.13 onwards, the permission
+# has been revoked for netdomain. If your domain requires it, access should be
+# granted using the extended permission "nlmsg".
 allow {
   netdomain
   -ephemeral_app
@@ -28,7 +31,8 @@
 # Connect to ports.
 allow netdomain port_type:tcp_socket name_connect;
 # See changes to the routing table.
-allow netdomain self:netlink_route_socket { create read getattr write setattr lock append connect getopt setopt shutdown nlmsg_read };
+allow netdomain self:netlink_route_socket { create read getattr write setattr lock append connect getopt setopt shutdown nlmsg_read nlmsg };
+allowxperm netdomain self:netlink_route_socket nlmsg unpriv_route_socket_nlmsgs;
 
 # Talks to netd via dnsproxyd socket.
 unix_socket_connect(netdomain, dnsproxyd, netd)
diff --git a/private/netd.te b/private/netd.te
index d966bcc..1c8fed4 100644
--- a/private/netd.te
+++ b/private/netd.te
@@ -64,6 +64,7 @@
 
 allow netd self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
 allow netd self:netlink_route_socket nlmsg_write;
+allowxperm netd self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 allow netd self:netlink_nflog_socket create_socket_perms_no_ioctl;
 allow netd self:netlink_socket create_socket_perms_no_ioctl;
 allow netd self:netlink_tcpdiag_socket create_socket_perms_no_ioctl;
diff --git a/private/network_stack.te b/private/network_stack.te
index e58d4fd..70b3ed3 100644
--- a/private/network_stack.te
+++ b/private/network_stack.te
@@ -23,6 +23,7 @@
 
 # Monitor neighbors via netlink.
 allow network_stack self:netlink_route_socket nlmsg_write;
+allowxperm network_stack self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 
 # Use netlink uevent sockets.
 allow network_stack self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
diff --git a/private/priv_app.te b/private/priv_app.te
index 1ef5be1..a3ba019 100644
--- a/private/priv_app.te
+++ b/private/priv_app.te
@@ -297,3 +297,7 @@
   bluetooth_socket iucv_socket rxrpc_socket isdn_socket phonet_socket ieee802154_socket caif_socket
   alg_socket nfc_socket kcm_socket qipcrtr_socket smc_socket xdp_socket
 } *;
+
+# Disallow sending RTM_GETLINK messages on netlink sockets.
+neverallow priv_app domain:netlink_route_socket { bind nlmsg_readpriv };
+neverallowxperm priv_app domain:netlink_route_socket nlmsg RTM_GETLINK;
diff --git a/private/recovery.te b/private/recovery.te
index 24dfd43..dbc1ab3 100644
--- a/private/recovery.te
+++ b/private/recovery.te
@@ -26,7 +26,13 @@
   set_prop(recovery, gsid_prop)
 
   # These are needed to allow recovery to manage network
-  allow recovery self:netlink_route_socket { create write read nlmsg_readpriv nlmsg_read };
+  allow recovery self:netlink_route_socket create_socket_perms_no_ioctl;
+  # For kernel < 6.13
+  allow recovery self:netlink_route_socket { nlmsg_readpriv nlmsg_read };
+  # For kernel >= 6.13
+  allow recovery self:netlink_route_socket nlmsg;
+  allowxperm recovery self:netlink_route_socket nlmsg unpriv_route_socket_nlmsgs;
+  allowxperm recovery self:netlink_route_socket nlmsg RTM_GETLINK;
   allow recovery self:global_capability_class_set net_admin;
   allow recovery self:tcp_socket { create ioctl };
   allowxperm recovery self:tcp_socket ioctl { SIOCGIFFLAGS SIOCSIFFLAGS };
diff --git a/private/system_server.te b/private/system_server.te
index 1cced81..2887667 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -180,6 +180,7 @@
 
 # Set and get routes directly via netlink.
 allow system_server self:netlink_route_socket nlmsg_write;
+allowxperm system_server self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 
 # Use XFRM (IPsec) netlink sockets
 allow system_server self:netlink_xfrm_socket create_socket_perms_no_ioctl;
diff --git a/private/untrusted_app_25.te b/private/untrusted_app_25.te
index d59245c..f4d17ef 100644
--- a/private/untrusted_app_25.te
+++ b/private/untrusted_app_25.te
@@ -52,6 +52,8 @@
 # allow sending RTM_GETNEIGH{TBL} messages.
 allow untrusted_app_25 self:netlink_route_socket nlmsg_getneigh;
 auditallow untrusted_app_25 self:netlink_route_socket nlmsg_getneigh;
+allowxperm untrusted_app_25 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
+auditallowxperm untrusted_app_25 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
 
 # Connect to mdnsd via mdnsd socket.
 unix_socket_connect(untrusted_app_25, mdnsd, mdnsd)
diff --git a/private/untrusted_app_27.te b/private/untrusted_app_27.te
index 8c970d8..cb3a860 100644
--- a/private/untrusted_app_27.te
+++ b/private/untrusted_app_27.te
@@ -40,6 +40,8 @@
 # allow sending RTM_GETNEIGH{TBL} messages.
 allow untrusted_app_27 self:netlink_route_socket nlmsg_getneigh;
 auditallow untrusted_app_27 self:netlink_route_socket nlmsg_getneigh;
+allowxperm untrusted_app_27 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
+auditallowxperm untrusted_app_27 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
 
 # Connect to mdnsd via mdnsd socket.
 unix_socket_connect(untrusted_app_27, mdnsd, mdnsd)
diff --git a/private/untrusted_app_29.te b/private/untrusted_app_29.te
index ed0bbfc..ddd3412 100644
--- a/private/untrusted_app_29.te
+++ b/private/untrusted_app_29.te
@@ -18,6 +18,8 @@
 # allow sending RTM_GETNEIGH{TBL} messages.
 allow untrusted_app_29 self:netlink_route_socket nlmsg_getneigh;
 auditallow untrusted_app_29 self:netlink_route_socket nlmsg_getneigh;
+allowxperm untrusted_app_29 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
+auditallowxperm untrusted_app_29 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
 
 # Connect to mdnsd via mdnsd socket.
 unix_socket_connect(untrusted_app_29, mdnsd, mdnsd)
diff --git a/private/untrusted_app_30.te b/private/untrusted_app_30.te
index c87548e..b645b05 100644
--- a/private/untrusted_app_30.te
+++ b/private/untrusted_app_30.te
@@ -20,6 +20,8 @@
 # allow sending RTM_GETNEIGH{TBL} messages.
 allow untrusted_app_30 self:netlink_route_socket nlmsg_getneigh;
 auditallow untrusted_app_30 self:netlink_route_socket nlmsg_getneigh;
+allowxperm untrusted_app_30 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
+auditallowxperm untrusted_app_30 self:netlink_route_socket nlmsg { RTM_GETNEIGH RTM_GETNEIGHTBL };
 
 # Connect to mdnsd via mdnsd socket.
 unix_socket_connect(untrusted_app_30, mdnsd, mdnsd)
diff --git a/private/wifi_mainline_supplicant.te b/private/wifi_mainline_supplicant.te
index d6c7998..7980678 100644
--- a/private/wifi_mainline_supplicant.te
+++ b/private/wifi_mainline_supplicant.te
@@ -27,5 +27,6 @@
 
 # Netlink sockets
 allow wifi_mainline_supplicant self:netlink_route_socket { bind create read write nlmsg_readpriv nlmsg_write };
+allowxperm wifi_mainline_supplicant self:netlink_route_socket nlmsg priv_route_socket_nlmsgs;
 allow wifi_mainline_supplicant self:netlink_socket create_socket_perms_no_ioctl;
 allow wifi_mainline_supplicant self:netlink_generic_socket create_socket_perms_no_ioctl;
diff --git a/vendor/ot_rcp.te b/vendor/ot_rcp.te
index 3d56bf4..fd9cae2 100644
--- a/vendor/ot_rcp.te
+++ b/vendor/ot_rcp.te
@@ -14,4 +14,10 @@
 allow ot_rcp self:udp_socket { bind create ioctl read setopt write };
 allow ot_rcp node:udp_socket node_bind;
 allow ot_rcp port:udp_socket name_bind;
-allow ot_rcp self:netlink_route_socket { nlmsg_read nlmsg_readpriv create read write };
+allow ot_rcp self:netlink_route_socket create_socket_perms_no_ioctl;
+# For kernel < 6.13
+allow ot_rcp self:netlink_route_socket { nlmsg_read nlmsg_readpriv };
+# For kernel >= 6.13
+allow ot_rcp self:netlink_route_socket nlmsg;
+allowxperm ot_rcp self:netlink_route_socket nlmsg unpriv_route_socket_nlmsgs;
+allowxperm ot_rcp self:netlink_route_socket nlmsg RTM_GETLINK;