[PATCH v3] libstdc++: fix a dangling reference crash in ranges::is_permutation
Giuseppe D'Angelo
giuseppe.dangelo@kdab.com
Sat Dec 21 10:22:17 GMT 2024
Hello,
On 20/12/2024 22:20, Patrick Palka wrote:
>>> The attached patch fixes it. I've tested on Linux x86-64. Adding a
>>> negative test for this is somehow challenging (how do you test you're
>>> not using a dangling reference?), but running the modified test under
>>> ASAN shows the fix in place.
>
> I'd expect a constexpr version of the test to reliably fail as soon as
> it encounters the UB.
Good idea! added.
>
>>>
>>> Do you need me to create a report on bugzilla and cross-reference it
>>> from the patch?
>
> That'd be good since we'll probably want to backport the fix to the
> release branches and the PR could reflect that.
Done, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118160
> Makes sense, but it might be preferable for sake of QoI to fix this
> without introducing extra dereferences or projection applications
> if possible.
>
> auto&& is supposed to perform lifetime extension, but that only happens
> for an outermost temporary and not any temporaries within a
> subexpression IIUC. So how about if we use a second auto&& for the
> *__scan subexpression so that lifetime extension occurs there?
>
>>
>> libstdc++-v3/ChangeLog:
>>
>> * include/bits/ranges_algo.h (__is_permutation_fn): Do not cache
>> the projection result in a local variable, as that may create
>> dangling references.
>> * testsuite/25_algorithms/is_permutation/constrained.cc: Add a
>> test with a range returning prvalues.
>>
>> Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
>> ---
>> libstdc++-v3/include/bits/ranges_algo.h | 3 +--
>> .../25_algorithms/is_permutation/constrained.cc | 11 +++++++++++
>> 2 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
>> index 772bf4dd997..4d3c4325e2c 100644
>> --- a/libstdc++-v3/include/bits/ranges_algo.h
>> +++ b/libstdc++-v3/include/bits/ranges_algo.h
>> @@ -567,9 +567,8 @@ namespace ranges
>>
>> for (auto __scan = __first1; __scan != __last1; ++__scan)
>> {
>> - auto&& __proj_scan = std::__invoke(__proj1, *__scan);
>> auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) -> bool {
>> - return std::__invoke(__pred, __proj_scan,
>
> If we go with the second auto&& approach then we should perfect forward
> __proj_scan here as you alluded to. That might seem unsafe at first
> glance (if say the project returns an rvalue) but since the predicate is
> regular_invocable it mustn't modify its arguments IIUC.
Just to reiterate: if the projection returns an rvalue, it would be
wrong for the predicate to actually move from it, as it would violate
the equality-preserving semantic requirements of regular_invocable? I'll
add the missing forward then.
New patch attached.
Thanks,
--
Giuseppe D'Angelo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-libstdc-fix-a-dangling-reference-crash-in-ranges-is_.patch
Type: text/x-patch
Size: 3342 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20241221/69754404/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4244 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20241221/69754404/attachment.p7s>
More information about the Libstdc++
mailing list