bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

findutils-4.1 `locate` bug and patch.


From: Simon Fraser
Subject: findutils-4.1 `locate` bug and patch.
Date: Sat, 25 Nov 2000 16:56:41 +0000 (GMT)

Hi,
I tickled a bug in locate on a few of our servers. The symptom report is
that locate will SEGV, seemingly at random.  Investigation reveals that
this is due to a bug in get_short which fails to deal with a signed
offset.  Since values greater than -127 are written out as a single char,
only encoded values which have an offset of less than -127 cause this bug
to appear.  

To extend the example from frcode.c: 

Encoding:
/usr/local/src
/usr/local/src/verylongpathnamewhichisnotuniqueforquitesometimehonestguvnorfoobarbazquuzwibblefredbarneyturnipwomblesplatfilenamenumber1foo
/usr/local/src/verylongpathnamewhichisnotuniqueforquitesometimehonestguvnorfoobarbazquuzwibblefredbarneyturnipwomblesplatfilenamenumber2foo
/usr/foo

Gives:
0 /usr/local/src
14 
/verylongpathnamewhichisnotuniqueforquitesometimehonestguvnorfoobarbazquuzwibblefredbarneyturnipwomblesplatfilenamenumber1foo
122 2foo
-131 foo

Reading /usr/foo from the locate database is controlled by lines 269 and
270 of locate.c:

  if (c == LOCATEDB_ESCAPE)
     count += get_short(fp);

get_short misreads the two chars as unsigned, and returns a value
appropriately, 65535 minus the intended value.  This causes count to be
incorrect, and count is used as an offset in the current path later on,
notably in getstr.  The resultant error in pointer arithmatic causes the
segmentation violation. 

This can be fixed by replacing the contents of get_short:
--
  register short x;

  x = fgetc (fp);
  return (x << 8) | (fgetc (fp) & 0xff);
--
with:
--
  char x[1];
  fread((void *)&x,2,1,fp);
  return ((x[0]<<8)|(x[1]&0xff));
--

The downside to this is that x is no longer a register variable, as it's
not possible to apply the & operator to data held in a register.  However,
it is only a single read operation instead of two, and does not have any
problems with signed values.   put_short does not need to be modified, so
the fixed version works with existing locate databases.

For reference the systems where this bug were discovered are both Sun
Sparcs, one an Ultra 5 running Solaris 2.6, the other an Ultra 60 running
Solaris 7.  Both have findutils 4.1. 

Thanks,
Simon.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]