4

I'm working through some compile errors when building OpenSSL with no-asm -ansi. I'm catching the error:

$ ./config no-asm -ansi
...
$ make
...
gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC
-DOPENSSLDIR="\"/usr/local/ssl\"" -DENGINESDIR="\"/usr/local/lib/engines\"" -Wall -O3
-pthread -m64 -DL_ENDIAN  -ansi -fPIC -Iinclude -I. -Icrypto/include -MMD -MF
crypto/bio/bss_dgram.d.tmp -MT crypto/bio/bss_dgram.o -c -o crypto/bio/bss_dgram.o
crypto/bio/bss_dgram.c
In file included from /usr/include/netdb.h:27:0,
                 from ./e_os.h:443,
                 from crypto/bio/bio_lcl.h:2,
                 from crypto/bio/bss_dgram.c:62:
crypto/bio/bss_dgram.c: In function ‘dgram_get_mtu_overhead’:
crypto/bio/bss_dgram.c:433:20: error: ‘const struct in6_addr’ has no member named ‘s6_addr32’
                 && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
                    ^

I found the struct in /usr/include/linux/in6.h:

#if __UAPI_DEF_IN6_ADDR
struct in6_addr {
    union {
        __u8        u6_addr8[16];
#if __UAPI_DEF_IN6_ADDR_ALT
        __be16      u6_addr16[8];
        __be32      u6_addr32[4];
#endif
    } in6_u;
#define s6_addr         in6_u.u6_addr8
#if __UAPI_DEF_IN6_ADDR_ALT
#define s6_addr16       in6_u.u6_addr16
#define s6_addr32       in6_u.u6_addr32
#endif
};
#endif /* __UAPI_DEF_IN6_ADDR */

I don't recall needing to define __UAPI_DEF_IN6_ADDR_ALT in the past. Searching for it reveals the following from the kernel's libc-compat.h, line 95 or so (if I am parsing it correctly):

#define __UAPI_DEF_IN6_ADDR             1
/* We unconditionally define the in6_addr macros and glibc must coordinate. */
#define __UAPI_DEF_IN6_ADDR_ALT         1
#define __UAPI_DEF_SOCKADDR_IN6         1
#define __UAPI_DEF_IPV6_MREQ            1
#define __UAPI_DEF_IPPROTO_V6           1
#define __UAPI_DEF_IPV6_OPTIONS         1
#define __UAPI_DEF_IN6_PKTINFO          1
#define __UAPI_DEF_IP6_MTUINFO          1

How should I proceed to get the alternate symbols defined?


The system is Ubuntu 14.04 (x86_64):

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.4 LTS
Release:    14.04
Codename:   trusty

GCC is:

$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
jww
  • 97,681
  • 90
  • 411
  • 885
  • Have you considered filing an issue against OpenSSL? If the build configuration program runs without error then you should be able to rely on the build to succeed, so this certainly seems to be a *bona fide* bug. Not only is it the right thing to do, but commentary on the ticket may yield a workaround or fix. – John Bollinger Mar 25 '16 at 13:01
  • The report was filed at [Issue #4480: Ubuntu 14 (x86_64): Compile errors and warnings when using "no-asm -ansi"](https://rt.openssl.org/Ticket/Display.html?id=4480&user=guest&pass=guest). I'm actually closer to the guy working the bug at the moment. – jww Mar 25 '16 at 13:06

1 Answers1

1

This turned out to be interesting... The short of it is I needed to add both -ansi and -D_DEFAULT_SOURCE=1. However, -D_DEFAULT_SOURCE=1 kind of undoes what -ansi is trying to accomplish so it needs to be contained.

First, /usr/include/linux/in6.h was the wrong header. I found it through a grep for struct in6_addr, and not tracing includes like needed to be done.

Next... -D_DEFAULT_SOURCE=1 indirectly came from /usr/include/netinet/in.h:

#ifndef __USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
  {
    union
      {
    uint8_t __u6_addr8[16];
#ifdef __USE_MISC
    uint16_t __u6_addr16[8];
    uint32_t __u6_addr32[4];
#endif
      } __in6_u;
#define s6_addr         __in6_u.__u6_addr8
#ifdef __USE_MISC
# define s6_addr16      __in6_u.__u6_addr16
# define s6_addr32      __in6_u.__u6_addr32
#endif
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

Manually enabling __USE_MISC did not work. Tracing things for __USE_MISC in /usr/include/features.h:

/*
...
   __USE_MISC       Define things from 4.3BSD or System V Unix.
...
*/

#undef __USE_MISC
...

#if defined _DEFAULT_SOURCE
# define __USE_MISC 1
#endif

And finally, from a comment in /usr/include/features.h:

_DEFAULT_SOURCE The default set of features (taking precedence over __STRICT_ANSI__).

Though _DEFAULT_SOURCE=1 diverges from -ansi, the impact can be limited to the one source file that's affected by IN6_IS_ADDR_V4MAPPED. That is, in for the C source file crypto/bio/bss_dgram.c:

/* OpenSSL copyright ... */

#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
#endif

#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
...

Fiddling with __USE_KERNEL_IPV6_DEFS made things even worse. I believe it enabled /usr/include/linux/in6.h, which had similar (but completely different) member names than <netinet/in.h>.

jww
  • 97,681
  • 90
  • 411
  • 885