Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Jul 2005 18:33:41 GMT
From:      Steve Sears <sjs@acm.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/83107: libc uuid_compare() doesn't work with large numbers
Message-ID:  <200507071833.j67IXfbl027699@www.freebsd.org>
Resent-Message-ID: <200507071840.j67IeBQx021079@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         83107
>Category:       misc
>Synopsis:       libc uuid_compare() doesn't work with large numbers
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 07 18:40:11 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Steve Sears
>Release:        5.4
>Organization:
self
>Environment:
FreeBSD sjs-linux.nane.netapp.com 5.4-STABLE FreeBSD 5.4-STABLE #19: Mon Apr 18 11:28:21 EDT 2005     root@sjs-linux.nane.netapp.com:/usr/src/sys-sjs/i386/compile/SJSKERN  i386

>Description:
      If you use uuid_compare and the uuid's are very different, an int
is too small to contain the results. For example, according to this code:

865e1a56-b9d9-11d9-ba27-0003476f2e88 < 062ac45c-b9d9-11d9-ba27-0003476f2e88

The implementation takes the results of a subtraction of the numbers
and assigns it to an int. But if the high bits remain on after the
subtraction, an int is too small and the results are negative.

The routine is located at ./src/lib/libc/uuid/uuid_compare.c

>How-To-Repeat:
      Invoke uuid_compare with the above two numbers. 

>Fix:
      Very simple fix: in uuid_compare.c, uuid_compare(), change the
local variable 'res' from int to int64_t. Remove the '(int)' cast from
the first subtraction.

Cdiff follows:

=== /u/sjs/freebsd/usr/src/lib/libc/uuid/uuid_compare.c ====
***************
*** 41,47 ****
  int32_t
  uuid_compare(uuid_t *a, uuid_t *b, uint32_t *status)
  {
!       int res;
  
        if (status != NULL)
                *status = uuid_s_ok;
--- 41,47 ----
  int32_t
  uuid_compare(uuid_t *a, uuid_t *b, uint32_t *status)
  {
!       int64_t res;
  
        if (status != NULL)
                *status = uuid_s_ok;
***************
*** 55,61 ****
                return ((uuid_is_nil(a, NULL)) ? 0 : 1);
  
        /* We have to compare the hard way. */
!       res = (int)((int64_t)a->time_low - (int64_t)b->time_low);
        if (res)
                return ((res < 0) ? -1 : 1);
        res = (int)a->time_mid - (int)b->time_mid;
--- 55,61 ----
                return ((uuid_is_nil(a, NULL)) ? 0 : 1);
  
        /* We have to compare the hard way. */
!       res = (int64_t)a->time_low - (int64_t)b->time_low;
        if (res)
                return ((res < 0) ? -1 : 1);
        res = (int)a->time_mid - (int)b->time_mid;

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507071833.j67IXfbl027699>