New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alter bounds check in ssl_load_session for slightly more safety #659
Labels
Comments
ARM Internal Ref: IOTSSL-1046 |
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 24, 2018
This commit replaces multiple bounds checks of the form `if( ptr + offset > end )` by `if( offset > end - ptr )`. The former is unsafe as the pointer arithmetic `ptr + offset` can overflow in case of a large value of `offset` paired with a value of `ptr` close to the (virtual) address boundary. The latter bounds check, in turn, is always safe if `offset` is a signed integral value, even if `ptr` happens to be larger than `end` (which should never happen, but it's better to be prepared just in case). Concretely, ssl_load_session() contains the bounds check `if( p + cert_len > end )` where `cert_len` is a 24-bit value of type `size_t`. This check is accordingly replaced by `if( (int) cert_len > end - p )`; the explicit cast `(int) cert_len` is safe because `int` is assumed to be 32-bit wide and paddingless, hence capable of holding 24-bit values. Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 24, 2018
This commit replaces multiple bounds checks of the form `if( ptr + offset > end )` by `if( offset > end - ptr )`. The former is unsafe as the pointer arithmetic `ptr + offset` can overflow in case of a large value of `offset` paired with a value of `ptr` close to the (virtual) address boundary. The latter bounds check, in turn, is always safe if `offset` is a signed integral value, even if `ptr` happens to be larger than `end` (which should never happen, but it's better to be prepared just in case). Concretely, ssl_load_session() contains the bounds check `if( p + cert_len > end )` where `cert_len` is a 24-bit value of type `size_t`. This check is accordingly replaced by `if( (int) cert_len > end - p )`; the explicit cast `(int) cert_len` is safe because `int` is assumed to be 32-bit wide and paddingless, hence capable of holding 24-bit values. Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 24, 2018
This commit replaces multiple bounds checks of the form `if( ptr + offset > end )` by `if( offset > end - ptr )`. The former is unsafe as the pointer arithmetic `ptr + offset` can overflow in case of a large value of `offset` paired with a value of `ptr` close to the (virtual) address boundary. The latter bounds check, in turn, is always safe if `offset` is a signed integral value, even if `ptr` happens to be larger than `end` (which should never happen, but it's better to be prepared just in case). Concretely, ssl_load_session() contains the bounds check `if( p + cert_len > end )` where `cert_len` is a 24-bit value of type `size_t`. This check is accordingly replaced by `if( (int) cert_len > end - p )`; the explicit cast `(int) cert_len` is safe because `int` is assumed to be 32-bit wide and paddingless, hence capable of holding 24-bit values. Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 24, 2018
This commit replaces multiple bounds checks of the form `if( ptr + offset > end )` by `if( offset > end - ptr )`. The former is unsafe as the pointer arithmetic `ptr + offset` can overflow in case of a large value of `offset` paired with a value of `ptr` close to the (virtual) address boundary. The latter bounds check, in turn, is always safe if `offset` is a signed integral value, even if `ptr` happens to be larger than `end` (which should never happen, but it's better to be prepared just in case). Concretely, ssl_load_session() contains the bounds check `if( p + cert_len > end )` where `cert_len` is a 24-bit value of type `size_t`. This check is accordingly replaced by `if( (int) cert_len > end - p )`; the explicit cast `(int) cert_len` is safe because `int` is assumed to be 32-bit wide and paddingless, hence capable of holding 24-bit values. Fixes Mbed-TLS#659 reported by Guido Vranken.
This was referenced Oct 24, 2018
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 25, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 25, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 25, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 25, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 26, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
hanno-becker
pushed a commit
to hanno-becker/mbedtls
that referenced
this issue
Oct 26, 2018
Fixes Mbed-TLS#659 reported by Guido Vranken.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In ssl_ticket.c ssl_load_session():
I would change this last check into
I don't think that under normal circumstances
cert_len
can ever exceed the buffer size, because it was always generated by the server itself inssl_save_session
, and is always verified to be legitimate inmbedtls_ssl_ticket_parse
. But in the unlikely event that an attacker can break the ticket decryption/authentication, the checkp + cert_len > end
doesn't work ifp
happens to be a very high virtual address andcert_len
happens to be very large.So say that
p
is address0xFFFF0000
, andend
is0xFFFFFF00
, andcert_len
is0x00FFFFFF
, then the comparison becomeswhich on 32 bit is
which is false, so it isn't treated as an error, despite
cert_len
exceeding the buffer size.If the attacker can also control the certificate that was embedded in the ticket, then they might be able to craft that certificate in such a way that
mbedtls_x509_crt_parse_der
writes N bytes of their choosing beyond buffer bounds (instead of occupying the wholecert_len
amount of space that probably leads to a crash).I hope this makes sense. The rationale is that breaking ticket encryption and authentication should only lead to session takeover, and not to a server compromise.
The text was updated successfully, but these errors were encountered: