Enforce ioctl command whitelisting on all sockets
Remove the ioctl permission for most socket types. For others, such as
tcp/udp/rawip/unix_dgram/unix_stream set a default unprivileged whitelist
that individual domains may extend (except where neverallowed like
untrusted_app). Enforce via a neverallowxperm rule.
Change-Id: I15548d830f8eff1fd4d64005c5769ca2be8d4ffe
diff --git a/bluetooth.te b/bluetooth.te
index 2723df2..2b99c3e 100644
--- a/bluetooth.te
+++ b/bluetooth.te
@@ -2,6 +2,8 @@
type bluetooth, domain, domain_deprecated;
app_domain(bluetooth)
net_domain(bluetooth)
+# Allow access to net_admin ioctls
+allowxperm bluetooth self:udp_socket ioctl priv_sock_ioctls;
wakelock_use(bluetooth);
@@ -25,9 +27,9 @@
allow bluetooth self:capability2 wake_alarm;
# tethering
-allow bluetooth self:packet_socket create_socket_perms;
+allow bluetooth self:packet_socket create_socket_perms_no_ioctl;
allow bluetooth self:capability { net_admin net_raw net_bind_service };
-allow bluetooth self:tun_socket create_socket_perms;
+allow bluetooth self:tun_socket create_socket_perms_no_ioctl;
allow bluetooth tun_device:chr_file rw_file_perms;
allow bluetooth efs_file:dir search;
diff --git a/clatd.te b/clatd.te
index fd6be00..8632087 100644
--- a/clatd.te
+++ b/clatd.te
@@ -29,5 +29,5 @@
allow clatd self:capability ipc_lock;
allow clatd self:netlink_route_socket nlmsg_write;
-allow clatd self:{ packet_socket rawip_socket tun_socket } create_socket_perms;
+allow clatd self:{ packet_socket rawip_socket tun_socket } create_socket_perms_no_ioctl;
allow clatd tun_device:chr_file rw_file_perms;
diff --git a/dhcp.te b/dhcp.te
index a858e08..a051b19 100644
--- a/dhcp.te
+++ b/dhcp.te
@@ -7,7 +7,7 @@
allow dhcp cgroup:dir { create write add_name };
allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service };
-allow dhcp self:packet_socket create_socket_perms;
+allow dhcp self:packet_socket create_socket_perms_no_ioctl;
allow dhcp self:netlink_route_socket nlmsg_write;
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
diff --git a/dnsmasq.te b/dnsmasq.te
index e5e4198..c52640f 100644
--- a/dnsmasq.te
+++ b/dnsmasq.te
@@ -3,6 +3,7 @@
type dnsmasq_exec, exec_type, file_type;
net_domain(dnsmasq)
+allowxperm dnsmasq self:udp_socket ioctl priv_sock_ioctls;
# TODO: Run with dhcp group to avoid need for dac_override.
allow dnsmasq self:capability dac_override;
diff --git a/domain.te b/domain.te
index a312acb..38a6db8 100644
--- a/domain.te
+++ b/domain.te
@@ -28,7 +28,6 @@
allow domain self:{ fifo_file file } rw_file_perms;
allow domain self:unix_dgram_socket { create_socket_perms sendto };
allow domain self:unix_stream_socket { create_stream_socket_perms connectto };
-allowxperm domain domain:{ unix_dgram_socket unix_stream_socket } ioctl unpriv_unix_sock_ioctls;
# Inherit or receive open files from others.
allow domain init:fd use;
@@ -146,10 +145,25 @@
allow domain fs_type:filesystem getattr;
allow domain fs_type:dir getattr;
+# Restrict all domains to a whitelist for common socket types. Additional
+# ioctl commands may be added to individual domains, but this sets safe
+# defaults for all processes. Note that granting this whitelist to domain does
+# not grant the ioctl permission on these socket types. That must be granted
+# separately.
+allowxperm domain domain:{ rawip_socket tcp_socket udp_socket }
+ ioctl { unpriv_sock_ioctls unpriv_tty_ioctls };
+# default whitelist for unix sockets.
+allowxperm domain domain:{ unix_dgram_socket unix_stream_socket }
+ ioctl unpriv_unix_sock_ioctls;
+
+
###
### neverallow rules
###
+# All socket ioctls must be restricted to a whitelist.
+neverallowxperm domain domain:socket_class_set ioctl { 0 };
+
# Do not allow any domain other than init or recovery to create unlabeled files.
neverallow { domain -init -recovery } unlabeled:dir_file_class_set create;
diff --git a/healthd.te b/healthd.te
index 0c31091..0bf92c8 100644
--- a/healthd.te
+++ b/healthd.te
@@ -11,7 +11,7 @@
allow healthd self:capability { net_admin sys_tty_config };
wakelock_use(healthd)
-allow healthd self:netlink_kobject_uevent_socket create_socket_perms;
+allow healthd self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
binder_use(healthd)
binder_service(healthd)
binder_call(healthd, system_server)
diff --git a/hostapd.te b/hostapd.te
index 41f429a..62f9cc7 100644
--- a/hostapd.te
+++ b/hostapd.te
@@ -15,9 +15,10 @@
allow hostapd proc_net:file { getattr open read };
# Various socket permissions.
-allow hostapd self:netlink_socket create_socket_perms;
-allow hostapd self:netlink_generic_socket create_socket_perms;
-allow hostapd self:packet_socket create_socket_perms;
+allowxperm hostapd self:udp_socket ioctl priv_sock_ioctls;
+allow hostapd self:netlink_socket create_socket_perms_no_ioctl;
+allow hostapd self:netlink_generic_socket create_socket_perms_no_ioctl;
+allow hostapd self:packet_socket create_socket_perms_no_ioctl;
allow hostapd self:netlink_route_socket nlmsg_write;
# hostapd can read and write WiFi related data and configuration.
diff --git a/init.te b/init.te
index e2f30a0..0a96314 100644
--- a/init.te
+++ b/init.te
@@ -295,6 +295,8 @@
# Run "ifup lo" to bring up the localhost interface
allow init self:udp_socket { create ioctl };
+# in addition to unpriv ioctls granted to all domains, init also needs:
+allowxperm init self:udp_socket ioctl SIOCSIFFLAGS;
allow init self:capability net_raw;
# This line seems suspect, as it should not really need to
diff --git a/ioctl_macros b/ioctl_macros
index 858bd78..d4ef2a6 100644
--- a/ioctl_macros
+++ b/ioctl_macros
@@ -21,7 +21,7 @@
SIOCSIFDSTADDR SIOCSIFBRDADDR SIOCSIFNETMASK SIOCGIFMETRIC SIOCSIFMETRIC SIOCGIFMEM
SIOCSIFMEM SIOCSIFMTU SIOCSIFNAME SIOCSIFHWADDR SIOCGIFENCAP SIOCSIFENCAP
SIOCGIFHWADDR SIOCGIFSLAVE SIOCSIFSLAVE SIOCADDMULTI SIOCDELMULTI
-SIOCSIFPFLAGS SIOCGIFPFLAGS SIOCDIFADDR SIOCSIFHWBROADCAST SIOCGIFBR SIOCSIFBR
+SIOCSIFPFLAGS SIOCGIFPFLAGS SIOCDIFADDR SIOCSIFHWBROADCAST SIOCKILLADDR SIOCGIFBR SIOCSIFBR
SIOCSIFTXQLEN SIOCETHTOOL SIOCGMIIPHY SIOCGMIIREG SIOCSMIIREG SIOCWANDEV
SIOCOUTQNSD SIOCDARP SIOCGARP SIOCSARP SIOCDRARP SIOCGRARP SIOCSRARP SIOCGIFMAP
SIOCSIFMAP SIOCADDDLCI SIOCDELDLCI SIOCGIFVLAN SIOCSIFVLAN SIOCBONDENSLAVE
diff --git a/logd.te b/logd.te
index 99d13e6..447fae5 100644
--- a/logd.te
+++ b/logd.te
@@ -12,7 +12,7 @@
allow logd self:capability { setuid setgid setpcap sys_nice audit_control };
allow logd self:capability2 syslog;
-allow logd self:netlink_audit_socket { create_socket_perms nlmsg_write };
+allow logd self:netlink_audit_socket { create_socket_perms_no_ioctl nlmsg_write };
allow logd kernel:system syslog_read;
allow logd kmsg_device:chr_file w_file_perms;
allow logd system_data_file:{ file lnk_file } r_file_perms;
diff --git a/mtp.te b/mtp.te
index 9677abd..02d4b56 100644
--- a/mtp.te
+++ b/mtp.te
@@ -6,7 +6,7 @@
net_domain(mtp)
# pptp policy
-allow mtp self:socket create_socket_perms;
+allow mtp self:socket create_socket_perms_no_ioctl;
allow mtp self:capability net_raw;
allow mtp ppp:process signal;
allow mtp vpn_data_file:dir search;
diff --git a/netd.te b/netd.te
index 515ad4f..976c43d 100644
--- a/netd.te
+++ b/netd.te
@@ -4,6 +4,8 @@
init_daemon_domain(netd)
net_domain(netd)
+# in addition to ioctls whitelisted for all domains, grant netd priv_sock_ioctls.
+allowxperm netd self:udp_socket ioctl priv_sock_ioctls;
r_dir_file(netd, cgroup)
allow netd system_server:fd use;
@@ -17,13 +19,13 @@
# for netd to operate.
dontaudit netd self:capability fsetid;
-allow netd self:netlink_kobject_uevent_socket create_socket_perms;
+allow netd self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
allow netd self:netlink_route_socket nlmsg_write;
-allow netd self:netlink_nflog_socket create_socket_perms;
-allow netd self:netlink_socket create_socket_perms;
-allow netd self:netlink_tcpdiag_socket { create_socket_perms nlmsg_read nlmsg_write };
-allow netd self:netlink_generic_socket create_socket_perms;
-allow netd self:netlink_netfilter_socket create_socket_perms;
+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 nlmsg_read nlmsg_write };
+allow netd self:netlink_generic_socket create_socket_perms_no_ioctl;
+allow netd self:netlink_netfilter_socket create_socket_perms_no_ioctl;
allow netd shell_exec:file rx_file_perms;
allow netd system_file:file x_file_perms;
allow netd devpts:chr_file rw_file_perms;
diff --git a/ppp.te b/ppp.te
index d7ed70d..3fb6f2b0 100644
--- a/ppp.te
+++ b/ppp.te
@@ -6,7 +6,7 @@
net_domain(ppp)
-allow ppp mtp:socket rw_socket_perms;
+allow ppp mtp:socket rw_socket_perms_no_ioctl;
allow ppp mtp:unix_dgram_socket rw_socket_perms;
allow ppp ppp_device:chr_file rw_file_perms;
allow ppp self:capability net_admin;
diff --git a/racoon.te b/racoon.te
index bf272d1..c3666bd 100644
--- a/racoon.te
+++ b/racoon.te
@@ -13,8 +13,8 @@
allow racoon cgroup:dir { add_name create };
allow racoon kernel:system module_request;
-allow racoon self:key_socket create_socket_perms;
-allow racoon self:tun_socket create_socket_perms;
+allow racoon self:key_socket create_socket_perms_no_ioctl;
+allow racoon self:tun_socket create_socket_perms_no_ioctl;
allow racoon self:capability { net_admin net_bind_service net_raw setuid };
# XXX: should we give ip-up-vpn its own label (currently racoon domain)
diff --git a/rild.te b/rild.te
index e721c90..0d834e1 100644
--- a/rild.te
+++ b/rild.te
@@ -4,6 +4,8 @@
init_daemon_domain(rild)
net_domain(rild)
+allowxperm rild self:udp_socket ioctl priv_sock_ioctls;
+
allow rild self:netlink_route_socket nlmsg_write;
allow rild kernel:system module_request;
allow rild self:capability { setpcap setgid setuid net_admin net_raw };
@@ -35,15 +37,16 @@
allow rild tty_device:chr_file rw_file_perms;
# Allow rild to create and use netlink sockets.
-allow rild self:netlink_socket create_socket_perms;
-allow rild self:netlink_generic_socket create_socket_perms;
-allow rild self:netlink_kobject_uevent_socket create_socket_perms;
+allow rild self:netlink_socket create_socket_perms_no_ioctl;
+allow rild self:netlink_generic_socket create_socket_perms_no_ioctl;
+allow rild self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
# Access to wake locks
wakelock_use(rild)
-allow rild self:socket create_socket_perms;
-
r_dir_file(rild, proc)
r_dir_file(rild, sysfs_type)
r_dir_file(rild, system_file)
+
+# granting the ioctl permission for rild should be device specific
+allow rild self:socket create_socket_perms_no_ioctl;
diff --git a/surfaceflinger.te b/surfaceflinger.te
index cc07e5b..d02fc93 100644
--- a/surfaceflinger.te
+++ b/surfaceflinger.te
@@ -31,7 +31,7 @@
allow surfaceflinger video_device:chr_file rw_file_perms;
# Create and use netlink kobject uevent sockets.
-allow surfaceflinger self:netlink_kobject_uevent_socket create_socket_perms;
+allow surfaceflinger self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
# Set properties.
set_prop(surfaceflinger, system_prop)
diff --git a/system_server.te b/system_server.te
index 795e255..05e929e 100644
--- a/system_server.te
+++ b/system_server.te
@@ -41,6 +41,9 @@
# system server gets network and bluetooth permissions.
net_domain(system_server)
+# in addition to ioctls whitelisted for all domains, also allow system_server
+# to use privileged ioctls commands. Needed to set up VPNs.
+allowxperm system_server self:udp_socket ioctl priv_sock_ioctls;
bluetooth_domain(system_server)
# These are the capabilities assigned by the zygote to the
@@ -71,15 +74,17 @@
allow system_server self:capability2 wake_alarm;
# Use netlink uevent sockets.
-allow system_server self:netlink_kobject_uevent_socket create_socket_perms;
+allow system_server self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
# Use generic netlink sockets.
-allow system_server self:netlink_socket create_socket_perms;
-allow system_server self:netlink_generic_socket create_socket_perms;
+allow system_server self:netlink_socket create_socket_perms_no_ioctl;
+allow system_server self:netlink_generic_socket create_socket_perms_no_ioctl;
# Use generic "sockets" where the address family is not known
-# to the kernel.
-allow system_server self:socket create_socket_perms;
+# to the kernel. The ioctl permission is specifically omitted here, but may
+# be added to device specific policy along with the ioctl commands to be
+# whitelisted.
+allow system_server self:socket create_socket_perms_no_ioctl;
# Set and get routes directly via netlink.
allow system_server self:netlink_route_socket nlmsg_write;
@@ -119,14 +124,14 @@
allow system_server debugfs:file r_file_perms;
# The DhcpClient and WifiWatchdog use packet_sockets
-allow system_server self:packet_socket create_socket_perms;
+allow system_server self:packet_socket create_socket_perms_no_ioctl;
# NetworkDiagnostics requires explicit bind() calls to ping sockets. These aren't actually the same
# as raw sockets, but the kernel doesn't yet distinguish between the two.
allow system_server node:rawip_socket node_bind;
# 3rd party VPN clients require a tun_socket to be created
-allow system_server self:tun_socket create_socket_perms;
+allow system_server self:tun_socket create_socket_perms_no_ioctl;
# Talk to init and various daemons via sockets.
unix_socket_connect(system_server, installd, installd)
diff --git a/tee.te b/tee.te
index d0b7391..3d4cc2f 100644
--- a/tee.te
+++ b/tee.te
@@ -11,8 +11,8 @@
allow tee tee_device:chr_file rw_file_perms;
allow tee tee_data_file:dir rw_dir_perms;
allow tee tee_data_file:file create_file_perms;
-allow tee self:netlink_socket create_socket_perms;
-allow tee self:netlink_generic_socket create_socket_perms;
+allow tee self:netlink_socket create_socket_perms_no_ioctl;
+allow tee self:netlink_generic_socket create_socket_perms_no_ioctl;
allow tee ion_device:chr_file r_file_perms;
r_dir_file(tee, sysfs_type)
allow tee system_data_file:file { getattr read };
diff --git a/ueventd.te b/ueventd.te
index 657c25b..d4880fa 100644
--- a/ueventd.te
+++ b/ueventd.te
@@ -23,7 +23,7 @@
allow ueventd dev_type:lnk_file { create unlink };
allow ueventd dev_type:chr_file { getattr create setattr unlink };
allow ueventd dev_type:blk_file { getattr relabelfrom relabelto create setattr unlink };
-allow ueventd self:netlink_kobject_uevent_socket create_socket_perms;
+allow ueventd self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
allow ueventd efs_file:dir search;
allow ueventd efs_file:file r_file_perms;
diff --git a/vold.te b/vold.te
index 98ccab4..6e0fa16 100644
--- a/vold.te
+++ b/vold.te
@@ -80,7 +80,7 @@
allow vold tmpfs:dir create_dir_perms;
allow vold tmpfs:dir mounton;
allow vold self:capability { net_admin dac_override mknod sys_admin chown fowner fsetid };
-allow vold self:netlink_kobject_uevent_socket create_socket_perms;
+allow vold self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
allow vold app_data_file:dir search;
allow vold app_data_file:file rw_file_perms;
allow vold loop_device:blk_file create_file_perms;
diff --git a/wificond.te b/wificond.te
index eb02ded..d7979ec 100644
--- a/wificond.te
+++ b/wificond.te
@@ -19,15 +19,13 @@
# create sockets to set interfaces up and down
allow wificond self:udp_socket create_socket_perms;
-# See discussion in b/31226503
-allowxperm wificond self:udp_socket ioctl unpriv_sock_ioctls;
# setting interface state up/down is a privileged ioctl
allowxperm wificond self:udp_socket ioctl { SIOCSIFFLAGS };
allow wificond self:capability { net_admin net_raw };
# allow wificond to speak to nl80211 in the kernel
-allow wificond self:netlink_socket create_socket_perms;
+allow wificond self:netlink_socket create_socket_perms_no_ioctl;
# newer kernels (e.g. 4.4 but not 4.1) have a new class for sockets
-allow wificond self:netlink_generic_socket create_socket_perms;
+allow wificond self:netlink_generic_socket create_socket_perms_no_ioctl;
r_dir_file(wificond, proc_net)
@@ -47,4 +45,4 @@
# dumpstate support
allow wificond dumpstate:fd use;
-allow wificond dumpstate:fifo_file write;
\ No newline at end of file
+allow wificond dumpstate:fifo_file write;
diff --git a/wpa.te b/wpa.te
index 3a2450f..dfb73dc 100644
--- a/wpa.te
+++ b/wpa.te
@@ -5,6 +5,8 @@
init_daemon_domain(wpa)
net_domain(wpa)
+# in addition to ioctls whitelisted for all domains, grant wpa priv_sock_ioctls.
+allowxperm wpa self:udp_socket ioctl priv_sock_ioctls;
r_dir_file(wpa, sysfs_type)
r_dir_file(wpa, proc_net)
@@ -13,9 +15,10 @@
allow wpa self:capability { setuid net_admin setgid net_raw };
allow wpa cgroup:dir create_dir_perms;
allow wpa self:netlink_route_socket nlmsg_write;
-allow wpa self:netlink_socket create_socket_perms;
-allow wpa self:netlink_generic_socket create_socket_perms;
+allow wpa self:netlink_socket create_socket_perms_no_ioctl;
+allow wpa self:netlink_generic_socket create_socket_perms_no_ioctl;
allow wpa self:packet_socket create_socket_perms;
+allowxperm wpa self:packet_socket ioctl { unpriv_sock_ioctls priv_sock_ioctls unpriv_tty_ioctls };
allow wpa wifi_data_file:dir create_dir_perms;
allow wpa wifi_data_file:file create_file_perms;
unix_socket_send(wpa, system_wpa, system_server)