Throw exceptions when rule violating UDS paths been passed in. (#11663)
Motivation: Currently, Netty is silently truncating all over the limit UDS paths and ignoring the `sun_path`'s null-termination role, which hurts compatibility with other UDS clients and servers. Modifications: Adding a validation in the JNI code, if the UDS path is not satisfying the system limit or Linux spec throw a NativeIoException. Result: All UDS paths Netty can successfully bind are connectable by other programs.
This commit is contained in:
parent
59275fba52
commit
3152ec76db
@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.channel.epoll;
|
package io.netty.channel.epoll;
|
||||||
|
|
||||||
|
import io.netty.channel.unix.DomainSocketAddress;
|
||||||
|
import io.netty.channel.unix.Errors.NativeIoException;
|
||||||
|
import io.netty.channel.unix.Socket;
|
||||||
|
import java.util.UUID;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
|
||||||
@ -53,4 +57,25 @@ public class LinuxSocketTest {
|
|||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnixDomainSocketTooLongPathFails() throws IOException {
|
||||||
|
// Most systems has a limit for UDS path of 108, 255 is generally too long.
|
||||||
|
StringBuilder socketPath = new StringBuilder("/tmp/");
|
||||||
|
while (socketPath.length() < 255) {
|
||||||
|
socketPath.append(UUID.randomUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
final DomainSocketAddress domainSocketAddress = new DomainSocketAddress(
|
||||||
|
socketPath.toString());
|
||||||
|
final Socket socket = Socket.newSocketDomain();
|
||||||
|
try {
|
||||||
|
Exception exception = assertThrows(NativeIoException.class, () -> {
|
||||||
|
socket.bind(domainSocketAddress);
|
||||||
|
});
|
||||||
|
Assertions.assertTrue(exception.getMessage().contains("too long"));
|
||||||
|
} finally {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,12 +764,13 @@ static jint netty_unix_socket_bindDomainSocket(JNIEnv* env, jclass clazz, jint f
|
|||||||
|
|
||||||
jbyte* socket_path = (*env)->GetByteArrayElements(env, socketPath, 0);
|
jbyte* socket_path = (*env)->GetByteArrayElements(env, socketPath, 0);
|
||||||
jint socket_path_len = (*env)->GetArrayLength(env, socketPath);
|
jint socket_path_len = (*env)->GetArrayLength(env, socketPath);
|
||||||
if (socket_path_len > sizeof(addr.sun_path)) {
|
|
||||||
socket_path_len = sizeof(addr.sun_path);
|
if (socket_path_len > sizeof(addr.sun_path) || (socket_path_len == sizeof(addr.sun_path) && socket_path[socket_path_len] != '\0')) {
|
||||||
|
return -ENAMETOOLONG;
|
||||||
}
|
}
|
||||||
memcpy(addr.sun_path, socket_path, socket_path_len);
|
memcpy(addr.sun_path, socket_path, socket_path_len);
|
||||||
|
|
||||||
if (unlink((const char*) socket_path) == -1 && errno != ENOENT) {
|
if (unlink((const char*) addr.sun_path) == -1 && errno != ENOENT) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,8 +792,9 @@ static jint netty_unix_socket_connectDomainSocket(JNIEnv* env, jclass clazz, jin
|
|||||||
|
|
||||||
jbyte* socket_path = (*env)->GetByteArrayElements(env, socketPath, 0);
|
jbyte* socket_path = (*env)->GetByteArrayElements(env, socketPath, 0);
|
||||||
socket_path_len = (*env)->GetArrayLength(env, socketPath);
|
socket_path_len = (*env)->GetArrayLength(env, socketPath);
|
||||||
if (socket_path_len > sizeof(addr.sun_path)) {
|
|
||||||
socket_path_len = sizeof(addr.sun_path);
|
if (socket_path_len > sizeof(addr.sun_path) || (socket_path_len == sizeof(addr.sun_path) && socket_path[socket_path_len] != '\0')) {
|
||||||
|
return -ENAMETOOLONG;
|
||||||
}
|
}
|
||||||
memcpy(addr.sun_path, socket_path, socket_path_len);
|
memcpy(addr.sun_path, socket_path, socket_path_len);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user