From c71c662201fff0232af2a7009552d6d79824670a Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep <jeffv@google.com> Date: Mon, 16 May 2016 21:12:17 -0700 Subject: [PATCH] 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 --- bluetooth.te | 4 ++-- clatd.te | 2 +- dhcp.te | 2 +- dnsmasq.te | 1 + domain.te | 16 +++++++++++++++- global_macros | 2 ++ healthd.te | 2 +- hostapd.te | 7 ++++--- init.te | 2 ++ ioctl_macros | 2 +- logd.te | 2 +- mtp.te | 2 +- netd.te | 14 ++++++++------ ppp.te | 2 +- racoon.te | 4 ++-- rild.te | 11 ++++++----- surfaceflinger.te | 2 +- system_server.te | 19 ++++++++++++------- tee.te | 4 ++-- ueventd.te | 2 +- vold.te | 2 +- wpa.te | 7 +++++-- 22 files changed, 71 insertions(+), 40 deletions(-) diff --git a/bluetooth.te b/bluetooth.te index 2723df22e..146c0e511 100644 --- a/bluetooth.te +++ b/bluetooth.te @@ -25,9 +25,9 @@ allow bluetooth self:capability net_admin; 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 fd6be00c9..8632087a1 100644 --- a/clatd.te +++ b/clatd.te @@ -29,5 +29,5 @@ allow clatd self:capability { net_admin net_raw setuid setgid }; 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 a858e080f..a051b192d 100644 --- a/dhcp.te +++ b/dhcp.te @@ -7,7 +7,7 @@ net_domain(dhcp) 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 e5e4198c0..c52640f1d 100644 --- a/dnsmasq.te +++ b/dnsmasq.te @@ -3,6 +3,7 @@ type dnsmasq, domain, domain_deprecated; 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 1224c6522..3cd167d6f 100644 --- a/domain.te +++ b/domain.te @@ -28,7 +28,6 @@ r_dir_file(domain, self) 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; @@ -141,10 +140,25 @@ allow domain debugfs_trace_marker:file w_file_perms; 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/global_macros b/global_macros index 0534e4638..eb3c9d239 100644 --- a/global_macros +++ b/global_macros @@ -41,6 +41,8 @@ define(`create_ipc_perms', `{ create setattr destroy rw_ipc_perms }') ##################################### # Common socket permission sets. define(`rw_socket_perms', `{ ioctl read getattr write setattr lock append bind connect getopt setopt shutdown }') +define(`rw_socket_perms_no_ioctl', `{ read getattr write setattr lock append bind connect getopt setopt shutdown }') define(`create_socket_perms', `{ create rw_socket_perms }') +define(`create_socket_perms_no_ioctl', `{ create rw_socket_perms_no_ioctl }') define(`rw_stream_socket_perms', `{ rw_socket_perms listen accept }') define(`create_stream_socket_perms', `{ create rw_stream_socket_perms }') diff --git a/healthd.te b/healthd.te index 7e4deed4b..fa183cfaa 100644 --- a/healthd.te +++ b/healthd.te @@ -11,7 +11,7 @@ r_dir_file(healthd, rootfs) 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 204a0d9eb..e552c2b25 100644 --- a/hostapd.te +++ b/hostapd.te @@ -3,11 +3,12 @@ type hostapd, domain, domain_deprecated; type hostapd_exec, exec_type, file_type; net_domain(hostapd) +allowxperm hostapd self:udp_socket ioctl priv_sock_ioctls; allow hostapd self:capability { net_admin net_raw setuid setgid }; -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; +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; allow hostapd wifi_data_file:file rw_file_perms; diff --git a/init.te b/init.te index 14ebd1410..4e1f40df4 100644 --- a/init.te +++ b/init.te @@ -281,6 +281,8 @@ allow init property_type:property_service set; # 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 0831db8c7..d7df1a135 100644 --- a/ioctl_macros +++ b/ioctl_macros @@ -20,7 +20,7 @@ SIOCADDRT SIOCDELRT SIOCRTMSG SIOCSIFLINK SIOCSIFFLAGS SIOCSIFADDR 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 ef0bd5fea..fe70d0aaf 100644 --- a/logd.te +++ b/logd.te @@ -12,7 +12,7 @@ r_dir_file(logd, proc_net) allow logd self:capability { setuid setgid 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 9677abd19..02d4b5633 100644 --- a/mtp.te +++ b/mtp.te @@ -6,7 +6,7 @@ init_daemon_domain(mtp) 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 1e7e5ec7c..f250aa779 100644 --- a/netd.te +++ b/netd.te @@ -4,6 +4,8 @@ type netd_exec, exec_type, file_type; 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 @@ allow netd self:capability { net_admin net_raw kill }; # 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 d7ed70d5d..3fb6f2b06 100644 --- a/ppp.te +++ b/ppp.te @@ -6,7 +6,7 @@ domain_auto_trans(mtp, ppp_exec, ppp) 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 bf272d1e8..c3666bd85 100644 --- a/racoon.te +++ b/racoon.te @@ -13,8 +13,8 @@ allow racoon tun_device:chr_file r_file_perms; 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 e721c9085..81b4a1150 100644 --- a/rild.te +++ b/rild.te @@ -35,15 +35,16 @@ auditallow rild system_radio_prop:property_service set; 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 6ea3d5483..933773180 100644 --- a/surfaceflinger.te +++ b/surfaceflinger.te @@ -31,7 +31,7 @@ allow surfaceflinger video_device:dir r_dir_perms; 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 695182ff1..52cae1b91 100644 --- a/system_server.te +++ b/system_server.te @@ -41,6 +41,9 @@ allow system_server zygote:unix_stream_socket { getopt getattr }; # 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: +allowxperm system_server self:udp_socket ioctl SIOCSIFFLAGS; bluetooth_domain(system_server) # These are the capabilities assigned by the zygote to the @@ -68,15 +71,17 @@ dontaudit system_server self:capability sys_ptrace; allow system_server kernel:system module_request; # 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; @@ -113,14 +118,14 @@ allow system_server proc_sysrq:file rw_file_perms; 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 d0b73910b..3d4cc2fba 100644 --- a/tee.te +++ b/tee.te @@ -11,8 +11,8 @@ allow tee self:capability { dac_override }; 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 cd9575a03..a101aba97 100644 --- a/ueventd.te +++ b/ueventd.te @@ -24,7 +24,7 @@ allow ueventd dev_type:dir create_dir_perms; 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 1f335b70b..ee98b12fd 100644 --- a/vold.te +++ b/vold.te @@ -80,7 +80,7 @@ allow vold tmpfs:filesystem { mount unmount }; 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/wpa.te b/wpa.te index 3661f00c4..dddc801e0 100644 --- a/wpa.te +++ b/wpa.te @@ -5,6 +5,8 @@ type wpa_exec, exec_type, file_type; 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 kernel:system module_request; 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) -- GitLab