Skip to content

Fix use-after-free on substituting function type involving conditional ~Escapable with Escapable type #81678

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

meg-gupta
Copy link
Contributor

@meg-gupta meg-gupta commented May 21, 2025

While type substituting a conditionally ~Escapable type with an Escapable type, we have to drop lifetime dependencies from the function type. The newly constructed lifetime dependencies after dropping substituted dependencies was from a temporary whose lifetime is shorter than needed. Allocate it on the ASTContext like all other instances.

Fixes rdar://151769354

@meg-gupta
Copy link
Contributor Author

@swift-ci test

@meg-gupta
Copy link
Contributor Author

@swift-ci test

@@ -939,7 +940,8 @@ case TypeKind::Id:
});

if (didRemoveLifetimeDependencies) {
extInfo = extInfo->withLifetimeDependencies(substDependenceInfos);
extInfo = extInfo->withLifetimeDependencies(
ctx.AllocateCopy(substDependenceInfos));
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it's best to sink the AllocateCopy down into withLifetimeDependencies()

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there some rule for when withLifetimeDependencies needs its own allocation? Could that at least be commented in the API?

We call this in several other places and I don't know which need an allocation and which don't. e.g.
SILFunctionType::getSubstLifetimeDependencies

Copy link
Contributor

Choose a reason for hiding this comment

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

It needs its own allocation if the LifetimeDependencies that you pass in are themselves not in the global AST context arena. It's safest to move the AllocateCopy into withLifetimeDependencies() itself, so that callers don't have to worry about creating an ExtInfo with a dangling pointer in it.

Copy link
Contributor Author

@meg-gupta meg-gupta May 21, 2025

Choose a reason for hiding this comment

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

I did not originally want to do this because withLifetimeDependencies is called from places with an already arena allocated pointer as the input arg, and proactively allocating within it would not allow sharing.

Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps the LifetimeDependencies objects should always be allocated and uniqued by the ASTContext then, so you'll pass them around by pointer and the pointer will always have global extent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was hoping to use something akin to llvm::BumpPtrAllocatorImpl::identifyObject to ensure the passed input arg is safe in assert builds. Not everything is plumbed through to try that out.

I added a C++ delete overload for withLifetimeDependencies when input argument is SmallVectorImpl for now.

Copy link
Contributor Author

@meg-gupta meg-gupta May 21, 2025

Choose a reason for hiding this comment

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

perhaps the LifetimeDependencies objects should always be allocated and uniqued by the ASTContext then

@slavapestov This sounds promising. But maybe a big refactor for release/6.2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I created rdar://151811669 (LifetimeDependencies objects should always be allocated and uniqued by the ASTContext)

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

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

LGTM. I think uniquing the lifetime dependence allocation in the AST context is important but separable.

@meg-gupta
Copy link
Contributor Author

@swift-ci test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants