diff --git a/bluetooth.te b/bluetooth.te
index 2723df22e8694d2eb4899281803065ecfd1febbf..146c0e5110d746eefb5d7567f8142ae0dea3a501 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 fd6be00c90ebaf9838304b1a16e46983c117d971..8632087a1035046927df84192ebb906d24a79f2d 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 a858e080faaa6bd28208f675781f243e18dbbb2e..a051b192d11d4a21157558957f2c9959d2b46068 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 e5e4198c0e43cdb481c5a2c8e40b05abc9cb9bcd..c52640f1d765db9afc08211c0bcfb538fdd17fe4 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 1224c6522d248e1faaace11b201aacc8bd8f8fb8..3cd167d6fc5559e785b574bb586a03c169db9402 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 0534e463812f26a89da3b32405dac72919aacb78..eb3c9d239522eb0ec467cbca73bb5719df59c740 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 7e4deed4bcc3654ab09049162b793be627acfad2..fa183cfaab45c3b50b6fa6a44193225bbaba3e44 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 204a0d9eb0156414cc49634057191f34d661d57a..e552c2b25994b883289e4de94a9061fd02e80e75 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 14ebd14105e1806e544085572f9ffee8359496f1..4e1f40df4ca4a78f6ca3bcdf049300fbf11e25fb 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 0831db8c70f42cab81ebb8845fd0cd4722cfe56a..d7df1a13567fef5a5eafb305dfdccba61770c994 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 ef0bd5fea985e53959eacca2a14a61b4f6c0768f..fe70d0aaf3678f73e67afb7a05ba55d6bf50aa54 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 9677abd19a32a187ed39114c2d095abecd416156..02d4b56335fe17ad35eaea9980f935fd4cec61fe 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 1e7e5ec7cdf7c2dbf95d6bd58b295cab2c5c9716..f250aa779a259f44d54470f5c3786c6e3b8b9d6d 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 d7ed70d5defd370642b13c45312d906e719a7799..3fb6f2b06552f58b66bef30f38540b3d02ea4bf1 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 bf272d1e8f057ed279f8b1868ae7d6a5a2377434..c3666bd8541ba66d966a846fc2de955112e7f74c 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 e721c9085bf1ccf6db830a64d7211e3e1a36fe85..81b4a115042d55a4f03759b369ce6cb5d3eb6492 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 6ea3d5483e708f3d2c9c2baaf564a82b708a9858..933773180942b90b94ea0a0e3cd6129357e4e206 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 695182ff17b60cd1f5ef65f09b54542b183ebf45..52cae1b91fdad1948e4963524c2c5741fbb9e05b 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 d0b73910b266a3735c5333675a04add15249c2e9..3d4cc2fba744a18f1b0283ba668283ccd3cc78a6 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 cd9575a0319969b711b5d1010dc7f6df3a0cf292..a101aba97d6d71044f4800a8fef925f486e9c7d2 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 1f335b70bc324de7b349d575e04083e0cc83d6d8..ee98b12fdf40be7cbfac932603bd6e7ac94f918d 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 3661f00c43c562c48f007e734e43947e47e3bf32..dddc801e032989f26630afd165732b4fd3b8517b 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)