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

Re: [PATCH v2 3/4] parse_commit(): handle broken whitespace-only timestamp

From
Jeff King <peff@peff.net>
Date
Apr 26, 2023, 11:36 UTC
Message-ID
<20230426113658.GC130148@coredump.intra.peff.net>
In-Reply-To
<xmqqttx43q08.fsf@gitster.g>
On Tue, Apr 25, 2023 at 09:06:47AM -0700, Junio C Hamano wrote:
Show 17 quoted lines
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
> > This probably doesn't matter in practice but we define our own
> > isspace() that does not treat '\v' and '\f' as whitespace. However
> > parse_timestamp() (which is just strtoumax()) uses the standard
> > library's isspace() which does treat those characters as whitespace
> > and is locale dependent. This means we can potentially stop at a
> > character that parse_timestamp() treats as whitespace and if there are
> > no digits after it we'll still walk past the end of the line. Using
> > Rene's suggestion of testing the character with isdigit() would fix
> > that. It would also avoid parsing negative timestamps as positive
> > numbers and reject any timestamps that begin with a locale dependent
> > digit.
> 
> A very interesting observation.  I wonder if a curious person can
> craft a malformed timestamp with "hash-object --literally" to do
> more than DoS themselves?

I think the answer is no, because the worst case is that they read to the trailing NUL that we stick after any object content we read into memory. So we'd mis-parse:

  committer name <email> \v\n
  123456 in the subject line

to read "123456" as the commit timestamp (so basically the same bug my patch was trying to fix). But we'd never read out-of-bounds memory. Still, it does not give me warm fuzzies, and I think is worth fixing.

Show 5 quoted lines
> We are not going to put anything other than [ 0-9+-] after the '>'
> we scan for, and making sure '>' is followed by SP and then [0-9]
> would be sufficient to ensure strtoumax() to stop before the '\n'
> but does not ensure that the "signal a bad timestamp with 0"
> happens.  Perhaps that would be sufficient.  I dunno.

Any single non-whitespace character at all would be sufficient to avoid the problem. And that's what the current iteration of the patch is trying to do. It's just that our definition of "whitespace" has to agree with strtoumax()'s for it to work. And as Phillip notes, that may even include locale dependent characters. So I don't think we want to get into trying to match them all (i.e., a "allow known" strategy).

Instead, we should go back to what the original iteration of the series was doing, and make sure there is at least one digit (i.e., a "forbid unknown" strategy). Assuming that there is no locale where ascii "1" is considered whitespace. ;)

Note that will exclude a few cases that we do allow now, like:
  committer name <email> \v123456 +0000\n

Right now that parses as "123456", but we'd reject it as "0" after such a patch.

The alternative is to check _all_ of the characters between ">" and the newline and make sure there is some digit somewhere, which would be sufficient to prevent strtoumax() from walking past the newline.

I guess it's not even any more expensive in the normal case (since the very first non-whitespace entry should be a digit!). I'm not sure it's worth caring about too much either way. Garbage making it into name/email is an easy mistake to make (for users and implementations). Putting whitespace control codes into your timestamp is not, and marking them as "0" is an OK outcome.

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 26 of 46 in “Weird behavior of 'git log --before' or 'git log --date-order': Commits from 2011 are treated to be before 1980”
  1. Thomas BockApr 14, 2023
  2. Jeff KingApr 15, 2023
  3. Jeff KingApr 15, 2023
  4. Kristoffer HaugsbakkApr 15, 2023
  5. Jeff KingApr 17, 2023
  6. Kristoffer HaugsbakkApr 17, 2023
  7. Jeff KingApr 17, 2023
  8. Kristoffer HaugsbakkApr 27, 2023
  9. Junio C HamanoApr 17, 2023
  10. Jeff KingApr 18, 2023
  11. Derrick StoleeApr 18, 2023
  12. Thomas BockApr 21, 2023
  13. 0/3 fixing some parse_commit() timestamp corner casesJeff King, Apr 22, 2023
  14. 1/3 t4212: avoid putting git on left-hand side of pipeJeff King, Apr 22, 2023
  15. 2/3 parse_commit(): parse timestamp from end of lineJeff King, Apr 22, 2023
  16. Junio C HamanoApr 24, 2023
  17. Jeff KingApr 25, 2023
  18. Junio C HamanoApr 24, 2023
  19. 0/3 fixing some parse_commit() timestamp corner casesJeff King, Apr 25, 2023
  20. Jeff KingApr 25, 2023
  21. 1/4 t4212: avoid putting git on left-hand side of pipeJeff King, Apr 25, 2023
  22. 2/4 parse_commit(): parse timestamp from end of lineJeff King, Apr 25, 2023
  23. 3/4 parse_commit(): handle broken whitespace-only timestampJeff King, Apr 25, 2023
  24. Phillip WoodApr 25, 2023
  25. Junio C HamanoApr 25, 2023
  26. Jeff KingApr 26, 2023
  27. Junio C HamanoApr 26, 2023
  28. 0/4 fixing some parse_commit() timestamp corner casesJeff King, Apr 27, 2023
  29. 1/4 t4212: avoid putting git on left-hand side of pipeJeff King, Apr 27, 2023
  30. 2/4 parse_commit(): parse timestamp from end of lineJeff King, Apr 27, 2023
  31. 3/4 parse_commit(): handle broken whitespace-only timestampJeff King, Apr 27, 2023
  32. Phillip WoodApr 27, 2023
  33. Phillip WoodApr 27, 2023
  34. Jeff KingApr 27, 2023
  35. Junio C HamanoApr 27, 2023
  36. Jeff KingApr 27, 2023
  37. Junio C HamanoApr 27, 2023
  38. Jeff KingApr 27, 2023
  39. 4/4 parse_commit(): describe more date-parsing failure modesJeff King, Apr 27, 2023
  40. Jeff KingApr 27, 2023
  41. Junio C HamanoApr 27, 2023
  42. Phillip WoodApr 26, 2023
  43. Andreas SchwabApr 26, 2023
  44. Phillip WoodApr 26, 2023
  45. 4/4 parse_commit(): describe more date-parsing failure modesJeff King, Apr 25, 2023
  46. Jeff KingApr 22, 2023

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.