Package: dhcp-client
Version: 2.0pl5-19.3
Severity: important

In common/packet.c in rotine decode_udp_ip_header there is an pointer
set without looking for alignment:
  ip = (struct ip *)(buf + bufix);
Later a field is copied to another place:
  memcpy (&from -> sin_addr, &ip -> ip_src, 4);
This seems to be optimized to a direct copy of an integer
(which I think is legal, as this pointer has to be aligned to
 be accessed to gcc may assume it also if for memcpy)

When I run dhclient on this UltraSparc 2 I unsuprisingly get a bus error
at this position (it's more suprising that it runs that long and does
not receives signals on all architectures but i386 all the time)

The attached patch fixes this problem for me. Though I suggest to let
someone experienced with writing code for processors with alignment
retraints take a look into it, as similar "tricks" seem to be used at
other places, too.

Bernhard R. Link

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: sparc (sparc64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.8-2-sparc64
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)

Versions of packages dhcp-client depends on:
ii  libc6                         2.3.5-8    GNU C Library: Shared libraries an
Versions of other related packages:
ii  gcc                           4.0.2-1    The GNU C compiler

diff -r -u dhcp-2.0pl5/common/packet.c dhcp.new/common/packet.c
--- dhcp-2.0pl5/common/packet.c 1999-06-10 02:58:16.000000000 +0200
+++ dhcp.new/common/packet.c    2005-12-02 20:20:17.380854320 +0100
@@ -229,8 +229,11 @@
   static int udp_packets_length_checked;
   static int udp_packets_length_overflow;
   int len;
+  struct ip ip_copy;
 
-  ip = (struct ip *)(buf + bufix);
+  ip = &ip_copy;
+  memcpy(ip,buf+bufix,sizeof(struct ip));
+  
   udp = (struct udphdr *)(buf + bufix + ip_len);
 
 #ifdef USERLAND_FILTER

diff -r -u dhcp-2.0pl5/common/packet.c dhcp.new/common/packet.c
--- dhcp-2.0pl5/common/packet.c 1999-06-10 02:58:16.000000000 +0200
+++ dhcp.new/common/packet.c    2005-12-02 20:20:17.380854320 +0100
@@ -229,8 +229,11 @@
   static int udp_packets_length_checked;
   static int udp_packets_length_overflow;
   int len;
+  struct ip ip_copy;
 
-  ip = (struct ip *)(buf + bufix);
+  ip = &ip_copy;
+  memcpy(ip,buf+bufix,sizeof(struct ip));
+  
   udp = (struct udphdr *)(buf + bufix + ip_len);
 
 #ifdef USERLAND_FILTER

Reply via email to