History log of /libcore/ojluni/src/main/java/sun/nio/ch/DefaultSelectorProvider.java
Revision Date Author Comments
00494db3844238de691d75ca6fcdc794380871e5 18-Oct-2017 Victor Chang <vichang@google.com> Don't untag socket before preClose / close

Previously, xt_qtaguid never freed tags when the socket was closed, so
if we didn't untag sockets in userspace it would leak memory. See for
example b/5274621. That was fixed by the fix in b/36374484, so this
code is no longer necessary.

Behavior change
- Automatically untagging sockets on close() is incorrect, because
close() does not close the socket, only the filedescriptor, which might
be only one of the references to the socket. Thus, socket(); dup();
close results in the socket being untagged, even if the dupd socket is
still open.
- Additionally, untagging sockets automatically has undesirable
side-effects. For example, it makes it very difficult for a process to
create and tag a socket, and pass that socket to an app, without losing
the tag.

Workaround to keep old behavior
If an app needs to keep old behavior, the app should call
TrafficStats.untagSocket to remove the tag before sending it to another
process.

Bug: 67425668
Test: CtsLibcoreTestCases
Test: CtsAppSecurityHostTestCases -t android.appsecurity.cts.AppSecurityTests
Test: CtsIncidentHostTestCases -t
com.android.server.cts.NetstatsIncidentTest
Test: CtsOsTestCases -t android.os.cts.StrictModeTest
Test: CtsUsageStatsTestCases -t android.app.usage.cts.NetworkUsageStatsTest
Change-Id: Ic311e626a57dec5584c97c8899468a3c800e7ef0
b9a07e95fa3a4503fba51f127efe39544e3ee228 08-Jun-2017 Tobias Thierer <tobiast@google.com> Tweak Android-changed markers in some sun.nio files.

This CL tweaks changed sections to include upstream code in block comments.
This minimizes the diff to upstream, makes it easier for automated tools
to correctly guess the upstream revision (OpenJDK 8u121-b13) that they are
based on, and makes it easier to review CLs that integrate future upstream
changes.

This CL only changes comments, it doesn't include behavior changes.

Bug: 35910877
Test: Treehugger build succeeds
Change-Id: Id23409ab476118758690cce014a30f2bd8faaea6
519adb2f61bb2bfa6cc993b1ca15cf7022b96697 29-Jun-2016 Shubham Ajmera <shubhamajmera@google.com> Port openJdk8 changes to sun.nio.ch package

- Moved poll event masks from AbstractPollArrayWrapper to Net.
- Removed BsdAsynchronousChannelProvider as it was not being used.
- IP_TOS can now be set for IPv6.

Change-Id: Ia17630280822fabc72f16c68891501ded73dc81c
49965c1dc9da104344f4893a05e45795a5740d20 30-Jun-2016 Ganesh Mahendran <opensource.ganesh@gmail.com> remove x attribute of java file

java file does not need x attribute. This patch removes it.

Change-Id: I2a7170d99f4bee7a7b819621c84dd197ded37fa2
Signed-off-by: Ganesh Mahendran <opensource.ganesh@gmail.com>
173e4cf05284f4f96b0c21976186edfc949559cd 25-May-2016 Narayan Kamath <narayan@google.com> Selector: Use poll based selector instead of an epoll based selector.

The OpenJDK epoll based selector suffers from a serious bug where it
can never successfully deregister keys from closed channels.

The root cause of this bug is the sequence of operations that occur when
a channel that's registered with a selector is closed :

(0) Application code calls Channel.close().

(1) The channel is "preClosed" - We dup2(2) /dev/null into the channel's
file descriptor and the channel is marked as closed at the Java level.

(2) All keys associated with the channel are cancelled. Cancels are
lazy, which means that the Selectors involved won't necessarily
deregister these keys until an ongoing call to select() (if any) returns
or until the next call to select() on that selector.

(3) Once all selectors associated with the channel deregister these
cancelled keys, the channel FD is properly closed (via close(2)). Note
that an arbitrary length of time might elapse between Step 0 and this step.
This isn't a resource leak because the channel's FD is now a reference
to "/dev/null".

