Project

General

Profile

Bug #4931

kernel's inet_pton still botches v4 mapped and compat addresses byte order

Added by Robert Mustacchi over 5 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
Category:
kernel
Start date:
2014-06-18
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:

Description

While developing something that used ksockets and the kernel's inet_pton to fill out a struct sockaddr_in6 with a v4 mapped IPv6 address, I found that the address was being transmitted on the wire incorrectly and the address "::ffff:10.88.88.70" was being sent to 70.88.88.10. To verify that I was seeing something crazy, I wrote the following sample C program and used DTrace to verify the structure:

$ cat tmp.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>

int
main(void)
{
        int ret;
        struct sockaddr_in6 in6;
        const char *addr = "::ffff:10.88.88.70";

        bzero(&in6, sizeof (struct sockaddr_in6));
        (void) inet_pton(AF_INET6, addr, &in6.sin6_addr);
        return (0);
}
$ cat tmp.d
pid$target::inet_pton:entry
{
        self->a = args[2];
}

pid$target::inet_pton:return
/self->a/
{
        print(((userland struct sockaddr_in6 *)self->a)->sin6_addr);
}
$ gcc -lnsl tmp.c
$ dtrace -qs ./tmp.d -c ./a.out
struct in6_addr {
    union _S6_un = {
        uint32_t [4] _S6_u32 = [ 0xffff0000, 0x4658580a, 0, 0 ]
        uint8_t [16] _S6_u8 = [ 0, 0, 0xff, 0xff, 0xa, 0x58, 0x58, 0x46, 0, 0, 0, 0, 0, 0, 0, 0 ]
        uint32_t __S6_align = 0xffff0000
    }
}

However, when looking at similar code in the kernel the equivalent D script output:

  0  22498                _inet_pton:return struct in6_addr {
    union _S6_un = {
        uint32_t [4] _S6_u32 = [ 0xffff0000, 0xa585846, 0, 0 ]
        uint8_t [16] _S6_u8 = [ 0, 0, 0xff, 0xff, 0x46, 0x58, 0x58, 0xa, 0, 0, 0, 0, 0, 0, 0, 0 ]
        uint32_t __S6_align = 0xffff0000
    }
}

Note how the data is still in host order in the kernel case, but network order in the user land case.

The problem is an extension of 3105 which addressed the issue for AF_INET, but not for AF_INET6. The solution; however, is similar. In addition, we shouldn't need to create an additional compatibility wrapper, because the existing one should cover this case.

History

#1

Updated by Robert Mustacchi over 5 years ago

  • Subject changed from kernel's inet_pton still doesn't handle byte order correctly to kernel's inet_pton still botches v4 mapped and compat addresses byte order
#2

Updated by Electric Monk over 5 years ago

  • Status changed from New to Closed
  • % Done changed from 90 to 100

git commit f67144614ce47a7037765727764c6d46dd000e86

commit  f67144614ce47a7037765727764c6d46dd000e86
Author: Robert Mustacchi <rm@joyent.com>
Date:   2014-06-21T17:22:45.000Z

    4931 kernel's inet_pton still botches v4 mapped and compat addresses byte order
    Reviewed by: Dan McDonald <danmcd@omniti.com>
    Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
    Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
    Approved by: Dan McDonald <danmcd@omniti.com>

Also available in: Atom PDF