Ticket #9 (closed defect: fixed)
avahi-core socket.c's input cmsghdr msg->msg_control buffers are misaligned on ia64 linux
| Reported by: | Jason Vas Dias <jvdias@…> | Owned by: | lennart |
|---|---|---|---|
| Milestone: | Component: | component1 | |
| Keywords: | ia64 unaligned socket | Cc: |
Description
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:
Please consider fixing this problem in the next release - thanks!
Jason Vas Dias<jvdias@…>, 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_
