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

Sandbox curl (PHP 7) #814

Merged
merged 12 commits into from
Apr 10, 2020
Merged

Sandbox curl (PHP 7) #814

merged 12 commits into from
Apr 10, 2020

Conversation

morrisonlevi
Copy link
Collaborator

@morrisonlevi morrisonlevi commented Apr 7, 2020

Description

This sandboxes curl on PHP 7. It has two parts:

  1. The CurlSandboxIntegration, which does a posthook on curl_exec to make a span and add meta.
  2. The C extension instruments curl_exec, curl_copy_handle, curl_close, curl_setopt, and curl_setopt_array to gather headers and to inject distributed tracing headers.

Some calls are not sandboxed yet, and there are a few other todo comments in the code.

Readiness checklist

  • Tests added for this feature/bug.

Reviewer checklist

  • Appropriate labels assigned.
  • Milestone is set.
  • Changelog has been added to the appropriate release draft. For community contributors the reviewer is in charge of this task.

PHP 5 is stubbed out, but doesn't do anything.
Put ddtrace_curl_handlers_startup behind it.
Note that PHP 5 is stubbed out and doesn't sandbox.
The signature of zend_lookup_class_ex changed from taking
"should autoload?" to taking flags. This is not documented in
UPGRADING.INTERNALS. Note there is a change there about the "key"
changing from zval* to zend_string*; we do not use this arg, so
we avoid that change.
Copy link
Contributor

@SammyK SammyK left a comment

Choose a reason for hiding this comment

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

Lovely PR @morrisonlevi! I left some questions and feedback. :)

src/DDTrace/Integrations/Curl/CurlSandboxedIntegration.php Outdated Show resolved Hide resolved
static void ddtrace_activate(void) {}
static void ddtrace_deactivate(void) {}

static zend_extension _dd_zend_extension_entry = {"ddtrace",
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we know for sure if running as a Zend extension hybrid will have any side effects? Especially from the perspective of neighboring extensions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure. The only bits of the zend_extension we are using in this PR is the startup -- that should be very safe.

PHP5_UNUSED(extension);
PHP7_UNUSED(extension);

ddtrace_curl_handlers_startup();
Copy link
Contributor

Choose a reason for hiding this comment

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

Given we make _dd_ext_curl_loaded atomic, would having a one-time RINIT feature achieve this same functionality without having to run as a Zend extension hybrid?

Copy link
Collaborator Author

@morrisonlevi morrisonlevi Apr 8, 2020

Choose a reason for hiding this comment

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

No. The handlers must be overwritten in startup/minit -- rinit is too late. Doing it in minit will not work reliably if the extension we want to change the handlers for is loaded as a shared object, because then we have possible load order issues.

In other words, it's only safe in startup and minit and minit is too early. I think startup is literally the only place we can do this safely.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see why doing it in MINIT is too early, but what makes RINIT too late? Doing it for every RINIT doesn't make sense, but doing it in a one-time RINIT would allow us to avoid running as a zend extension hybrid, no? Is there something that makes it unsafe to do in RINIT at all?

I guess ultimately my concern is really about converting to a zend extension hybrid which in my opinion has more unknowns in terms of side effects versus a one-time RINIT feature. But if that's our only option, let's definitely do some nice-neighbor framework testing. :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Replacing an internal function handler in RINIT would only be safe for NTS builds, and I seem to remember a conversation in Stack Overflow PHP chat about how it may not be valid at all with JIT -- I'll try to dig that up.

Doing it in zend_extension startup should always be safe.

PHP_RSHUTDOWN(ddtrace),
PHP_MINFO(ddtrace),
PHP_DDTRACE_VERSION,
PHP_MODULE_GLOBALS(ddtrace),
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

src/ext/php7/curl_handlers.c Outdated Show resolved Hide resolved
src/ext/php7/curl_handlers.c Outdated Show resolved Hide resolved
_dd_curl_close_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}

static void _dd_instrument_curl_close(void) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused by this function name as it mentions instrumentation but I don't see any instrumentation logic. I'm guessing this is just a hook for the custom handler?

Same goes for _dd_instrument_curl_copy_handle(), _dd_instrument_curl_exec(), _dd_instrument_curl_setopt(), and _dd_instrument_curl_setopt_array() below. :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This series of functions overrides the internal function handlers -- I could change "instrument" to "install"?


zval *curl_var = zend_call_method_with_0_params(NULL, NULL, NULL, "curl_init", &retval);
if (curl_var && Z_TYPE_P(curl_var) == IS_RESOURCE) {
le_curl = Z_RES_P(curl_var)->type;
Copy link
Contributor

Choose a reason for hiding this comment

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

Clever! 🔝 #SneakySneaks

package.xml Outdated Show resolved Hide resolved
If we expand this technique to other extensions (like PDO),
then the files will be next to each other for convenience.
@morrisonlevi morrisonlevi marked this pull request as ready for review April 9, 2020 08:12
Copy link
Contributor

@SammyK SammyK left a comment

Choose a reason for hiding this comment

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

Nicely done. This just needs, milestone, labels, and changelog, but other than that it's good to go. Solid work @morrisonlevi!

@morrisonlevi morrisonlevi added c-extension Apply this label to issues and prs related to the C-extension 🎉 new-integration A new integration labels Apr 9, 2020
@morrisonlevi morrisonlevi added this to the 0.43.0 milestone Apr 10, 2020
@morrisonlevi
Copy link
Collaborator Author

Everything still look good after testing on the nice-neighbor framework and also running a build- branch -- going to merge it in.

@morrisonlevi morrisonlevi merged commit c690c04 into master Apr 10, 2020
@morrisonlevi morrisonlevi deleted the levi/curl branch April 10, 2020 16:19
@SammyK SammyK mentioned this pull request Jun 4, 2020
5 tasks
@SammyK SammyK mentioned this pull request Jul 27, 2020
5 tasks
bwoebi added a commit that referenced this pull request Jan 6, 2025
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
Add SSRF Rasp capability (#814)
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
bwoebi added a commit that referenced this pull request Jan 6, 2025
…og changes (#3005)

* refactor: add feature_flag to Cargo.toml according to libdatadog changes

* change reference to libdatadog

* Make cbindgen

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

* Bump the minimum rust version to 1.78

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

* test: fix prof asan nightly version

* Avoid undefined symbol errors in test run

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
Add SSRF Rasp capability (#814)
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>

---------

Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
Co-authored-by: Bob Weinand <bob.weinand@datadoghq.com>
Co-authored-by: Levi Morrison <levi.morrison@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-extension Apply this label to issues and prs related to the C-extension 🎉 new-integration A new integration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants