NetworkConfiguration / dhcpcd

DHCP / IPv4LL / IPv6RA / DHCPv6 client.
https://roy.marples.name/projects/dhcpcd
BSD 2-Clause "Simplified" License
348 stars 112 forks source link

Compilation error on musl using tinycc #347

Closed blmayer closed 3 months ago

blmayer commented 3 months ago

Hi I tried compiling it and an error appeared:

dhcp6.c:123: error: invalid array size

The line above is an assert on the size of a packed struct. So I'm not sure if this is a compiler issue. Also my arch is aarch64. The offending line:

https://github.com/NetworkConfiguration/dhcpcd/blob/5ac1235b99d33085d0574ef81b95ceafcf79db34/src/dhcp6.c#L123

There is a fixme on the struct definition.

There are some warnings before the error:

In file included from if-linux.c:45:
/include/linux/sockios.h:42: warning: SIOCGSTAMP redefined
In file included from if-linux.c:45:
/include/linux/sockios.h:43: warning: SIOCGSTAMPNS redefined
In file included from if-linux.c:60:
In file included from /include/linux/if_arp.h:27:
In file included from /include/linux/netdevice.h:29:
/include/linux/if.h:135: warning: IFF_VOLATILE redefined
...
bpf.c:709: warning: #warning A compromised PF_PACKET socket can be used as a raw socket
...
dhcp6.c:123: error: invalid array size

Thanks.

gadall commented 3 months ago

@blmayer On amd64, running Debian, tcc 0.9.27+git20200814.62c30a4a-1, the following program compiles with no warning or error.

The definition of in6_addr is copied from musl's include/netinet/in.h

Could you perhaps try to compile this on your machine?

#include <stdint.h>

#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
# ifndef __packed
#  define __packed __attribute__((__packed__))
# endif
# ifndef __unused
#  define __unused __attribute__((__unused__))
# endif
#else
# ifndef __packed
#  define __packed
# endif
# ifndef __unused
#  define __unused
# endif
#endif

#ifndef __CTASSERT
# ifdef __COUNTER__
#   define  __CTASSERT(x)       __CTASSERT0(x, __ctassert, __COUNTER__)
# else
#  define   __CTASSERT(x)       __CTASSERT99(x, __INCLUDE_LEVEL__, __LINE__)
#  define   __CTASSERT99(x, a, b)   __CTASSERT0(x, __CONCAT(__ctassert,a), \
                           __CONCAT(_,b))
# endif
# define    __CTASSERT0(x, y, z)    __CTASSERT1(x, y, z)
# define    __CTASSERT1(x, y, z)    typedef char y ## z[/*CONSTCOND*/(x) ? 1 : -1] __unused
#endif

struct in6_addr {
    union {
        uint8_t __s6_addr[16];
        uint16_t __s6_addr16[8];
        uint32_t __s6_addr32[4];
    } __in6_union;
};
struct dhcp6_ia_addr {
    struct in6_addr addr;
    uint32_t pltime;
    uint32_t vltime;
};
__CTASSERT(sizeof(struct dhcp6_ia_addr) == 16 + 8);

int main() {
}
gadall commented 3 months ago

@blmayer Oh, I forgot about my raspberry pis ;-) it compiles on them too, Debian on aarch64

rsmarples commented 3 months ago

@blmayer tinycc does not support packed structures. https://lists.nongnu.org/archive/html/tinycc-devel/2005-02/msg00004.html

The redefinition warnings are an issue with your headers. I don't see such issues on Alpine which uses musl and gcc/clang.

rsmarples commented 3 months ago

@blmayer can you test that branch please? It should fix it for you.

blmayer commented 3 months ago

Hi, thanks for the responses. First of all I was able to compile by just removing line 123, so I got unblocked.

Second, I'll try the snippet, and yes it is a compiler's limitation. As you guys already figured out.

And last, I'll try this new branch and report here.

Thanks again

rsmarples commented 3 months ago

Hi, thanks for the responses. First of all I was able to compile by just removing line 123, so I got unblocked.

Sure it will compile, but it won't work because the struct you are using is padded for alignment. If you use DHCPv6 Prefix Delegation it will crash, which the assertion was guarding against. My patch above should fix it, but needs testing.

blmayer commented 3 months ago

@rsmarples The nopacked branch compiled without errors, only the same warnings appeared. I ran dhcpcd and it worked! I have internet now on my Rpi ;-D.

I don't think I'm using IPv6, so maybe I'm not testing the right parts.

Also @gadall your snippet compiled without errors or warnings.

Thanks everyone.