Conversation
Theres a data race between ossl_method_store_insert and
ossl_method_store_do_all, as the latter doesn't take the property lock
before iterating.
However, we can't lock in do_all, as the call stack in several cases
later attempts to take the write lock.
The choices to fix it are I think:
1) add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so that
subsequent callers can determine if they need to take a lock or not
2) Clone the algs sparse array in ossl_method_store_do_all and use the
clone to iterate with no lock held, ensuring that updates to the
parent copy of the sparse array are left untoucheTheres a data race
between ossl_method_store_insert and ossl_method_store_do_all, as the
latter doesn't take the property lock before iterating.
However, we can't lock in do_all, as the call stack in several cases
later attempts to take the write lock.
The choices to fix it are I think:
1) add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so
that subsequent callers can determine if they need to take a lock
or not
2) Clone the algs sparse array in ossl_method_store_do_all and use
the clone to iterate with no lock held, ensuring that updates to
the parent copy of the sparse array are left untouched during the
iteration
I think method (2), while being a bit more expensive, is probably the
far less invasive way to go here
Fixes openssl#24672
nhorman
marked this pull request as draft
July 2, 2024 19:15
nhorman
marked this pull request as ready for review
July 2, 2024 19:36
paulidale
approved these changes
Jul 2, 2024
paulidale
left a comment
Contributor
There was a problem hiding this comment.
Just one nit.
This is the method we use elsewhere to avoid similar problems.
Contributor
|
A thought: would using a stack for the temporary copy make sense? It would avoid some of the inefficiencies of the sparse array. |
Member
Yeah, we should use that. |
Member
|
Please also note there is a duplicated text in the commit message. |
read lock store on ossl_method_store_do_all Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes openssl#24672
Contributor
Author
|
fixups made to use a stack rather than a sparse array, fix nits, and correct commit message |
rschu1ze
pushed a commit
to ClickHouse/openssl
that referenced
this pull request
Jul 3, 2024
This is a combination of 3 commits.
This is the 1st commit message:
read lock store on ossl_method_store_do_all
Theres a data race between ossl_method_store_insert and
ossl_method_store_do_all, as the latter doesn't take the property lock
before iterating.
However, we can't lock in do_all, as the call stack in several cases
later attempts to take the write lock.
The choices to fix it are I think:
1) add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so that
subsequent callers can determine if they need to take a lock or not
2) Clone the algs sparse array in ossl_method_store_do_all and use the
clone to iterate with no lock held, ensuring that updates to the
parent copy of the sparse array are left untoucheTheres a data race
between ossl_method_store_insert and ossl_method_store_do_all, as the
latter doesn't take the property lock before iterating.
However, we can't lock in do_all, as the call stack in several cases
later attempts to take the write lock.
The choices to fix it are I think:
1) add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so
that subsequent callers can determine if they need to take a lock
or not
2) Clone the algs sparse array in ossl_method_store_do_all and use
the clone to iterate with no lock held, ensuring that updates to
the parent copy of the sparse array are left untouched during the
iteration
I think method (2), while being a bit more expensive, is probably the
far less invasive way to go here
Fixes openssl#24672
This is the commit message #2:
amend! read lock store on ossl_method_store_do_all
read lock store on ossl_method_store_do_all
Theres a data race between ossl_method_store_insert and
ossl_method_store_do_all, as the latter doesn't take the property lock
before iterating.
However, we can't lock in do_all, as the call stack in several cases
later attempts to take the write lock.
The choices to fix it are I think:
1) add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so that
subsequent callers can determine if they need to take a lock or not
2) Clone the algs sparse array in ossl_method_store_do_all and use the
clone to iterate with no lock held, ensuring that updates to the
parent copy of the sparse array are left untoucheTheres a data race
between ossl_method_store_insert and ossl_method_store_do_all, as the
latter doesn't take the property lock before iterating.
I think method (2), while being a bit more expensive, is probably the
far less invasive way to go here
Fixes openssl#24672
This is the commit message #3:
fixup! amend! read lock store on ossl_method_store_do_all
t8m
approved these changes
Jul 3, 2024
paulidale
reviewed
Jul 4, 2024
paulidale
self-requested a review
July 4, 2024 03:26
t8m
approved these changes
Jul 8, 2024
Collaborator
|
This pull request is ready to merge |
Member
|
Merged to all the active branches. Thank you. |
openssl-machine
pushed a commit
that referenced
this pull request
Jul 9, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #24782) (cherry picked from commit d8def79)
openssl-machine
pushed a commit
that referenced
this pull request
Jul 9, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #24782)
openssl-machine
pushed a commit
that referenced
this pull request
Jul 9, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #24782) (cherry picked from commit d8def79)
openssl-machine
pushed a commit
that referenced
this pull request
Jul 9, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #24782) (cherry picked from commit d8def79)
openssl-machine
pushed a commit
that referenced
this pull request
Jul 9, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #24782) (cherry picked from commit d8def79)
rschu1ze
added a commit
to ClickHouse/openssl
that referenced
this pull request
Jul 14, 2024
This reverts commit ee2bb85. The PR was not finished yet, more commits were added later on.
rschu1ze
pushed a commit
to ClickHouse/openssl
that referenced
this pull request
Jul 14, 2024
read lock store on ossl_method_store_do_all Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes openssl#24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl#24782) (cherry picked from commit d8def79)
eclipse-oniro-oh-bot
pushed a commit
to eclipse-oniro-mirrors/third_party_openssl
that referenced
this pull request
Sep 6, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl/openssl#24782) (cherry picked from commit d8def79838cd0d5e7c21d217aa26edb5229f0ab4) Signed-off-by: 王静 <[email protected]>
rschu1ze
pushed a commit
to ClickHouse/openssl
that referenced
this pull request
Sep 6, 2024
read lock store on ossl_method_store_do_all Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes openssl#24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl#24782) (cherry picked from commit d8def79)
eclipse-oniro-oh-bot
pushed a commit
to eclipse-oniro-mirrors/third_party_openssl
that referenced
this pull request
Sep 7, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl/openssl#24782) (cherry picked from commit d8def79838cd0d5e7c21d217aa26edb5229f0ab4) Signed-off-by: 王静 <[email protected]>
eclipse-oniro-oh-bot
pushed a commit
to eclipse-oniro-mirrors/third_party_openssl
that referenced
this pull request
Oct 4, 2024
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock. The choices to fix it are I think: 1) add an argument to indicate to ossl_method_store_do_all weather to take the read or write lock when doing iterations, and add an is_locked api to the ossl_property_[read|write] lock family so that subsequent callers can determine if they need to take a lock or not 2) Clone the algs sparse array in ossl_method_store_do_all and use the clone to iterate with no lock held, ensuring that updates to the parent copy of the sparse array are left untoucheTheres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating. I think method (2), while being a bit more expensive, is probably the far less invasive way to go here Fixes #24672 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl/openssl#24782) (cherry picked from commit d8def79838cd0d5e7c21d217aa26edb5229f0ab4) Signed-off-by: 王静 <[email protected]>
nhorman
added a commit
to nhorman/openssl
that referenced
this pull request
Oct 8, 2025
PR openssl#24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: openssl#24672 However, the problem wasn't completely fixed. Issue: openssl#27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes openssl#27726
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
openssl-machine
pushed a commit
that referenced
this pull request
Oct 23, 2025
PR #24782 introduced a copying of the algs stack in ossl_method_store_do all, so that the subsequent iteration of elements through alg_do_one could be done without a lock, and without triggering a tsan error as reported in: #24672 However, the problem wasn't completely fixed. Issue: #27726 Noted that, sometimes we still get a crash when iterating over each algs impls stack. This occurs because, even though we've cloned the algs to a private data area, the impls stack for each alg still points to shared data, which we are accessing without the benefit of a lock. Because of that, if some other thread calls a function that mutates the impl stack (say ossl_method_store_remove()), we may encounter a NULL or garbage value in one of the impl stack values, leading to an unexpected NULL pointer or simmilar, which in turn leads to a crash. Unfortunately we can't use a lock to create exclusive access here, as there are several paths that lead to a recursive mutation of the stack, which would deadlock. So the only way that I see to prevent this (which is admittedly ugly), is to not only clone the alg stack, but to duplicate each algs impl stack with the read lock held, prior to doing the iteration. Further, we've been unable to test this, as the problem is rare, and we don't have a solid reproducer for the issue, but visual inspection suggests this should fix that. Hopefully: Fixes #27726 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from #28783) (cherry picked from commit 9ef4f42)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Theres a data race between ossl_method_store_insert and ossl_method_store_do_all, as the latter doesn't take the property lock before iterating.
However, we can't lock in do_all, as the call stack in several cases later attempts to take the write lock.
The choices to fix it are I think:
add an argument to indicate to ossl_method_store_do_all weather to
take the read or write lock when doing iterations, and add an
is_locked api to the ossl_property_[read|write] lock family so that
subsequent callers can determine if they need to take a lock or not
Clone the algs sparse array in ossl_method_store_do_all and use the
clone to iterate with no lock held, ensuring that updates to the
parent copy of the sparse array are left untoucheTheres a data race
between ossl_method_store_insert and ossl_method_store_do_all, as the
latter doesn't take the property lock before iterating.
I think method (2), while being a bit more expensive, is probably the far less invasive way to go here
Fixes #24672