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

SRF functions need to "fetch" (call FromDatum) each argument while … #784

Merged
merged 2 commits into from
Oct 19, 2022

Conversation

eeeebbbbrrrr
Copy link
Contributor

…operating within the function's "multi-call-memory-context". This ensures any allocation FromDatum might do lives as along as the entire SRF calling process does.

This is the proper fix for PR #779, which pointed out that it wasn't possible for SRFs to return data borrowed from their input. Tests are included.

@Smittyvb: This PR should resolve the problems that #779 was trying to explain away with documentation. Prior to this PR, pgx was potentially detoasting argument datums in the wrong memory context, causing the UAF you were seeing. I'd love it if you could rejigger your code against this PR and make sure it now works as you'd expect. I updated the strings example to show that a SRF can borrow from its input.

…operating within the function's "multi-call-memory-context". This ensures any allocation `FromDatum` might do lives as along as the entire SRF calling process does.

This is the proper fix for PR #779, which pointed out that it wasn't possible for SRFs to return data
borrowed from their input.
@eeeebbbbrrrr eeeebbbbrrrr self-assigned this Oct 19, 2022
@eeeebbbbrrrr eeeebbbbrrrr added the bug Something isn't working label Oct 19, 2022
Copy link
Contributor

@syvb syvb left a comment

Choose a reason for hiding this comment

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

I tested my code against this PR and it fixed the use-after-free I was getting. (the tests now pass before and after reverting timescale/timescaledb-toolkit@fe8b386).

@eeeebbbbrrrr
Copy link
Contributor Author

That's fantastic, @Smittyvb. Thanks for checking so quickly.

We'll get this reviewed and merged ASAP. I'm hoping we can get another release out this week...

Comment on lines +474 to +476
// function arguments need to be "fetched" while in the function call's
// multi-call-memory-context to ensure that any detoasted datums will
// live long enough for the SRF to use them over each call
Copy link
Member

Choose a reason for hiding this comment

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

This is what needs to also be documented in a place outside the context of this function's comments. Especially so because this is something that will always need to remain true: we always must satisfy this sort of lifetime-binding condition, and it doesn't matter whether the code is burned and rewritten a million times: it remains a constraint. It should be easier to reference this sort of information than reading thousands of lines of implementations line by line, because it determines how fast someone can begin to understand the concepts required to write correct code for implementing PGX.

Comment on lines +415 to +422
"name" => {
let mut out: NameMacro = mac.parse_body().expect("name!() in wrong format");
staticize_lifetimes(&mut out.used_ty.resolved_ty);

// rewrite the name!() macro so that it has a static lifetime, if any
let ident = syn::parse_str::<Ident>(&out.ident).unwrap();
let ty = out.used_ty.resolved_ty;
type_macro.mac = syn::parse_quote! {name!(#ident, #ty)};
Copy link
Member

Choose a reason for hiding this comment

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

#[pg_extern]
fn split_table_with_borrow<'a>(
    input: &'a str,
    pattern: &'a str,
) -> TableIterator<'a, (name!(i, i32), name!(s, &'a str))>

So in this case, the return lifetimes we are expecting will be

) -> TableIterator<'static, (name!(i, i32), name!(s, &'static str))>

?

Copy link
Member

Choose a reason for hiding this comment

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

Hm. I think this can be done in a better way in the future, but I can't find the solution immediately and we're staticizing other lifetimes, so I think this is acceptable for the current moment.

@workingjubilee workingjubilee merged commit 4232735 into develop Oct 19, 2022
bors bot added a commit to timescale/timescaledb-toolkit that referenced this pull request Oct 31, 2022
597: Revert now unneeded pgx workaround r=Smittyvb a=Smittyvb

We don't need copy everything into memory owned by Rust anymore, since pgx 0.5.4 fixed the bug that made doing that necessary (pgcentralfoundation/pgrx#784).

This reverts commit fe8b386.

I didn't add anything to the changelog since this an internal change that doesn't affect end users.

Co-authored-by: Smitty <smitty@timescale.com>
@eeeebbbbrrrr eeeebbbbrrrr deleted the pr-779-followup branch June 20, 2023 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants