git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git-diff-tree rename detection bug

From
Paul Mackerras <paulus@samba.org>
Date
Sep 15, 2005, 04:52 UTC
Message-ID
<17192.65054.520959.454610@cargo.ozlabs.ibm.com>
In-Reply-To
<Pine.LNX.4.58.0509142032300.26803@g5.osdl.org>
Linus Torvalds writes:
Show 9 quoted lines
> It works, but it does end up complaining about things like 
> 
> 	==23756== Invalid read of size 4
> 	==23756==    at 0x25A38990: strlen (in /lib/libc-2.3.5.so)
> 	..
> 	==23756==  Address 0x25B86754 is 3 bytes after a block of size 17 alloc'd
> 
> which seems to be just strlen prefetching the next word or something like 
> that. 

The strlen() in glibc for ppc is unbearably clever hand-coded assembly, which loads up 8 bytes at a time (once it has the address 8-byte aligned), and does various ANDs and ORs and ADDs and conditional branches. If some of the 8 bytes aren't defined, it will in many cases branch one way or the other based on the undefined bytes, but end up computing the same result on either branch.

Valgrind is right in that strlen is loading up some bytes that are past the end of a malloc'd block. In fact those bytes don't end up affecting the result, and in fact the load couldn't cause a segfault, but it's not surprising that Valgrind can't see that, since the value of the extra bytes can actually affect whether a conditional branch is taken or not, but we end up with the same result either way.

Valgrind sets LD_PRELOAD so that you get a simple Valgrind-supplied set of string functions, including strlen, from vgpreload_memcheck.so rather than the fancy glibc ones. However, that doesn't seem to catch the calls to strlen from inside glibc - the call from vfprintf is a direct branch rather than going through the PLT, for instance.

I could add a suppression to suppress all errors in strlen, but that would mean you would miss real errors, where the string is not null-terminated within the malloc'd block, and strlen runs off the end.

I wish I had a good answer for this problem, but I don't. Maybe we need a debugging version of glibc that doesn't use the fancy bit-fiddling algorithms in the string functions.

(Just for interest: here are the comments from strlen.S:
   1) Given a word 'x', we can test to see if it contains any 0 bytes
      by subtracting 0x01010101, and seeing if any of the high bits of each
      byte changed from 0 to 1. This works because the least significant
      0 byte must have had no incoming carry (otherwise it's not the least
      significant), so it is 0x00 - 0x01 == 0xff. For all other
      byte values, either they have the high bit set initially, or when
      1 is subtracted you get a value in the range 0x00-0x7f, none of which
      have their high bit set. The expression here is
      (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
      there were no 0x00 bytes in the word.
   2) Given a word 'x', we can test to see _which_ byte was zero by
      calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
      This produces 0x80 in each byte that was zero, and 0x00 in all
      the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
      byte, and the '| x' part ensures that bytes with the high bit set
      produce 0x00. The addition will carry into the high bit of each byte
      iff that byte had one of its low 7 bits set. We can then just see
      which was the most significant bit set and divide by 8 to find how
      many to add to the index.
      This is from the book 'The PowerPC Compiler Writer's Guide',
      by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
)
Paul.
Previous: Linus TorvaldsNext: Junio C Hamano
Message 9 of 23 in “git-diff-tree rename detection bug”
  1. Wayne ScottSep 14, 2005
  2. Junio C HamanoSep 14, 2005
  3. Wayne ScottSep 14, 2005
  4. Linus TorvaldsSep 14, 2005
  5. Fix alloc_filespec() initializationLinus Torvalds, Sep 14, 2005
  6. Paul MackerrasSep 15, 2005
  7. Paul MackerrasSep 15, 2005
  8. Linus TorvaldsSep 15, 2005
  9. Paul MackerrasSep 15, 2005
  10. Junio C HamanoSep 15, 2005
  11. Josef WeidendorferSep 15, 2005
  12. Paul MackerrasSep 20, 2005
  13. Linus TorvaldsSep 15, 2005
  14. Junio C HamanoSep 16, 2005
  15. H. Peter AnvinSep 15, 2005
  16. Junio C HamanoSep 15, 2005
  17. Linus TorvaldsSep 15, 2005
  18. Matthias UrlichsSep 16, 2005
  19. Nicolas PitreSep 15, 2005
  20. Junio C HamanoSep 14, 2005
  21. Junio C HamanoSep 14, 2005
  22. Linus TorvaldsSep 14, 2005
  23. Junio C HamanoSep 14, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.