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>