From: darcy <acednes@xxxxxxxxx> Overriding the date of a commit to be close to "1970-01-01 00:00:00" with a large enough timezone for the equivelant GMT time to be before the epoch is considered valid by `parse_date_basic`. This leads to an integer underflow in the commit timestamp, which is not caught by `git-commit`, but will cause other services to fail, such as `git-fsck`, which reports "badDateOverflow: invalid author/committer line - date causes integer overflow". Instead check the timezone offset and fail if the resulting time comes before the epoch, "1970-01-01T00:00:00Z", when parsing. Signed-off-by: Darcy Burke <acednes@xxxxxxxxx> --- fix: prevent date underflow when using positive timezone offset cc: Patrick Steinhardt ps@xxxxxx cc: Phillip Wood phillip.wood123@xxxxxxxxx Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1726%2Fdxrcy%2Fmaster-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1726/dxrcy/master-v2 Pull-Request: https://github.com/git/git/pull/1726 Range-diff vs v1: 1: 4542d984aab ! 1: db508b2f533 fix: prevent date underflow when using positive timezone offset @@ Metadata Author: darcy <acednes@xxxxxxxxx> ## Commit message ## - fix: prevent date underflow when using positive timezone offset + date: detect underflow when parsing dates with positive timezone offset - Overriding the date of a commit to be `1970-01-01` with a large enough - timezone for the equivalent GMT time to before 1970 is no longer - accepted. + Overriding the date of a commit to be close to "1970-01-01 00:00:00" + with a large enough timezone for the equivelant GMT time to be before + the epoch is considered valid by `parse_date_basic`. - Example: `GIT_COMMITTER_DATE='1970-01-01T00:00:00+10' git commit` would - previously be accepted, only to unexpectedly fail in other parts of the - code, such as `git push`. The timestamp is now checked against postitive - timezone values. + This leads to an integer underflow in the commit timestamp, which is not + caught by `git-commit`, but will cause other services to fail, such as + `git-fsck`, which reports "badDateOverflow: invalid author/committer + line - date causes integer overflow". - Signed-off-by: darcy <acednes@xxxxxxxxx> + Instead check the timezone offset and fail if the resulting time comes + before the epoch, "1970-01-01T00:00:00Z", when parsing. + + Signed-off-by: Darcy Burke <acednes@xxxxxxxxx> ## date.c ## -@@ date.c: int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset) - match = match_alpha(date, &tm, offset); - else if (isdigit(c)) - match = match_digit(date, &tm, offset, &tm_gmt); -- else if ((c == '-' || c == '+') && isdigit(date[1])) -+ else if ((c == '-' || c == '+') && isdigit(date[1]) && tm.tm_hour != -1) - match = match_tz(date, offset); - - if (!match) { @@ date.c: int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset) } } - if (!tm_gmt) + if (!tm_gmt) { -+ if (*offset > 0 && *offset * 60 > *timestamp) { ++ if (*offset > 0 && *offset * 60 > *timestamp) + return -1; -+ } *timestamp -= *offset * 60; + } + return 0; /* success */ } + + ## t/t0006-date.sh ## +@@ t/t0006-date.sh: check_parse '2008-02-14 20:30:45 -:30' '2008-02-14 20:30:45 +0000' + check_parse '2008-02-14 20:30:45 -05:00' '2008-02-14 20:30:45 -0500' + check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5 + check_parse 'Thu, 7 Apr 2005 15:14:13 -0700' '2005-04-07 15:14:13 -0700' ++check_parse '1970-01-01 00:00:00' '1970-01-01 00:00:00 +0000' ++check_parse '1970-01-01 00:00:00 +00' '1970-01-01 00:00:00 +0000' ++check_parse '1970-01-01 00:00:00 Z' '1970-01-01 00:00:00 +0000' ++check_parse '1970-01-01 00:00:00 -01' '1970-01-01 00:00:00 -0100' ++check_parse '1970-01-01 00:00:00 +01' bad ++check_parse '1970-01-01 00:00:00 +11' bad ++check_parse '1970-01-01 00:59:59 +01' bad ++check_parse '1970-01-01 01:00:00 +01' '1970-01-01 01:00:00 +0100' ++check_parse '1970-01-01 01:00:00 +11' bad ++check_parse '1970-01-02 00:00:00 +11' '1970-01-02 00:00:00 +1100' ++check_parse '1969-12-31 23:59:59' bad ++check_parse '1969-12-31 23:59:59 +00' bad ++check_parse '1969-12-31 23:59:59 Z' bad ++check_parse '1969-12-31 23:59:59 +11' bad ++check_parse '1969-12-31 23:59:59 -11' bad + + check_approxidate() { + echo "$1 -> $2 +0000" >expect date.c | 6 +++++- t/t0006-date.sh | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/date.c b/date.c index 7365a4ad24f..8e3ec1bcb00 100644 --- a/date.c +++ b/date.c @@ -937,8 +937,12 @@ int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset) } } - if (!tm_gmt) + if (!tm_gmt) { + if (*offset > 0 && *offset * 60 > *timestamp) + return -1; *timestamp -= *offset * 60; + } + return 0; /* success */ } diff --git a/t/t0006-date.sh b/t/t0006-date.sh index 3031256d143..cdbb40bec01 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -116,6 +116,21 @@ check_parse '2008-02-14 20:30:45 -:30' '2008-02-14 20:30:45 +0000' check_parse '2008-02-14 20:30:45 -05:00' '2008-02-14 20:30:45 -0500' check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5 check_parse 'Thu, 7 Apr 2005 15:14:13 -0700' '2005-04-07 15:14:13 -0700' +check_parse '1970-01-01 00:00:00' '1970-01-01 00:00:00 +0000' +check_parse '1970-01-01 00:00:00 +00' '1970-01-01 00:00:00 +0000' +check_parse '1970-01-01 00:00:00 Z' '1970-01-01 00:00:00 +0000' +check_parse '1970-01-01 00:00:00 -01' '1970-01-01 00:00:00 -0100' +check_parse '1970-01-01 00:00:00 +01' bad +check_parse '1970-01-01 00:00:00 +11' bad +check_parse '1970-01-01 00:59:59 +01' bad +check_parse '1970-01-01 01:00:00 +01' '1970-01-01 01:00:00 +0100' +check_parse '1970-01-01 01:00:00 +11' bad +check_parse '1970-01-02 00:00:00 +11' '1970-01-02 00:00:00 +1100' +check_parse '1969-12-31 23:59:59' bad +check_parse '1969-12-31 23:59:59 +00' bad +check_parse '1969-12-31 23:59:59 Z' bad +check_parse '1969-12-31 23:59:59 +11' bad +check_parse '1969-12-31 23:59:59 -11' bad check_approxidate() { echo "$1 -> $2 +0000" >expect base-commit: 9eaef5822cd76bbeb53b6479ce0ddaad34ee2b14 -- gitgitgadget