From f3c8502e38de714caab8edd895113528f1ea4f5e Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Wed, 4 Feb 2026 00:51:29 +0000 Subject: [PATCH] 8227493: Return a more useful error message from lookupAllHostAddr if getaddrinfo results in EAI_SYSTEM error Reviewed-by: dfuchs, djelinski, michaelm --- .../unix/native/libnet/Inet4AddressImpl.c | 6 ++- .../unix/native/libnet/Inet6AddressImpl.c | 6 ++- .../unix/native/libnet/net_util_md.c | 37 ++++++++++++++++--- .../unix/native/libnet/net_util_md.h | 5 ++- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/java.base/unix/native/libnet/Inet4AddressImpl.c b/src/java.base/unix/native/libnet/Inet4AddressImpl.c index 9bddbcaede7..e99dfd89411 100644 --- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,6 +112,8 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, error == EAI_SYSTEM && errno == EINTR); if (error) { + // capture the errno from getaddrinfo + const int sys_errno = errno; #if defined(MACOSX) // If getaddrinfo fails try getifaddrs, see bug 8170910. // java_net_spi_InetAddressResolver_LookupPolicy_IPV4_FIRST and no ordering is ok @@ -122,7 +124,7 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, } #endif // report error - NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error); + NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error, sys_errno); goto cleanupAndReturn; } else { int i = 0; diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c index 8dce4f9cc6b..e0963c8dc3e 100644 --- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -231,6 +231,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, error == EAI_SYSTEM && errno == EINTR); if (error) { + // capture the errno from getaddrinfo + const int sys_errno = errno; #if defined(MACOSX) // if getaddrinfo fails try getifaddrs ret = lookupIfLocalhost(env, hostname, JNI_TRUE, characteristics); @@ -239,7 +241,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, } #endif // report error - NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error); + NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error, sys_errno); goto cleanupAndReturn; } else { int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0, diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 48cc1a7bb02..f7b690f1032 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -178,13 +178,21 @@ jint reuseport_supported(int ipv6_available) void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, - int gai_error) + int gai_error, + int sys_errno) { int size; char *buf; + const char *sys_errno_string = NULL; const char *error_string = gai_strerror(gai_error); - if (error_string == NULL) + if (error_string == NULL) { error_string = "unknown error"; + } + if (gai_error == EAI_SYSTEM) { + // EAI_SYSTEM implies that the actual error is stored in the system errno. + // Here we get the string representation of that errno. + sys_errno_string = strerror(sys_errno); + } int enhancedExceptions = getEnhancedExceptionsAllowed(env); if (enhancedExceptions == ENH_INIT_ERROR && (*env)->ExceptionCheck(env)) { return; @@ -195,16 +203,33 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, } else { size = 0; } - size += strlen(error_string) + 3; - + if (sys_errno_string == NULL) { + // the 3 is for the additional 3 characters - colon, space and + // the NULL termination character, that we will include in the + // message of the Exception that we construct + size += strlen(error_string) + 3; + } else { + // the 5 is for the additional 5 characters - 2 colons, 2 spaces and + // the NULL termination character, that we will include in the + // message of the Exception that we construct + size += strlen(error_string) + strlen(sys_errno_string) + 5; + } buf = (char *) malloc(size); if (buf) { jstring s; int n; if (enhancedExceptions == ENH_ENABLED) { - n = snprintf(buf, size, "%s: %s", hostname, error_string); + if (sys_errno_string == NULL) { + n = snprintf(buf, size, "%s: %s", hostname, error_string); + } else { + n = snprintf(buf, size, "%s: %s: %s", hostname, error_string, sys_errno_string); + } } else { - n = snprintf(buf, size, " %s", error_string); + if (sys_errno_string == NULL) { + n = snprintf(buf, size, " %s", error_string); + } else { + n = snprintf(buf, size, " %s: %s", error_string, sys_errno_string); + } } if (n >= 0) { s = JNU_NewStringPlatform(env, buf); diff --git a/src/java.base/unix/native/libnet/net_util_md.h b/src/java.base/unix/native/libnet/net_util_md.h index dca6e97755a..639cf00515f 100644 --- a/src/java.base/unix/native/libnet/net_util_md.h +++ b/src/java.base/unix/native/libnet/net_util_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,8 @@ typedef union { */ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, - int gai_error); + int gai_error, + int sys_errno); void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, const char *defaultDetail);