# HG changeset patch # User michaelm # Date 1573743709 0 # Node ID 5e250ee9259efb743b70f798d46b4d53f730213e # Parent 7893d10125801c5322e9f6071ce3baa0fc743c01 unixdomainchannels: fix some sockaddr_un address handling diff -r 7893d1012580 -r 5e250ee9259e src/java.base/share/native/libnet/net_util.h --- a/src/java.base/share/native/libnet/net_util.h Thu Nov 14 12:40:13 2019 +0000 +++ b/src/java.base/share/native/libnet/net_util.h Thu Nov 14 15:01:49 2019 +0000 @@ -166,7 +166,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port); JNIEXPORT jobject JNICALL -NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa); +NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa, socklen_t len); JNIEXPORT jint JNICALL NET_UnixSocketAddressToSockaddr(JNIEnv *env, jobject uaddr, struct sockaddr_un *sa, int *len); diff -r 7893d1012580 -r 5e250ee9259e src/java.base/unix/native/libnio/ch/InheritedChannel.c --- a/src/java.base/unix/native/libnio/ch/InheritedChannel.c Thu Nov 14 12:40:13 2019 +0000 +++ b/src/java.base/unix/native/libnio/ch/InheritedChannel.c Thu Nov 14 15:01:49 2019 +0000 @@ -77,7 +77,7 @@ if (getpeername(fd, (struct sockaddr *)&sa, &len) == 0) { if (sa.sun_family == AF_UNIX) { - remote_sa = NET_SockaddrToUnixAddress(env, &sa); + remote_sa = NET_SockaddrToUnixAddress(env, &sa, len); } } return remote_sa; diff -r 7893d1012580 -r 5e250ee9259e src/java.base/unix/native/libnio/ch/Net.c --- a/src/java.base/unix/native/libnio/ch/Net.c Thu Nov 14 12:40:13 2019 +0000 +++ b/src/java.base/unix/native/libnio/ch/Net.c Thu Nov 14 15:01:49 2019 +0000 @@ -51,12 +51,19 @@ extern jmethodID udsa_ctorID; extern jfieldID udsa_pathID; +#define PATHLEN(len) (len - offsetof(struct sockaddr_un, sun_path)) + JNIEXPORT jobject JNICALL -NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa) { +NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa, socklen_t len) { if (sa->sun_family == AF_UNIX) { - char *name = sa->sun_path; + char *name; + if (PATHLEN(len) == 0) { + name = ""; + } else { + name = sa->sun_path; + } jstring nstr = JNU_NewStringPlatform(env, name); return (*env)->NewObject(env, udsa_class, udsa_ctorID, nstr); } @@ -110,8 +117,8 @@ int sa_len = 0; int rv = 0; - if (uaddr == NULL) - return; /* Rely on implicit bind */ + if (uaddr == NULL) + return; /* Rely on implicit bind */ if (NET_UnixSocketAddressToSockaddr(env, uaddr, &sa, &sa_len) != 0) return; @@ -180,7 +187,7 @@ setfdval(env, newfdo, newfd); - usa = NET_SockaddrToUnixAddress(env, &sa); + usa = NET_SockaddrToUnixAddress(env, &sa, sa_len); CHECK_NULL_RETURN(usa, IOS_THROWN); (*env)->SetObjectArrayElement(env, usaa, 0, usa); @@ -198,7 +205,7 @@ handleSocketError(env, errno); return NULL; } - return NET_SockaddrToUnixAddress(env, &sa); + return NET_SockaddrToUnixAddress(env, &sa, sa_len); } /** diff -r 7893d1012580 -r 5e250ee9259e src/java.base/windows/native/libnio/ch/Net.c --- a/src/java.base/windows/native/libnio/ch/Net.c Thu Nov 14 12:40:13 2019 +0000 +++ b/src/java.base/windows/native/libnio/ch/Net.c Thu Nov 14 15:01:49 2019 +0000 @@ -90,12 +90,19 @@ extern jmethodID udsa_ctorID; extern jfieldID udsa_pathID; +#define PATHLEN(len) (len - offsetof(struct sockaddr_un, sun_path)) + JNIEXPORT jobject JNICALL -NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa) { +NET_SockaddrToUnixAddress(JNIEnv *env, struct sockaddr_un *sa, socklen_t len) { if (sa->sun_family == AF_UNIX) { - char *name = sa->sun_path; + char *name; + if (PATHLEN(len) == 0) { + name = ""; + } else { + name = sa->sun_path; + } jstring nstr = JNU_NewStringPlatform(env, name); return (*env)->NewObject(env, udsa_class, udsa_ctorID, nstr); } @@ -222,7 +229,7 @@ setfdval(env, newfdo, newfd); - usa = NET_SockaddrToUnixAddress(env, &sa); + usa = NET_SockaddrToUnixAddress(env, &sa, sa_len); CHECK_NULL_RETURN(usa, IOS_THROWN); (*env)->SetObjectArrayElement(env, usaa, 0, usa); @@ -239,7 +246,7 @@ handleSocketError(env, errno); return NULL; } - return NET_SockaddrToUnixAddress(env, &sa); + return NET_SockaddrToUnixAddress(env, &sa, sa_len); } JNIEXPORT void JNICALL diff -r 7893d1012580 -r 5e250ee9259e test/jdk/java/nio/channels/unixdomain/Bind.java --- a/test/jdk/java/nio/channels/unixdomain/Bind.java Thu Nov 14 12:40:13 2019 +0000 +++ b/test/jdk/java/nio/channels/unixdomain/Bind.java Thu Nov 14 15:01:49 2019 +0000 @@ -53,100 +53,93 @@ System.out.println("Unix domain channels not supported"); return; } - spath = Path.of("server.sock"); - cpath = Path.of("client.sock"); - sAddr = new UnixDomainSocketAddress(spath); - cAddr = new UnixDomainSocketAddress(cpath); - nullAddr = new UnixDomainSocketAddress(""); + spath = Path.of("server.sock"); + cpath = Path.of("client.sock"); + sAddr = new UnixDomainSocketAddress(spath); + cAddr = new UnixDomainSocketAddress(cpath); + nullAddr = new UnixDomainSocketAddress(""); runTests(); } static boolean supported() { - try { - SocketChannel.open(StandardProtocolFamily.UNIX); - } catch (UnsupportedAddressTypeException e) { - return false; - } catch (Exception e) { - return true; // continue test to see what problem is - } - return true; + try { + SocketChannel.open(StandardProtocolFamily.UNIX); + } catch (UnsupportedAddressTypeException e) { + return false; + } catch (Exception e) { + return true; // continue test to see what problem is + } + return true; } static interface ThrowingRunnable { - public void run() throws Exception; + public void run() throws Exception; } static void init() throws IOException { - Files.deleteIfExists(cpath); - Files.deleteIfExists(spath); - client = null; server = null; accept1 = null; + Files.deleteIfExists(cpath); + Files.deleteIfExists(spath); + client = null; server = null; accept1 = null; } - + static void checkNormal(ThrowingRunnable r) { - try { - init(); - r.run(); - System.out.println("PASS:"); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - cleanup(); - } + try { + init(); + r.run(); + System.out.println("PASS:"); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + cleanup(); + } } static void checkException(Class expected, ThrowingRunnable r) { - try { - init(); - r.run(); - throw new RuntimeException("Exception expected"); - } catch (Exception e) { - if (!expected.isAssignableFrom(e.getClass())) { - String msg = "Expected: " + expected + " Got: " + e.getClass(); - throw new RuntimeException(msg); - } - System.out.println("PASS: Got " + e); - } finally { - cleanup(); - } + try { + init(); + r.run(); + throw new RuntimeException("Exception expected"); + } catch (Exception e) { + if (!expected.isAssignableFrom(e.getClass())) { + String msg = "Expected: " + expected + " Got: " + e.getClass(); + throw new RuntimeException(msg); + } + System.out.println("PASS: Got " + e); + } finally { + cleanup(); + } } static void cleanup() { - try { - if (server != null) - server.close(); - if (client != null) - client.close(); - if (accept1 != null) - accept1.close(); - } catch (IOException e) {} + try { + if (server != null) + server.close(); + if (client != null) + client.close(); + if (accept1 != null) + accept1.close(); + } catch (IOException e) {} } static void assertClientAddress(SocketAddress a) { - assertAddress(a, cAddr, "client"); + assertAddress(a, cAddr, "client"); } static void assertServerAddress(SocketAddress a) { - assertAddress(a, sAddr, "server"); + assertAddress(a, sAddr, "server"); } static void assertAddress(SocketAddress a, UnixDomainSocketAddress a1, String s) { - if (!(a instanceof UnixDomainSocketAddress)) - throw new RuntimeException("wrong address type"); - UnixDomainSocketAddress ua = (UnixDomainSocketAddress)a; - if (!a.equals(a1)) - throw new RuntimeException("this is not the " + s + " address"); + if (!(a instanceof UnixDomainSocketAddress)) { + System.err.println("adddr = " + a); + throw new RuntimeException("wrong address type"); + } + UnixDomainSocketAddress ua = (UnixDomainSocketAddress)a; + if (!a.equals(a1)) + throw new RuntimeException("this is not the " + s + " address"); } public static void runTests() throws IOException { - checkNormal(() -> { - client = SocketChannel.open(StandardProtocolFamily.UNIX); - client.bind(cAddr); - }); - checkNormal(() -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.bind(sAddr); - }); - // Repeat first two to make sure they are repeatable checkNormal(() -> { client = SocketChannel.open(StandardProtocolFamily.UNIX); client.bind(cAddr); @@ -155,45 +148,55 @@ server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); server.bind(sAddr); }); - // client bind to null: allowed - checkNormal(() -> { - client = SocketChannel.open(StandardProtocolFamily.UNIX); - client.bind(null); - assertAddress(client.getLocalAddress(), nullAddr, "null address"); - }); - // server bind to null: not allowed - checkException( - BindException.class, () -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.bind(null); - } - ); - // server no bind : not allowed - checkException( - NotYetBoundException.class, () -> { - server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); - server.accept(); - } - ); - // client implicit bind and connect - checkNormal(() -> { + // Repeat first two to make sure they are repeatable + checkNormal(() -> { + client = SocketChannel.open(StandardProtocolFamily.UNIX); + client.bind(cAddr); + }); + checkNormal(() -> { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.bind(sAddr); + }); + // client bind to null: allowed + checkNormal(() -> { + client = SocketChannel.open(StandardProtocolFamily.UNIX); + client.bind(null); + SocketAddress a = client.getLocalAddress(); + assertAddress(client.getLocalAddress(), nullAddr, "null address"); + }); + // server bind to null: not allowed + checkException( + BindException.class, () -> { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.bind(null); + } + ); + // server no bind : not allowed + checkException( + NotYetBoundException.class, () -> { + server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); + server.accept(); + } + ); + // client implicit bind and connect + checkNormal(() -> { server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); client = SocketChannel.open(StandardProtocolFamily.UNIX); server.bind(sAddr); - client.connect(sAddr); - assertAddress(client.getLocalAddress(), nullAddr, "null address"); - assertServerAddress(server.getLocalAddress()); - }); - // client null bind and connect (check all addresses) - checkNormal(() -> { + client.connect(sAddr); + assertAddress(client.getLocalAddress(), nullAddr, "null address"); + assertServerAddress(server.getLocalAddress()); + }); + // client null bind and connect (check all addresses) + checkNormal(() -> { server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); client = SocketChannel.open(StandardProtocolFamily.UNIX); server.bind(sAddr); - client.bind(null); - client.connect(sAddr); - assertAddress(client.getLocalAddress(), nullAddr, "null address"); - assertServerAddress(server.getLocalAddress()); - }); + client.bind(null); + client.connect(sAddr); + assertAddress(client.getLocalAddress(), nullAddr, "null address"); + assertServerAddress(server.getLocalAddress()); + }); // client explicit bind and connect (check all addresses) checkNormal(() -> { server = ServerSocketChannel.open(StandardProtocolFamily.UNIX); @@ -201,12 +204,12 @@ server.bind(sAddr); client.bind(cAddr); client.connect(sAddr); - accept1 = server.accept(); + accept1 = server.accept(); assertClientAddress(client.getLocalAddress()); assertServerAddress(server.getLocalAddress()); - assertAddress(client.getRemoteAddress(), sAddr, "client's remote server address"); - assertAddress(accept1.getLocalAddress(), sAddr, "accepted local address (server)"); - assertAddress(accept1.getRemoteAddress(), cAddr, "accepted remote address (client)"); + assertAddress(client.getRemoteAddress(), sAddr, "client's remote server address"); + assertAddress(accept1.getLocalAddress(), sAddr, "accepted local address (server)"); + assertAddress(accept1.getRemoteAddress(), cAddr, "accepted remote address (client)"); }); // server multiple bind : not allowed checkException(