Eric J. Bowersox wrote:
> I'm not sure why this happens, but the hash_lan function in ipmi_lan.c,
> when compiled in 64-bit mode, sometimes returns negative numbers, which
> results in a segfault inside the library.  I suspect the games it's
> playing with pointer math aren't exactly 64-bit clean.  Adding an
> operation to mask the index value to 31 bits after the shift and before
> the modulo operation clears this up.  I doubt it will seriously affect
> the output of the hash function, since the mask operation is masking off
> bits that "should" be removed by the modulo operation anyway.
>
> This problem has existed at least as far back as OpenIPMI 2.0.10, where
> I first noticed it.  When we recently upgraded the version of OpenIPMI
> we use to 2.0.14, this problem reared its ugly head again.  Hopefully, I
> can get this fix in the mainline code and we'll never have to worry
> about it again.
>
> diff -Naur OpenIPMI-2.0.14-ORIGINAL/lib/ipmi_lan.c
> OpenIPMI-2.0.14/lib/ipmi_lan.c
> --- OpenIPMI-2.0.14-ORIGINAL/lib/ipmi_lan.c     2007-10-16
> 11:46:15.000000000 -0600
> +++ OpenIPMI-2.0.14/lib/ipmi_lan.c      2008-11-17 10:48:51.000000000
> -0700
> @@ -1352,6 +1352,8 @@
>
>      idx = (((unsigned long) ipmi)
>            >> (sizeof(unsigned long) >> LAN_HASH_SHIFT));
> +    /* sometimes 64-bit pointer math gets in the way, mask to 31 bits
> */
> +    idx &= 0x7FFFFFFF;
>      idx %= LAN_HASH_SIZE;
>      return idx;
>  }
>   
The following change is already checked in to fix that problem (and 
another dealing with incorrect hashing).  Thanks for the report and 
patch, though.

-corey

Index: lib/ipmi_lan.c
===================================================================
RCS file: /cvsroot/openipmi/OpenIPMI/lib/ipmi_lan.c,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -r1.116 -r1.117
--- lib/ipmi_lan.c    11 Apr 2008 05:26:04 -0000    1.116
+++ lib/ipmi_lan.c    7 Nov 2008 15:20:29 -0000    1.117
@@ -1349,13 +1349,13 @@
 static lan_link_t lan_list[LAN_HASH_SIZE];
 static lan_link_t lan_ip_list[LAN_HASH_SIZE];
 
-static int
+static unsigned int
 hash_lan(const ipmi_con_t *ipmi)
 {
-    int idx;
+    unsigned int idx;
 
     idx = (((unsigned long) ipmi)
-       >> (sizeof(unsigned long) >> LAN_HASH_SHIFT));
+       >> (sizeof(unsigned long) + LAN_HASH_SHIFT));
     idx %= LAN_HASH_SIZE;
     return idx;
 }
@@ -1392,7 +1392,7 @@
 static void
 lan_add_con(lan_data_t *lan)
 {
-    int          idx;
+    unsigned int idx;
     lan_link_t   *head;
     unsigned int i;
 
@@ -1441,8 +1441,8 @@
 static lan_data_t *
 lan_find_con(ipmi_con_t *ipmi)
 {
-    int        idx;
-    lan_link_t *l;
+    unsigned int idx;
+    lan_link_t   *l;
 
     ipmi_lock(lan_list_lock);
     idx = hash_lan(ipmi);
@@ -5292,9 +5292,9 @@
 static lan_data_t *
 find_matching_lan(lan_conn_parms_t *cparm)
 {
-    lan_link_t *l;
-    lan_data_t *lan;
-    int        idx;
+    lan_link_t   *l;
+    lan_data_t   *lan;
+    unsigned int idx;
 
     /* Look in the first IP addresses list. */
     idx = hash_lan_addr(&cparm->ip_addr[0].s_ipsock.s_addr);
@@ -5807,7 +5807,7 @@
     lan_link_t   *l;
     lan_data_t   *lan;
     unsigned int i;
-    int          idx;
+    unsigned int idx;
     lan_do_evt_t *found = NULL;
     lan_do_evt_t *next = NULL;
 



-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to