THE PROBLEM :
-------------
The default Selector implementation on Linux 2.6 and higher uses epoll(7).
epoll can scale better than poll(2) because a lot of the state related
to the interest set (the set of descriptors we're polling on) is
maintained by the kernel. One of the side-effects of this design is that
callers must call into the kernel to make changes to the interest set
via epoll_ctl(7), for eg., by using EPOLL_CTL_ADD to add descriptors or
EPOLL_CTL_DEL to remove descriptors from the interest set. A call to
epoll_ctl with op = EPOLL_CTL_DEL is made when the selector attempts to
deregister an FD associated with a channel from the interest set (see
Step 2, above). These calls will *always fail* because the channel has
been preClosed (see Step 1). They fail because the kernel uses its own
internal file structure to maintain state, and rejects the command
because the descriptor we're passing in describes a different file
(/dev/null) that isn't selectable and isn't registered with the epoll
instance.

This is an issue in upstream OpenJDK as well and various select
implementations (such as netty) have hacks to work around it. Outside
of Android, things will work OK in most cases because the kernel has its
own internal cleanup logic to deregister files from epoll instances
whenever the last *non epoll* reference to the file has been closed -
and usually this happens at the point at which the dup2(2) from Step 1
is called. However, on Android, sockets tagged with the SocketTagger
will never hit this code path because the socket tagging implementation
(qtaguid) keeps a reference to the internal file until the socket
has been untagged. In cases where sockets are closed without being
untagged, the tagger keeps a reference to it until the process dies.

THE SOLUTION :
--------------
We switch over to using poll(2) instead of epoll(7). One of the
advantages of poll(2) is that there's less state maintained by the
kernel. We don't need to make a syscall (analogous to epoll_ctl)
whenever we want to remove an FD from the interest set; we merely
remove it from the list of FDs passed in the next time we call
through to poll. Poll is also slightly more efficient and less
overhead to set up when the number of FDs being polled is small
(which is the common case on Android).

We also need to make sure that all tagged sockets are untagged before
they're preclosed at the platform level. However, there's nothing we
can do about applications that abuse public api (android.net.TrafficStats).

ALTERNATE APPROACHES :
----------------------
For completeness, I'm listing a couple of other approaches that were
considered but discarded.

- Removing preClose: This has the disadvantage of increasing the amount
of time (Delta between Step 0 and Step 3) a channel's descriptor is
kept alive. This also opens up races in the rare case where a
closed FD number is reused on a different thread while we have reads
pending.

- A Synchronous call to EPOLL_CTL_DEL when a channel is removed: This is a
non-starter because of the specified order of events in
AbstractSelectableChannel; implCloseSelectableChannel must be called
before all associated keys are cancelled.

bug: 28318596

(partially cherry picked from commit 4585ee7a9ef27260cb2e2b54bb18bc68861d5584)

This version of the change preserves the original EPoll classes because
they are used for asynchronous channels.

Change-Id: I61baf5b2403c7e793c167d99d46b28bee93f9ffc
4585ee7a9ef27260cb2e2b54bb18bc68861d5584 25-May-2016 Narayan Kamath <narayan@google.com> Selector: Use poll based selector instead of an epoll based selector.

The OpenJDK epoll based selector suffers from a serious bug where it
can never successfully deregister keys from closed channels.

The root cause of this bug is the sequence of operations that occur when
a channel that's registered with a selector is closed :

(0) Application code calls Channel.close().

(1) The channel is "preClosed" - We dup2(2) /dev/null into the channel's
file descriptor and the channel is marked as closed at the Java level.

(2) All keys associated with the channel are cancelled. Cancels are
lazy, which means that the Selectors involved won't necessarily
deregister these keys until an ongoing call to select() (if any) returns
or until the next call to select() on that selector.

(3) Once all selectors associated with the channel deregister these
cancelled keys, the channel FD is properly closed (via close(2)). Note
that an arbitrary length of time might elapse between Step 0 and this step.
This isn't a resource leak because the channel's FD is now a reference
to "/dev/null".

THE PROBLEM :
-------------
The default Selector implementation on Linux 2.6 and higher uses epoll(7).
epoll can scale better than poll(2) because a lot of the state related
to the interest set (the set of descriptors we're polling on) is
maintained by the kernel. One of the side-effects of this design is that
callers must call into the kernel to make changes to the interest set
via epoll_ctl(7), for eg., by using EPOLL_CTL_ADD to add descriptors or
EPOLL_CTL_DEL to remove descriptors from the interest set. A call to
epoll_ctl with op = EPOLL_CTL_DEL is made when the selector attempts to
deregister an FD associated with a channel from the interest set (see
Step 2, above). These calls will *always fail* because the channel has
been preClosed (see Step 1). They fail because the kernel uses its own
internal file structure to maintain state, and rejects the command
because the descriptor we're passing in describes a different file
(/dev/null) that isn't selectable and isn't registered with the epoll
instance.

This is an issue in upstream OpenJDK as well and various select
implementations (such as netty) have hacks to work around it. Outside
of Android, things will work OK in most cases because the kernel has its
own internal cleanup logic to deregister files from epoll instances
whenever the last *non epoll* reference to the file has been closed -
and usually this happens at the point at which the dup2(2) from Step 1
is called. However, on Android, sockets tagged with the SocketTagger
will never hit this code path because the socket tagging implementation
(qtaguid) keeps a reference to the internal file until the socket
has been untagged. In cases where sockets are closed without being
untagged, the tagger keeps a reference to it until the process dies.

THE SOLUTION :
--------------
We switch over to using poll(2) instead of epoll(7). One of the
advantages of poll(2) is that there's less state maintained by the
kernel. We don't need to make a syscall (analogous to epoll_ctl)
whenever we want to remove an FD from the interest set; we merely
remove it from the list of FDs passed in the next time we call
through to poll. Poll is also slightly more efficient and less
overhead to set up when the number of FDs being polled is small
(which is the common case on Android).

We also need to make sure that all tagged sockets are untagged before
they're preclosed at the platform level. However, there's nothing we
can do about applications that abuse public api (android.net.TrafficStats).

ALTERNATE APPROACHES :
----------------------
For completeness, I'm listing a couple of other approaches that were
considered but discarded.

- Removing preClose: This has the disadvantage of increasing the amount
of time (Delta between Step 0 and Step 3) a channel's descriptor is
kept alive. This also opens up races in the rare case where a
closed FD number is reused on a different thread while we have reads
pending.

- A Synchronous call to EPOLL_CTL_DEL when a channel is removed: This is a
non-starter because of the specified order of events in
AbstractSelectableChannel; implCloseSelectableChannel must be called
before all associated keys are cancelled.

bug: 28318596
Change-Id: I407b06b4b538e19823ac27a4c9ae4c608a01a2ea
51b1b6997fd3f980076b8081f7f1165ccc2a4008 16-Feb-2015 Piotr Jastrzebski <haaawk@google.com> Initial import of OpenJdk files.

Create new libcore/ojluni directory with src/main/java and
src/main/native subdirectiories.

Build ojluni into core-oj jar.

Use openjdk classes from java.awt.font package.

Copy all files from jdk/src/share/classes and jdk/src/solaris/classes
directories in openjdk into libcore/ojluni/src/main/java.

Copy following native files from openjdk to
libcore/ojluni/src/main/native:
jdk/src/solaris/native/java/io/canonicalize_md.c
build/linux-amd64/include/classfile_constants.h
jdk/src/share/native/java/net/DatagramPacket.c
jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c
jdk/src/share/native/java/lang/Double.c
jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h
jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
jdk/src/solaris/native/java/io/FileDescriptor_md.c
jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
jdk/src/share/native/java/io/FileInputStream.c
jdk/src/solaris/native/sun/nio/ch/FileKey.c
jdk/src/solaris/native/java/io/FileOutputStream_md.c
jdk/src/solaris/native/java/io/FileSystem_md.c
jdk/src/share/native/java/lang/Float.c
jdk/src/share/native/java/net/Inet4Address.c
jdk/src/solaris/native/java/net/Inet4AddressImpl.c
jdk/src/share/native/java/net/Inet6Address.c
jdk/src/solaris/native/java/net/Inet6AddressImpl.c
jdk/src/share/native/java/net/InetAddress.c
jdk/src/solaris/native/java/net/InetAddressImplFactory.c
jdk/src/share/native/java/io/io_util.c
jdk/src/solaris/native/sun/nio/ch/IOUtil.c
jdk/src/share/native/java/io/io_util.h
jdk/src/solaris/native/java/io/io_util_md.c
jdk/src/solaris/native/java/io/io_util_md.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/java_io_FileDescriptor.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileInputStream.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileOutputStream.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_FileSystem.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_ObjectStreamClass.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_io_UnixFileSystem.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Double.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Float.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Integer.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Long.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Runtime.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Shutdown.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_StrictMath.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_String.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_System.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Thread.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/java_lang_Throwable.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_DatagramPacket.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet4Address.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet4AddressImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet6Address.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_Inet6AddressImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_InetAddress.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_InetAddressImplFactory.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_NetworkInterface.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_PlainDatagramSocketImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_PlainSocketImpl.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketInputStream.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketOptions.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/java_net_SocketOutputStream.h
jdk/src/share/native/java/lang/java_props.h
jdk/src/solaris/native/java/lang/java_props_md.c
jdk/src/share/native/java/util/zip/Adler32.c as java_util_zip_Adler32.c
jdk/src/share/native/java/util/zip/CRC32.c as java_util_zip_CRC32.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_CRC32.h
jdk/src/share/native/java/util/zip/Deflater.c as java_util_zip_Deflater.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_Deflater.h
jdk/src/share/native/java/util/zip/Inflater.c as java_util_zip_Inflater.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_Inflater.h
jdk/src/share/native/java/util/zip/ZipFile.c as java_util_zip_ZipFile.c
build/linux-amd64/tmp/sun/java.util.zip/zip/CClassHeaders/java_util_zip_ZipFile.h
jdk/src/share/native/java/lang/fdlibm/include/jfdlibm.h
jdk/src/share/native/common/jlong.h
jdk/src/solaris/native/common/jlong_md.h
jdk/src/share/native/common/jni_util.c
jdk/src/share/native/common/jni_util.h
jdk/src/solaris/native/common/jni_util_md.c
jdk/src/share/javavm/export/jvm.h
jdk/src/solaris/javavm/export/jvm_md.h
jdk/src/solaris/native/java/net/linux_close.c
jdk/src/share/native/sun/misc/NativeSignalHandler.c
jdk/src/solaris/native/sun/nio/ch/NativeThread.c
jdk/src/share/native/java/net/net_util.c
jdk/src/share/native/java/net/net_util.h
jdk/src/solaris/native/java/net/net_util_md.c
jdk/src/solaris/native/java/net/net_util_md.h
jdk/src/solaris/native/java/net/NetworkInterface.c
jdk/src/share/native/sun/nio/ch/nio.h
jdk/src/solaris/native/sun/nio/ch/nio_util.h
jdk/src/share/native/java/io/ObjectStreamClass.c
jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c
jdk/src/solaris/native/java/net/PlainSocketImpl.c
jdk/src/solaris/native/java/lang/ProcessEnvironment_md.c
jdk/src/share/native/java/lang/Runtime.c
jdk/src/share/native/java/lang/Shutdown.c
jdk/src/share/native/sun/misc/Signal.c
jdk/src/solaris/native/java/net/SocketInputStream.c
jdk/src/solaris/native/java/net/SocketOutputStream.c
jdk/src/share/native/java/lang/StrictMath.c
jdk/src/share/native/java/lang/String.c
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/sun_misc_NativeSignalHandler.h
build/linux-amd64/tmp/java/java.lang/java/CClassHeaders/sun_misc_Signal.h
build/linux-amd64/tmp/sun/java.net/net/CClassHeaders/sun_net_spi_DefaultProxySelector.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileChannelImpl.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileDispatcherImpl.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_FileKey.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_IOStatus.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_IOUtil.h
build/linux-amd64/tmp/java/java.nio/nio/CClassHeaders/sun_nio_ch_NativeThread.h
jdk/src/share/native/java/lang/System.c
jdk/src/share/native/java/lang/Thread.c
jdk/src/share/native/java/lang/Throwable.c
jdk/src/solaris/native/java/io/UnixFileSystem_md.c
jdk/src/solaris/native/java/lang/UNIXProcess_md.c
jdk/src/share/native/java/util/zip/zip_util.c
jdk/src/share/native/java/util/zip/zip_util.h

Change-Id: Ib237df4e1b7b5b4d9f12e74d189e6ec9eed3c31d