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;
|
||||
|
||||
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.BeforeAll;
|
||||
|
||||
@ -53,4 +57,25 @@ public class LinuxSocketTest {
|
||||
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);
|
||||
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);
|
||||
|
||||
if (unlink((const char*) socket_path) == -1 && errno != ENOENT) {
|
||||
if (unlink((const char*) addr.sun_path) == -1 && errno != ENOENT) {
|
||||
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);
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user