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

[clang] Prevent dangling StringRefs #98699

Merged
merged 2 commits into from
Jul 16, 2024
Merged

[clang] Prevent dangling StringRefs #98699

merged 2 commits into from
Jul 16, 2024

Conversation

JOE1994
Copy link
Member

@JOE1994 JOE1994 commented Jul 12, 2024

Fix locations where dangling StringRefs are created.

  • ConstraintSatisfaction::SubstitutionDiagnostic: typedef of std::pair<SourceLocation, StringRef>

  • concepts::Requirement::SubstitutionDiagnostic: struct whose 1st and 3rd data members are StringRefs

Fixes #98667

@JOE1994 JOE1994 requested a review from ahatanak July 12, 2024 22:58
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:modules C++20 modules and Clang Header Modules labels Jul 12, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-clang

Author: Youngsuk Kim (JOE1994)

Changes

Fix locations where dangling StringRefs are created.

  • ConstraintSatisfaction::SubstitutionDiagnostic: typedef of std::pair&lt;SourceLocation, StringRef&gt;

  • concepts::Requirement::SubstitutionDiagnostic: struct whose 1st and 3rd data members are StringRefs

Fixes #98667


Full diff: https://github.com/llvm/llvm-project/pull/98699.diff

1 Files Affected:

  • (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+16-5)
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 5a5d7be69a2c3..ecbc57d642ca7 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -797,10 +797,14 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
       if (/* IsDiagnostic */Record.readInt()) {
         SourceLocation DiagLocation = Record.readSourceLocation();
         std::string DiagMessage = Record.readString();
+        char *DBuf = new (Record.getContext()) char[DiagMessage.size()];
+        std::copy(DiagMessage.begin(), DiagMessage.end(), DBuf);
+
         Satisfaction.Details.emplace_back(
-            ConstraintExpr, new (Record.getContext())
-                                ConstraintSatisfaction::SubstitutionDiagnostic{
-                                    DiagLocation, DiagMessage});
+            ConstraintExpr,
+            new (Record.getContext())
+                ConstraintSatisfaction::SubstitutionDiagnostic{
+                    DiagLocation, StringRef(DBuf, DiagMessage.size())});
       } else
         Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr());
     }
@@ -822,11 +826,18 @@ void ASTStmtReader::VisitConceptSpecializationExpr(
 static concepts::Requirement::SubstitutionDiagnostic *
 readSubstitutionDiagnostic(ASTRecordReader &Record) {
   std::string SubstitutedEntity = Record.readString();
+  char *SBuf = new (Record.getContext()) char[SubstitutedEntity.size()];
+  std::copy(SubstitutedEntity.begin(), SubstitutedEntity.end(), SBuf);
+
   SourceLocation DiagLoc = Record.readSourceLocation();
   std::string DiagMessage = Record.readString();
+  char *DBuf = new (Record.getContext()) char[DiagMessage.size()];
+  std::copy(DiagMessage.begin(), DiagMessage.end(), DBuf);
+
   return new (Record.getContext())
-      concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
-                                                    DiagMessage};
+      concepts::Requirement::SubstitutionDiagnostic{
+          StringRef(SBuf, SubstitutedEntity.size()), DiagLoc,
+          StringRef(DBuf, DiagMessage.size())};
 }
 
 void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-clang-modules

Author: Youngsuk Kim (JOE1994)

Changes

Fix locations where dangling StringRefs are created.

  • ConstraintSatisfaction::SubstitutionDiagnostic: typedef of std::pair&lt;SourceLocation, StringRef&gt;

  • concepts::Requirement::SubstitutionDiagnostic: struct whose 1st and 3rd data members are StringRefs

Fixes #98667


Full diff: https://github.com/llvm/llvm-project/pull/98699.diff

