On ia64 linux platforms, the kernel detects and complains about mis-aligned memory
accesses, which avahi-daemon upto and including 0.6.6 suffers from:
$ avahi-daemon ...
...
avahi-daemon(28929): unaligned access to 0x60000fffffeef2c4, ip=0x20000000000b20c1
avahi-daemon(28929): unaligned access to 0x60000fffffeef2e4, ip=0x20000000000b1ec0
avahi-daemon(28929): unaligned access to 0x60000fffffeef2e4, ip=0x20000000000b2061
avahi-daemon(28929): unaligned access to 0x60000fffffeef2c4, ip=0x20000000000b20c1
Running with:
$ prctl --unaligned=signal gdb avahi-daemon
shows the fault occurs in avahi-core's socket.c's avahi_recv_dns_packet_ipv4(...),
upon the first invocation of CMSG_NEXTHDR, @line 657 .
It turns out that the 'aux' buffer on the stack, declared as :
uint8_t aux[1024];
was not on an 8-byte boundary, so the first cmsg address (0x60000fffffeef2c4) is not
properly aligned for access to a cmsghdr structure.
The following patch fixes the issue wherever it might occur in socket.c, and
prevents the messages being generated with Red Hat Fedora Core 5's avahi-0.6.6-1
package . This problem was first reported as Red Hat Bugzilla #179448:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=179448
Please consider fixing this problem in the next release - thanks!
Jason Vas Dias<jvdias@redhat.com>,
avahi package maintainer
Red Hat, Inc.
_BEGIN PATCH_
--- avahi-0.6.5/avahi-core/socket.c.bz179448 2005-11-09 13:45:51.000000000 -0500
+++ avahi-0.6.5/avahi-core/socket.c 2006-02-01 17:54:22.000000000 -0500
@@ -456,10 +456,10 @@
struct iovec io;
#ifdef IP_PKTINFO
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_pktinfo))];
+ struct cmsghdr cmsg_data[( CMSG_SPACE(sizeof(struct in_addr)) / sizeof(struct cmsghdr)) + 1];
#elif defined(IP_SENDSRCADDR)
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_addr))];
+ struct cmsghdr cmsg_data[( CMSG_SPACE(sizeof(struct in_addr)) / sizeof(struct cmsghdr)) + 1];
#endif
assert(fd >= 0);
@@ -542,7 +542,7 @@
struct msghdr msg;
struct iovec io;
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+ struct cmsghdr cmsg_data[(CMSG_SPACE(sizeof(struct in6_pktinfo))/sizeof(struct msghdr)) + 1];
assert(fd >= 0);
assert(p);
@@ -596,7 +596,7 @@
AvahiDnsPacket? *p= NULL;
struct msghdr msg;
struct iovec io;
- uint8_t aux[1024];
+ struct cmsghdr aux[1024 / sizeof(struct cmsghdr)]; /* for alignment on ia64 ! */
ssize_t l;
struct cmsghdr *cmsg;
int found_addr = 0;
@@ -726,7 +726,7 @@
AvahiDnsPacket? *p = NULL;
struct msghdr msg;
struct iovec io;
- uint8_t aux[64];
+ struct cmsghdr aux[1024 / sizeof(struct cmsghdr)];
ssize_t l;
int ms;
struct cmsghdr *cmsg;
_END PATCH_