Skip to content

Commit

Permalink
Add RELEASE_NOTES.md
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Sep 4, 2023
1 parent 731b349 commit d4d6df9
Show file tree
Hide file tree
Showing 2 changed files with 801 additions and 106 deletions.
106 changes: 0 additions & 106 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,88 +3,6 @@ Changelog

This file will be updated on new releases, there usually won't be an `Unreleased` section.

## Unreleased

### Relation between chrono and time 0.1

Since Rust 0.7 the standard library had a `time` module. It moved to `libextra`, and then to a
`libtime` library shipped alongside the standard library. In 2014 the work on chrono started in
order to provide a full-featured date and time library in Rust. Some improvements from chrono made
it into the standard library, notably the `chrono::Duration` type was moved to
`std::time::Duration` ([rust#15934]).

In preparation of Rust 1.0 at the end of 2014 `libtime` was moved out of the Rust distro and into
the `time` crate to eventually be redesigned ([rust#18832], [rust#18858]), just like the `num` and
`rand` crates. Naturally chrono gained `time` as a dependency. `time` also started re-exporting
`std::time::Duration`. Later the standard library was changed to have a more limited unsigned
`Duration` type ([rust#24920], [RFC 1040]), while the `time` crate kept the full functionality with
`time::Duration`. And `time::Duration` was part of the public API of chrono.

By 2016 `time` 0.1 lived under the `rust-lang-deprecated` organisation and was not actively
maintained ([time#136]). Chrono absorbed the platform functionality and `Duration` type of the time
crate in [chrono#478] (the work started in [chrono#286]). But because of the `time::Duration` type
and to not make this a breaking change `time` would still remain as a dependency. Crates could opt
to use chrono without the `old-time` feature to drop the dependency. During this time @jhpratt would
take over `time` and release what amounts to a new crate under time 0.2.

[rust#15934]: https://github.com/rust-lang/rust/pull/15934
[rust#18832]: https://github.com/rust-lang/rust/pull/18832#issuecomment-62448221
[rust#18858]: https://github.com/rust-lang/rust/pull/18858
[rust#24920]: https://github.com/rust-lang/rust/pull/24920
[RFC 1040]: https://rust-lang.github.io/rfcs/1040-duration-reform.html
[time#136]: https://github.com/time-rs/time/issues/136
[chrono#286]: https://github.com/chronotope/chrono/pull/286
[chrono#478]: https://github.com/chronotope/chrono/pull/478

#### Security advisories

In november 2020 [CVE-2020-26235] and [RUSTSEC-2020-0071] were opened against the time crate, and
the start of quite some frustration for the rust ecosystem. @quininer found that calls to
`localtime_r` may be unsound ([chrono#499]). Eventually, almost a year later, this was also made
into a security advisory against chrono as [RUSTSEC-2020-0159], which had platform code similar to
`time`.

The issue: on Unix-like systems a process is given a time zone id or description via the `TZ`
environment variable. We need this time zone data to calculate the current local time from a value
that is in UTC, such as the time from the system clock. `time` 0.1 and chrono used the POSIX
function `localtime_r` to do the conversion to local time, which reads the `TZ` variable.

Rust assumes the environment to be writable and uses locks to access it from multiple threads. So do
some other programming languages and libraries, but there is no shared locking mechanism. More
importantly POSIX declares modifying the environment in a multi-threaded process as unsafe, and
`getenv` in libc can't be changed to just take a lock because it returns a pointer to the data (see
[rust#27970] for more discussion).

Since [chrono#677], released as version 4.20, chrono no longer uses `localtime_r` but provides a
pure-rust solution. This makes reading the `TZ` variable if changed by Rust code sound. The fix
involves reading the `TZ` variable and/or the `/etc/localtime` symlink, caching, implementing the
logic for POSIX TZ String time zone transitions, and parsing TZif files and working with that data.
The code mostly comes from the work by @x-hgg-x on the [tz-rs crate].

The good thing to come from this is that we can improve beyond what the platform offers.

[CVE-2020-26235]: https://nvd.nist.gov/vuln/detail/CVE-2020-26235
[RUSTSEC-2020-0071]: https://rustsec.org/advisories/RUSTSEC-2020-0071
[chrono#499]: https://github.com/chronotope/chrono/pull/499
[RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html
[rust#27970]: https://github.com/rust-lang/rust/issues/27970
[chrono#677]: https://github.com/chronotope/chrono/pull/677
[tz-rs crate]: https://crates.io/crates/tz-rs

#### Removing time 0.1

Still users of chrono would get a security advisory because of the time 0.1 dependency, which was
never fixed. We were careful not to break backwards compatibility with the `time::Duration` type.
But how many crates actually depend on this compatibility with time 0.1? Remember it was
unmaintained for multiple years, and now had much improved new releases. After a primitive
crater-like run it turned out only a tiny number of crates would break ([chrono#1095]), which we
reached out to if still maintained.

With 0.4.29 chrono finally drops the time 0.1 dependency, making an end to the *many* security
advisory warnings against crates depending on chrono.

[chrono#1095]: https://github.com/chronotope/chrono/pull/1095

## [0.4.28] - 2023-08-30

This release fixes a test failure on 32-bit targets introduced with 0.4.27,
Expand Down Expand Up @@ -343,30 +261,6 @@ Additionally, there is a documentation fix that reverts an incorrect guarantee:

## [0.4.20] - 2022-08-04

This is the first chrono release since Sep 2020. There has been a long hiatus
since the previous maintainer was no longer able to spend much time on the
crate; thanks to @quodlibetor for their stewardship of the chrono crate for
many years! The new maintainers are @djc and @esheppa.

Our first priority has been fixing the soundness issues with calls to
`localtime_r()` as first reported in #499 and the [RUSTSEC-2020-0159] advisory.
In order to do this we adapted code from the tz-rs crate maintained by
@x-hgg-x for use within chrono -- thanks for working on that! With the new
implementation, chrono uses safe Rust code to parse the timezone data files on
Unix platforms directly instead of relying on libc.

Due to compatibility reasons, this release does not yet remove the time 0.1
dependency, though chrono 0.4.20 does not depend on the vulnerable parts of the
time 0.1.x versions. In a future 0.5 release, we will remove the time
dependency.

The minimum supported Rust version for 0.4.20 is 1.32.0, which is intentionally
still quite conservative. If you are using chrono 0.4 with a Rust version older
than 1.52, we'd like to hear from you since we'd like to further modernize the
code base to ease maintenance.

[RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159

### Fixes

* Fix unsound call to `localtime_r()` by parsing timezone files in Rust on Unix (#677 and #728)
Expand Down

0 comments on commit d4d6df9

Please sign in to comment.