1 Files Affected:

  • (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+16-5)
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 5a5d7be69a2c3..ecbc57d642ca7 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -797,10 +797,14 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
       if (/* IsDiagnostic */Record.readInt()) {
         SourceLocation DiagLocation = Record.readSourceLocation();
         std::string DiagMessage = Record.readString();
+        char *DBuf = new (Record.getContext()) char[DiagMessage.size()];
+        std::copy(DiagMessage.begin(), DiagMessage.end(), DBuf);
+
         Satisfaction.Details.emplace_back(
-            ConstraintExpr, new (Record.getContext())
-                                ConstraintSatisfaction::SubstitutionDiagnostic{
-                                    DiagLocation, DiagMessage});
+            ConstraintExpr,
+            new (Record.getContext())
+                ConstraintSatisfaction::SubstitutionDiagnostic{
+                    DiagLocation, StringRef(DBuf, DiagMessage.size())});
       } else
         Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr());
     }
@@ -822,11 +826,18 @@ void ASTStmtReader::VisitConceptSpecializationExpr(
 static concepts::Requirement::SubstitutionDiagnostic *
 readSubstitutionDiagnostic(ASTRecordReader &Record) {
   std::string SubstitutedEntity = Record.readString();
+  char *SBuf = new (Record.getContext()) char[SubstitutedEntity.size()];
+  std::copy(SubstitutedEntity.begin(), SubstitutedEntity.end(), SBuf);
+
   SourceLocation DiagLoc = Record.readSourceLocation();
   std::string DiagMessage = Record.readString();
+  char *DBuf = new (Record.getContext()) char[DiagMessage.size()];
+  std::copy(DiagMessage.begin(), DiagMessage.end(), DBuf);
+
   return new (Record.getContext())
-      concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
-                                                    DiagMessage};
+      concepts::Requirement::SubstitutionDiagnostic{
+          StringRef(SBuf, SubstitutedEntity.size()), DiagLoc,
+          StringRef(DBuf, DiagMessage.size())};
 }
 
 void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {

Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

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

LGTM.

If it does fix the mentioned issue, please add a release note.

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

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

It looks like we are using the same pattern that fix is using in ASTStmtReader::VisitRequiresExpr which gives me some comfort but I am not happy that we have a relatively complex and easy to get wrong operation repeated in three places now. This feel like it should be refactored into common code and if we find a bug w/ it later on fixing it one place will fix all the places.

Fix locations where dangling StringRefs are created.

* `ConstraintSatisfaction::SubstitutionDiagnostic`:
   typedef of `std::pair<SourceLocation, StringRef>`

* `concepts::Requirement::SubstitutionDiagnostic`:
   struct whose 1st and 3rd data members are `StringRef`s

Fixes llvm#98667
@JOE1994 JOE1994 requested a review from shafik July 13, 2024 15:48
@JOE1994 JOE1994 merged commit 55c8fd9 into llvm:main Jul 16, 2024
8 checks passed
@JOE1994 JOE1994 deleted the clang_cleanup branch July 16, 2024 13:45
Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

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

This LGTM but when someone blocks (requests changes) you should wait for approval from them before landing the change.

sayhaan pushed a commit to sayhaan/llvm-project that referenced this pull request Jul 16, 2024
Summary:
Fix locations where dangling StringRefs are created.

* `ConstraintSatisfaction::SubstitutionDiagnostic`: typedef of
`std::pair<SourceLocation, StringRef>`

* `concepts::Requirement::SubstitutionDiagnostic`: struct whose 1st and
3rd data members are `StringRef`s

Fixes llvm#98667

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D59822407
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
Fix locations where dangling StringRefs are created.

* `ConstraintSatisfaction::SubstitutionDiagnostic`: typedef of
`std::pair<SourceLocation, StringRef>`

* `concepts::Requirement::SubstitutionDiagnostic`: struct whose 1st and
3rd data members are `StringRef`s

Fixes #98667

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251531
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Possible use-after-free in readConstraintSatisfaction
4 participants