Class CmsgHdr


  • final class CmsgHdr
    extends java.lang.Object
    
     struct cmsghdr {
         socklen_t cmsg_len;    // data byte count, including header
         int cmsg_level;  //originating protocol
         int cmsg_type;   // protocol-specific type
         // followed by unsigned char cmsg_data[];
     };
     
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private CmsgHdr()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      private static void closeQuietly​(int fd, java.lang.Throwable error)  
      (package private) static int numFds​(long cmsgLen, int cmsgLenForFd, int sizeofInt)
      Computes how many file descriptors a SCM_RIGHTS cmsg of the given cmsgLen carries, given cmsgLenForFd, the platform's CMSG_LEN(sizeof(int)) (the length of a cmsg holding exactly one fd), and sizeofInt, the platform's sizeof(int).
      (package private) static int numFdsToClose​(int nfds, boolean truncated)
      Returns the number of delivered fds that must be closed because the message is rejected: all of them if the message was truncated (and at least one fd was delivered) or if more than one fd was delivered.
      (package private) static int readScmRights​(java.nio.ByteBuffer cmsghdr, int cmsgHdrDataOffset, boolean truncated)
      Reads the file descriptor delivered via a SCM_RIGHTS control message.
      (package private) static void write​(java.nio.ByteBuffer cmsghdr, int cmsgHdrDataOffset, int cmsgLen, int cmsgLevel, int cmsgType, short segmentSize)  
      (package private) static void writeScmRights​(java.nio.ByteBuffer cmsghdr, int cmsgHdrDataOffset, int fd)  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • CmsgHdr

        private CmsgHdr()
    • Method Detail

      • write

        static void write​(java.nio.ByteBuffer cmsghdr,
                          int cmsgHdrDataOffset,
                          int cmsgLen,
                          int cmsgLevel,
                          int cmsgType,
                          short segmentSize)
      • writeScmRights

        static void writeScmRights​(java.nio.ByteBuffer cmsghdr,
                                   int cmsgHdrDataOffset,
                                   int fd)
      • readScmRights

        static int readScmRights​(java.nio.ByteBuffer cmsghdr,
                                 int cmsgHdrDataOffset,
                                 boolean truncated)
                          throws java.io.IOException
        Reads the file descriptor delivered via a SCM_RIGHTS control message.

        A malicious (or buggy) peer can pack more than one file descriptor into the single control message that Netty only ever sizes for one fd. On 64-bit Linux CMSG_SPACE(sizeof(int)) and CMSG_SPACE(2 * sizeof(int)) are both 24 bytes (due to 8 byte alignment), so the kernel does not report MSG_CTRUNC even though two fds were delivered. If that is not detected the surplus fd is never closed and leaks for the lifetime of the process (see CVE-2026-45536 for the equivalent issue that was fixed for the epoll/kqueue transports in netty_unix_socket_recvFd()).

        To guard against this we validate the cmsg level/type, compute the real number of fds from cmsg_len and, if more than one fd (or a truncated message) was received, close every fd we got and fail instead of silently returning a partial (and leaking) result.

        Throws:
        java.io.IOException - if the control message did not carry exactly one well-formed SCM_RIGHTS fd.
      • numFds

        static int numFds​(long cmsgLen,
                          int cmsgLenForFd,
                          int sizeofInt)
        Computes how many file descriptors a SCM_RIGHTS cmsg of the given cmsgLen carries, given cmsgLenForFd, the platform's CMSG_LEN(sizeof(int)) (the length of a cmsg holding exactly one fd), and sizeofInt, the platform's sizeof(int). Returns -1 if cmsgLen is smaller than one fd or not a whole number of fds (i.e. truncated or malformed).

        Pure function of primitives (no native/JNI dependency) so it can be unit tested in isolation.

      • numFdsToClose

        static int numFdsToClose​(int nfds,
                                 boolean truncated)
        Returns the number of delivered fds that must be closed because the message is rejected: all of them if the message was truncated (and at least one fd was delivered) or if more than one fd was delivered.

        Pure function of primitives so it can be unit tested in isolation.

      • closeQuietly

        private static void closeQuietly​(int fd,
                                         java.lang.Throwable error)