Package: openjdk-8
Version: 8u181-b13-1
Severity: normal
Tags: patch

--- Please enter the report below this line. ---

This bugs affects all currently available Java versions in Debian (7, 8, 10 and 
11).
I don't know how to mark this here. The contents of the patch should
be usable for all versions with very little change.

If a java program tries to bind a datagram/UDP socket to a link- or node-local 
multicast
address and also sets the needed interface index, the bind operation on the 
socket
fails with "java.net.SocketException: Invalid argument".

This is because the JVM only transfers the interface index to the scope_id 
field in the struct sockaddr_in6,
if the address to bind to is a link local address (IN6_IS_ADDR_LINKLOCAL()).

A bind to a multicast address of link- or node-local scope needs the scope_id 
field as well.
(There might be an additional problem here, when binding to a higher scoped 
multicast address and trying to use
the non-default-route interface)

The attached patch fixes/adds this in the jvm.

I applied the patch by copying it to an "apt-get source"d openjdk-8 packages 
debian/patches dir and including it
in the debian/rules file in the COMMON_PATCHES variable. The resulting debian 
packages work as expected.

Additionally attached is a very small test program that wrongly throws the 
mentioned exception.
When run with the patched VM it works.
You might have to edit the interface name in line 33 when trying this out.

Regards
  Andre

--- System information. ---
Architecture: 
Kernel:       Linux 4.17.0-3-amd64

Debian Release: buster/sid
  500 unstable-debug  debug.mirrors.debian.org 
  500 unstable        deb.debian.org 

--- Package information. ---
Package's Depends field is empty.

Package's Recommends field is empty.

Package's Suggests field is empty.

diff -Naur jdk/src/solaris/native/java/net/net_util_md.c jdk.new/src/solaris/native/java/net/net_util_md.c
--- a/jdk/src/solaris/native/java/net/net_util_md.c	2018-05-17 22:24:20.000000000 +0200
+++ b/jdk/src/solaris/native/java/net/net_util_md.c	2018-08-28 10:54:00.022607297 +0200
@@ -838,7 +838,9 @@
          * cases the used value is cached for further use.
          */
 #ifdef __linux__
-        if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))) {
+        if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))
+				|| IN6_IS_ADDR_MC_NODELOCAL(&(him6->sin6_addr))
+				|| IN6_IS_ADDR_MC_LINKLOCAL(&(him6->sin6_addr))) {
             int cached_scope_id = 0, scope_id = 0;
 
             if (ia6_cachedscopeidID) {

import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Inet6Address;
import java.net.NetworkInterface;

import java.lang.Error;

class mcast_test {

    private static final byte[] ADDR = new byte[]{
        (byte) 0xff,
        (byte) 0x12,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x00,
        (byte) 0x47,
        (byte) 0x49,
        (byte) 0x47,
        (byte) 0x50
    };

	public static void main(String[] args) throws Exception
	{
		Inet6Address addr = Inet6Address.getByAddress(
				"", ADDR, NetworkInterface.getByName("enp6s0")
				);

		System.out.println(addr);

		DatagramSocket s = new DatagramSocket(
				new InetSocketAddress(
					addr,
					29550
					)
				);
	}
};

Reply via email to