-
-
Notifications
You must be signed in to change notification settings - Fork 249
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
Fixed out of bounds reads for open_cursor #1837
Fixed out of bounds reads for open_cursor #1837
Conversation
can you add a FIXME for it? thanks. |
The main reason it doesn't return a Result is that all of this was a relatively under-designed API that has been scheduled for total demolition and replacement, so comparatively minor but still breaking changes like "maybe we should have returned a Result here..." have been on-hold. |
pgrx/src/spi/query.rs
Outdated
let args = args.unwrap_or_default(); | ||
|
||
let (mut datums, nulls): (Vec<_>, Vec<_>) = args.into_iter().map(prepare_datum).unzip(); | ||
let (mut datums, nulls) = self.args_to_datums(args).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
specifically adding the FIXME right here.
Also alternatively: add fn try_open_cursor
, then tag this one with #[deprecated(since = "0.12.2", note = "lol ub")]
, and then replace the inner impl of this with just self.try_open_cursor(_client, args).unwrap()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will write the new method too then, that's not an issue for me. And actually, I have other plans for improvements there and around (:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that said, adding new API is optional, but we do need a #[should_panic]
test on this case for open_cursor
, or a "returns Err" test on the try_open_cursor
fn, either one.
It feels a little early to bump to 0.13, not that I'm afraid of such, but yk "a month" seems like a good span. |
I addressed your changes, but what I honestly don't like is If you share your plans on the SPI part, then I can contribute by reshaping it. |
The most fundamental issue is that the API does not enforce lifetime bounds properly. Solving this is hard, but it is why 0.12 landed a huge breaking change for most pgrx-using code: solving the problem with the It also has some overly complicated parts, like the overly-cutesy Query trait, which I would wish to move away from. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, this looks good.
Spi::connect(|mut client| { | ||
client.update("CREATE TABLE tests.cursor_table (id int)", None, None)?; | ||
client.update( | ||
"INSERT INTO tests.cursor_table (id) \ | ||
SELECT i FROM generate_series(1, 10) AS t(i)", | ||
None, | ||
None, | ||
)?; | ||
let prepared = client.prepare( | ||
"SELECT * FROM tests.cursor_table WHERE id = $1", | ||
Some([PgBuiltInOids::INT4OID.oid()].to_vec()), | ||
)?; | ||
client.open_cursor(&prepared, args); | ||
unreachable!(); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh, does this return an error because we panic during the connection? interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, it panics and the tests are marked as #[should_panic]
. That allows us to verify that there's no undefined behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, it's a bit incorrect without the reason I haven't provided for tests because unreachable!!
panics too and gives us a false negative. See #1843 for a fix.
pgrx/src/spi/client.rs
Outdated
/// # Panics | ||
/// | ||
/// Panics if a cursor wasn't opened. | ||
#[deprecated(since = "0.12.2", note = "undefined behavior")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm. on second thought, not entirely sure if we want to deprecate this just because it panics... otoh most people don't like panics...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, deprecate or leave it as it is for now? Personally I hate panicking, but there's a lot of upcoming work with breaking changes anyway, I guess, so forcing users to fix their code on each release isn't wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I've reconsidered and I think we should remove the deprecation note, I don't want to churn people pointlessly. I'll try to mention it in the release notes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or @eeeebbbbrrrr will. :^)
unless he feels that we should in fact deprecate this because it started panicking (but only when the alternative was UB).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stripping the deprecated stuff mostly, sorry about changing my mind back and forth.
@@ -532,6 +577,7 @@ mod tests { | |||
} | |||
|
|||
#[pg_test] | |||
#[allow(deprecated)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[allow(deprecated)] |
Thanks! |
Welcome to pgrx v0.12.2. This is a minor release that fixes a few bugs, improves compilation times with `cargo pgrx run/install/test`, and adds a few more Postgres headers. As usual, please `cargo install cargo-pgrx --version 0.12.2 --locked`. Then you can run `cargo pgrx upgrade` in your extension crate's root to update its dependencies. ## What's Changed * [ `CPPFLAGS`] Switch to `USE_ASSERT_CHECKING` by @SamuelMarks in #1826 * Add UnboxDatum for Range<T> by @mhov in #1827 * Moved Sized from FromDatum methods to trait by @YohDeadfall in #1831 * Used SPI result type for cursor API by @YohDeadfall in #1836 * always compile `pgrx_embed_*` without opts by @eeeebbbbrrrr in #1838 * Fixed out of bounds reads for open_cursor by @YohDeadfall in #1837 * Include `access/visibilitymap.h` and `utils/tuplestore.h` by @eeeebbbbrrrr in #1841 ## New Contributors Thanks to these folks for their first-time contributions -- it's greatly appreciated! * @SamuelMarks made their first contribution in #1826 * @YohDeadfall made their first contribution in #1831 **Full Changelog**: v0.12.1...v0.12.2
Fixes issues left from #1837, but nothing critical. The problem with `unreachable!` in tests is that it requires to have a non-empty `expected` in the `#[should_panic]` attribute. So we provide a message to verify that panicking happens for the right reason.
Welcome to pgrx v0.12.3. This point release upgrades to use the new Postgres 17rc1. As usual, please `cargo install cargo-pgrx --version 0.12.3 --locked`. Then you can run `cargo pgrx upgrade` in your extension crate's root to update its dependencies. ## What's Changed * Fixups of issues left from #1837 by @YohDeadfall in #1843 * move to Postgres v17rc1 by @eeeebbbbrrrr in #1846 **Full Changelog**: v0.12.2...v0.12.3
Welcome to pgrx v0.12.3. This point release upgrades to use the new Postgres 17rc1. As usual, please `cargo install cargo-pgrx --version 0.12.3 --locked`. Then you can run `cargo pgrx upgrade` in your extension crate's root to update its dependencies. ## What's Changed * Fixups of issues left from pgcentralfoundation#1837 by @YohDeadfall in pgcentralfoundation#1843 * move to Postgres v17rc1 by @eeeebbbbrrrr in pgcentralfoundation#1846 **Full Changelog**: pgcentralfoundation/pgrx@v0.12.2...v0.12.3
The problem arises when the prepared statement has less arguments than
the used plan since there's no parameter to pass the number of arguments
like it's for
SPI_execute_with_args
. Meanwhile theexecute
methoddoes a check.
Introduce a variant,
try_open_cursor
, that returns an SpiResult instead.