aws-sdk-cpp icon indicating copy to clipboard operation
aws-sdk-cpp copied to clipboard

Fix crashes in S3 CRT GetObjectAsync / PutObjectAsync

Open grrtrr opened this issue 3 years ago • 0 comments

This fixes undefined behaviour in Get/PutObjecAsync which results in crashes and program termination.

Issue #, if available: Resolves #1655.

Description of changes:

The Get/PutObjectAsync methods use const-references to std::function as callbacks:

typedef std::function<void(const S3CrtClient*, const Model::GetObjectRequest&, Model::GetObjectOutcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext>&) > GetObjectResponseReceivedHandler;
typedef std::function<void(const S3CrtClient*, const Model::PutObjectRequest&, const Model::PutObjectOutcome&, const std::shared_ptr<const Aws::Client::AsyncCallerContext>&) > PutObjectResponseReceivedHandler;

void S3CrtClient::GetObjectAsync(const GetObjectRequest& request, const GetObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context) const;
void S3CrtClient::PutObjectAsync(const PutObjectRequest& request, const PutObjectResponseReceivedHandler& handler, const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context) const;

The address of these const references is taken and later dereferenced (the PutObjectAsync path is similar):

// S3Client.h:
        struct CrtRequestCallbackUserData {
          const S3CrtClient *s3CrtClient;
          const void *userCallback;  // <== HERE
          // ...
   };

// S3CrtClient.cpp:
  CrtRequestCallbackUserData *userData = Aws::New<CrtRequestCallbackUserData>(ALLOCATION_TAG);
  // ...
  userData->userCallback = static_cast<const void*>(&handler);

By the time the userCallback is executed within GetObjectRequestShutdownCallback, the handler object is out of scope, since the GetObjectAsync function returns quickly. The address now points to a destructed std::function object.

Fix

Rather than taking the address of a (temporary) object and risk its destruction, copy-construct the handlers within CrtRequestCallbackUserData to ensure that the required std::function objects are still alive when the shutdown callbacks get called.

Check all that applies:

  • [X] Did a review by yourself.
  • [X] Added proper tests to cover this PR. (If tests are not applicable, explain.) Tested behaviour manually, using the code in #1655 and a similar local application. Please see below for more details.
  • [X] Checked if this PR is a breaking (APIs have been changed) change.
  • [X] Checked if this PR will not introduce cross-platform inconsistent behavior.
  • [X] Checked if this PR would require a ReadMe/Wiki update.

Check which platforms you have built SDK on to verify the correctness of this PR.

  • [X] Linux
  • [ ] Windows
  • [ ] Android
  • [ ] MacOS
  • [ ] IOS
  • [ ] Other Platforms

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

grrtrr avatar Jan 29 '22 15:01 grrtrr