Skip to content

Conversation

jarlamsa
Copy link
Contributor

@jarlamsa jarlamsa commented Aug 12, 2019

Description

This is a side-port to development of PR https://github.com/ARMmbed/mbedtls-restricted/pull/570 that has already been merged to baremetal.

Dependencies: based on #2764 and #2766 - see "Background" below.

The goal of this PR is to make the session serialisation ABI-independent.

Background

This is the third in a series of seven PRs implementing serialization of a full SSL context (not just the session), under some restrictions.

The PRs in the series are:

  1. r563 -> [s11n 1/7] Refactor derive keys (side-port) #2764 Refactor derive keys
  2. r568 -> [s11n 2/7] Make session serialisation functions public #2766 Make session serialisation functions public
  3. r570 -> [s11n 3/7] Make session format ABI-independent #2785 Make session format ABI-independent (this PR)
  4. r567 -> [s11n 4/7] Add version + config check to SSL tickets #2788 Add version + config check to SSL tickets
  5. r572 -> [s11n 5/7] Context serialisation: API and documentation #2789 Context serialisation: API and documentation
  6. r575 -> [s11n 6/7] Serialisation test #2791 Serialization test
  7. r616 -> [s11n 7/7] Implement context serialisation #2792 Implement context serialization

The full series is already merged in baremetal. It needs upstreaming for the benefit of the Could team, who will be the main user, and relies on upstream releases.

Side-porting details

Side-porting was done with git cherry-pick; most commit were picked with no conflicts. With the remaining one, the conflicts were trivial (only the context had changed due to independent addition at the same place).

The table shows how each side-ported commit was handled:

  • (nothing) cherry-picking worked without conflict
  • "t" only trivial context-related conflicts (eg. independent additions to the same place)
  • "r" manual rework after cherry-picking
  • "R" the commit was reconstructed manually (moving code around)
  • "+" added in this side-port PR
resolution original commit commit message
r 60a4299 Add new ABI-independent format for serialization
f8c355a Adapt buffering test to new ticket size
c4f5080 Re-enable test that now works with new format

Review notes

Reviewers are strongly encouraged to review commit by commit, as the final diff is unlikely to make sense. Please note that the first commits (up to "Fix serialization tests for !SSL_KEEP_PEER_CERT") are part of #2764 and #2766 and don't need to be re-reviewed here (except checking that they're indeed part of #2764 #2766).

@jarlamsa
Copy link
Contributor Author

Amended 28b7590

@jarlamsa jarlamsa requested a review from simonbutcher August 14, 2019 07:25
@jarlamsa jarlamsa added needs-ci Needs to pass CI tests needs-review Every commit must be reviewed by at least two team members, and removed needs-work needs-ci Needs to pass CI tests labels Aug 14, 2019
hanno-becker
hanno-becker previously approved these changes Aug 14, 2019
Copy link

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jarlamsa
Copy link
Contributor Author

Rebased on top of #2766

hanno-becker
hanno-becker previously approved these changes Aug 15, 2019
Copy link

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the rebase myself and obtained the same result.

@jarlamsa
Copy link
Contributor Author

Rebased

@jarlamsa
Copy link
Contributor Author

@hanno-arm please re-review

mpg added 17 commits August 23, 2019 12:48
This uncovered a bug that led to a double-free (in practice, in general could
be free() on any invalid value): initially the session structure is loaded
with `memcpy()` which copies the previous values of pointers peer_cert and
ticket to heap-allocated buffers (or any other value if the input is
attacker-controlled). Now if we exit before we got a chance to replace those
invalid values with valid ones (for example because the input buffer is too
small, or because the second malloc() failed), then the next call to
session_free() is going to call free() on invalid pointers.

This bug is fixed in this commit by always setting the pointers to NULL right
after they've been read from the serialised state, so that the invalid values
can never be used.

(An alternative would be to NULL-ify them when writing, which was rejected
mostly because we need to do it when reading anyway (as the consequences of
free(invalid) are too severe to take any risk), so doing it when writing as
well is redundant and a waste of code size.)

Also, while thinking about what happens in case of errors, it became apparent
to me that it was bad practice to leave the session structure in an
half-initialised state and rely on the caller to call session_free(), so this
commit also ensures we always clear the structure when loading failed.
Not checking the return value allowed a bug to go undetected, fix the bug and
check the return value.
This test works regardless of the serialisation format and embedded pointers
in it, contrary to the load-save test, though it requires more maintenance of
the test code (sync the member list with the struct definition).
Found by 'all.sh test_no_platform' and by 'tests/scripts/test-ref-configs.pl'.
We have explicit recommendations to use US spelling for technical writing, so
let's apply this to code as well for uniformity. (My fingers tend to prefer UK
spelling, so this needs to be fixed in many places.)

sed -i 's/\([Ss]eriali\)s/\1z/g' **/*.[ch] **/*.function **/*.data ChangeLog
This bug was present since cert digest had been introduced, which highlights
the need for testing.

While at it, fix a bug in the comment explaining the format - this was
introduced by me copy-pasting to hastily from current baremetal, that has a
different format (see next PR in the series for the same in development).
The chosen fix matches what's currently done in the baremetal branch - except
the `#ifdef` have been adapted because now in baremetal the digest is not kept
if renegotiation is disabled.
The size of the ticket used in this test dropped from 192 to 143 bytes, so
move all sizes used in this test down 50 bytes. Also, we now need to adapt the
server response size as the default size would otherwise collide with the new
mtu value.
Previously the test didn't work because of embedded pointer values that
are not predictable. Now it works as we no longer serialize such values.
@jarlamsa jarlamsa dismissed stale reviews from jarvte and hanno-becker via aa75583 August 23, 2019 09:50
@jarlamsa jarlamsa force-pushed the abi-indep-session-serial-dev branch from 9fcb57a to aa75583 Compare August 23, 2019 09:50
@jarlamsa
Copy link
Contributor Author

Rebased without conflicts

@jarlamsa
Copy link
Contributor Author

@hanno-arm @jarvte please re-review

@jarvte jarvte self-requested a review August 23, 2019 10:31
Copy link

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the rebase myself and obtained the same result. Therefore reapproving.

@jarlamsa
Copy link
Contributor Author

All of the serialisation PRs now have 2 approving reviews and passing CI. Thus considering all of them ready for merge.

@jarlamsa jarlamsa added approved Design and code approved - may be waiting for CI or backports and removed needs-review Every commit must be reviewed by at least two team members, labels Aug 26, 2019
@Patater Patater merged commit aa75583 into Mbed-TLS:development Aug 27, 2019
@Patater Patater removed the needs-preceding-pr Requires another PR to be merged first label Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Design and code approved - may be waiting for CI or backports component-tls enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants