Skip to content
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

Fix an out-of-bounds read for TLS <- 1.2 cipher strings that end in a "-" #19166

Closed
wants to merge 1 commit into from

Conversation

millert
Copy link
Contributor

@millert millert commented Sep 7, 2022

In ssl_cipher_process_rulestr(), if rule_str ended in a "-", "l" was incremented one byte past the end of the buffer. This resulted in an out-of-bounds read when "l" is dereferenced at the end of the loop. The trivial fix is to only increment "l" if the last byte read is not a NUL.

CLA: trivial

@millert millert changed the title Fix an out-of-bounds read for TLS <- 1.2 cipher strings that end in a "-"ssl_cipher_process_rulestr: don't read outside rule_str buffer Fix an out-of-bounds read for TLS <- 1.2 cipher strings that end in a "-" Sep 7, 2022
@paulidale paulidale added branch: master Merge to master branch triaged: bug The issue/pr is/fixes a bug cla: trivial One of the commits is marked as 'CLA: trivial' branch: 3.0 Merge to openssl-3.0 branch labels Sep 7, 2022
@t8m t8m added the approval: done This pull request has the required number of approvals label Sep 8, 2022
@paulidale
Copy link
Contributor

Confirm trivial? I think it is but I added the label 😃

@t8m
Copy link
Member

t8m commented Sep 8, 2022

I am OK with CLA: trivial for this.

@paulidale should this go into 1.1.1 too? IMO yes, if it applies there.

@paulidale paulidale added the branch: 1.1.1 Merge to OpenSSL_1_1_1-stable branch label Sep 8, 2022
@davidben
Copy link
Contributor

davidben commented Sep 8, 2022

Should this have a regression test? That test combined with ASan should provide regression coverage.

ssl/ssl_ciph.c Outdated
@@ -1064,7 +1064,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
*/
ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND);
retval = found = 0;
l++;
if (ch != '\0')
l++;
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, is this the right fix? This is an error condition, ERR_raise and all, and yet we're breaking out of just the inner loop. It seems we actually just want to break out of the outer loop.

Looking back, it seems we hit this with a fuzzer a while back, but our fix was to make the function immediately fail.
https://boringssl-review.googlesource.com/c/boringssl/+/11421/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Returning early seems safer.

Copy link
Contributor

@davidben davidben Sep 8, 2022

Choose a reason for hiding this comment

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

Yeah. It also seems the function will get confused otherwise. If I'm reading this right, I believe break exits to line 1220 ("Ok, we have the rule, now apply it"). That could try to execute CIPHER_SPECIAL or skip over something and then continue running. We may execute more rules, pile on more errors, before finally returning failure anyway because retval is cleared.

@millert
Copy link
Contributor Author

millert commented Sep 8, 2022

For some reason this can be hard to trigger with address sanitizer. The following reliably reproduces the problem for me with gcc -O2 -fsanitize=address -fno-omit-frame-pointer (but does not if -fno-omit-frame-pointer is not specified). With a dynamically allocated ciphers list triggering the bug is more difficult.

#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>

int
main(int argc, char *argv[])
{
    const char ciphers[] = "ALL:-";
    SSL_CTX *ctx = SSL_CTX_new(TLS_method());
    SSL_CTX_set_cipher_list(ctx, ciphers);
    SSL_CTX_free(ctx);
}

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@t8m t8m added branch: 3.1 Merge to openssl-3.1 and removed approval: done This pull request has the required number of approvals labels Oct 24, 2022
@t8m
Copy link
Member

t8m commented Oct 24, 2022

@millert could you please change this according to the @davidben's suggestion?

If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial
@millert
Copy link
Contributor Author

millert commented Oct 24, 2022

@t8m I updated the commit to just return early as discussed.

@t8m t8m added the approval: review pending This pull request needs review by a committer label Oct 24, 2022
@t8m
Copy link
Member

t8m commented Oct 24, 2022

@paulidale still OK?

@paulidale paulidale added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Oct 25, 2022
@openssl-machine openssl-machine removed the approval: done This pull request has the required number of approvals label Oct 26, 2022
@openssl-machine openssl-machine added the approval: ready to merge The 24 hour grace period has passed, ready to merge label Oct 26, 2022
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

openssl-machine pushed a commit that referenced this pull request Oct 26, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #19166)
openssl-machine pushed a commit that referenced this pull request Oct 26, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #19166)

(cherry picked from commit 428511c)
openssl-machine pushed a commit that referenced this pull request Oct 26, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #19166)

(cherry picked from commit 428511c)
@t8m
Copy link
Member

t8m commented Oct 26, 2022

Merged to all branches (after fixing trivial conflict on 1.1.1 branch). Thank you for your contribution.

@t8m t8m closed this Oct 26, 2022
openssl-machine pushed a commit that referenced this pull request Oct 26, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #19166)

(cherry picked from commit 428511c)
bernd-edlinger pushed a commit to bernd-edlinger/openssl that referenced this pull request Nov 4, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#19166)

(cherry picked from commit 428511c)
bernd-edlinger pushed a commit to bernd-edlinger/openssl that referenced this pull request Nov 4, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#19166)

(cherry picked from commit 428511c)
bernd-edlinger pushed a commit to bernd-edlinger/openssl that referenced this pull request Nov 4, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#19166)

(cherry picked from commit 428511c)
beldmit pushed a commit to beldmit/openssl that referenced this pull request Dec 26, 2022
If rule_str ended in a "-", "l" was incremented one byte past the
end of the buffer.  This resulted in an out-of-bounds read when "l"
is dereferenced at the end of the loop.  It is safest to just return
early in this case since the condition occurs inside a nested loop.

CLA: trivial

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#19166)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Merge to master branch branch: 1.1.1 Merge to OpenSSL_1_1_1-stable branch branch: 3.0 Merge to openssl-3.0 branch branch: 3.1 Merge to openssl-3.1 cla: trivial One of the commits is marked as 'CLA: trivial' triaged: bug The issue/pr is/fixes a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants