Skip to content

Commit a23327c

Browse files
committed
Merge branch 'main' into HEAD
2 parents 4aa0a8e + 84ea3a9 commit a23327c

File tree

123 files changed

+1506
-603
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+1506
-603
lines changed

cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected

+43
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ edges
1212
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | provenance | |
1313
| test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | provenance | |
1414
| test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | provenance | |
15+
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:322:12:322:12 | a | provenance | |
16+
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:344:12:344:24 | *access to array [ptr] | provenance | |
17+
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:345:12:345:24 | *access to array [ptr] | provenance | |
18+
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
19+
| test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | provenance | |
20+
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | test_free.cpp:345:12:345:24 | *access to array [ptr] | provenance | |
21+
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
22+
| test_free.cpp:344:12:344:24 | *access to array [ptr] | test_free.cpp:344:26:344:28 | ptr | provenance | |
23+
| test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | provenance | |
24+
| test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | test_free.cpp:346:12:346:24 | *access to array [ptr] | provenance | |
25+
| test_free.cpp:345:12:345:24 | *access to array [ptr] | test_free.cpp:345:26:345:28 | ptr | provenance | |
26+
| test_free.cpp:345:12:345:24 | *access to array [ptr] | test_free.cpp:345:26:345:28 | ptr | provenance | |
27+
| test_free.cpp:345:26:345:28 | pointer to operator delete output argument | test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | provenance | |
28+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
29+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
30+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | test_free.cpp:346:26:346:28 | ptr | provenance | |
1531
nodes
1632
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
1733
| test_free.cpp:14:10:14:10 | a | semmle.label | a |
@@ -39,6 +55,26 @@ nodes
3955
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
4056
| test_free.cpp:301:12:301:14 | pointer to g_free output argument | semmle.label | pointer to g_free output argument |
4157
| test_free.cpp:302:12:302:14 | buf | semmle.label | buf |
58+
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
59+
| test_free.cpp:322:12:322:12 | a | semmle.label | a |
60+
| test_free.cpp:343:12:343:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
61+
| test_free.cpp:343:26:343:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
62+
| test_free.cpp:344:12:344:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
63+
| test_free.cpp:344:12:344:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
64+
| test_free.cpp:344:26:344:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
65+
| test_free.cpp:344:26:344:28 | ptr | semmle.label | ptr |
66+
| test_free.cpp:345:12:345:24 | *access to array [post update] [ptr] | semmle.label | *access to array [post update] [ptr] |
67+
| test_free.cpp:345:12:345:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
68+
| test_free.cpp:345:12:345:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
69+
| test_free.cpp:345:26:345:28 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
70+
| test_free.cpp:345:26:345:28 | ptr | semmle.label | ptr |
71+
| test_free.cpp:345:26:345:28 | ptr | semmle.label | ptr |
72+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
73+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
74+
| test_free.cpp:346:12:346:24 | *access to array [ptr] | semmle.label | *access to array [ptr] |
75+
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
76+
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
77+
| test_free.cpp:346:26:346:28 | ptr | semmle.label | ptr |
4278
subpaths
4379
#select
4480
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:14:10:14:10 | a | a | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -54,3 +90,10 @@ subpaths
5490
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:154:10:154:10 | a | a | test_free.cpp:152:22:152:25 | call to free | call to free |
5591
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:209:10:209:10 | a | a | test_free.cpp:207:5:207:8 | call to free | call to free |
5692
| test_free.cpp:302:12:302:14 | buf | test_free.cpp:301:12:301:14 | pointer to g_free output argument | test_free.cpp:302:12:302:14 | buf | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:302:12:302:14 | buf | buf | test_free.cpp:301:5:301:10 | call to g_free | call to g_free |
93+
| test_free.cpp:322:12:322:12 | a | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:322:12:322:12 | a | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:322:12:322:12 | a | a | test_free.cpp:319:9:319:16 | delete | delete |
94+
| test_free.cpp:344:26:344:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:344:26:344:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:344:26:344:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
95+
| test_free.cpp:345:26:345:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:345:26:345:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:345:26:345:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
96+
| test_free.cpp:345:26:345:28 | ptr | test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:345:26:345:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:345:26:345:28 | ptr | ptr | test_free.cpp:344:5:344:28 | delete | delete |
97+
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:343:26:343:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:343:5:343:28 | delete | delete |
98+
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:344:26:344:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:344:5:344:28 | delete | delete |
99+
| test_free.cpp:346:26:346:28 | ptr | test_free.cpp:345:26:345:28 | pointer to operator delete output argument | test_free.cpp:346:26:346:28 | ptr | Memory pointed to by $@ may already have been freed by $@. | test_free.cpp:346:26:346:28 | ptr | ptr | test_free.cpp:345:5:345:28 | delete | delete |

cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected

+9
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@
104104
| test_free.cpp:293:8:293:10 | buf |
105105
| test_free.cpp:301:12:301:14 | buf |
106106
| test_free.cpp:302:12:302:14 | buf |
107+
| test_free.cpp:313:16:313:16 | a |
108+
| test_free.cpp:319:16:319:16 | a |
109+
| test_free.cpp:322:12:322:12 | a |
110+
| test_free.cpp:331:12:331:12 | a |
111+
| test_free.cpp:335:12:335:12 | a |
112+
| test_free.cpp:343:26:343:28 | ptr |
113+
| test_free.cpp:344:26:344:28 | ptr |
114+
| test_free.cpp:345:26:345:28 | ptr |
115+
| test_free.cpp:346:26:346:28 | ptr |
107116
| virtual.cpp:18:10:18:10 | a |
108117
| virtual.cpp:19:10:19:10 | c |
109118
| virtual.cpp:38:10:38:10 | b |

cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected

+19
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ edges
2525
| test_free.cpp:294:3:294:3 | *s [post update] [buf] | test_free.cpp:295:12:295:12 | *s [buf] | provenance | |
2626
| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:3:294:3 | *s [post update] [buf] | provenance | |
2727
| test_free.cpp:295:12:295:12 | *s [buf] | test_free.cpp:295:14:295:16 | buf | provenance | |
28+
| test_free.cpp:313:16:313:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
29+
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:321:5:321:6 | * ... | provenance | |
30+
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
31+
| test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
32+
| test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | provenance | |
2833
nodes
2934
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
3035
| test_free.cpp:12:5:12:5 | a | semmle.label | a |
@@ -66,6 +71,15 @@ nodes
6671
| test_free.cpp:294:3:294:13 | ... = ... | semmle.label | ... = ... |
6772
| test_free.cpp:295:12:295:12 | *s [buf] | semmle.label | *s [buf] |
6873
| test_free.cpp:295:14:295:16 | buf | semmle.label | buf |
74+
| test_free.cpp:313:16:313:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
75+
| test_free.cpp:319:16:319:16 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
76+
| test_free.cpp:321:5:321:6 | * ... | semmle.label | * ... |
77+
| test_free.cpp:322:12:322:12 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
78+
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
79+
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
80+
| test_free.cpp:324:5:324:6 | * ... | semmle.label | * ... |
81+
| test_free.cpp:331:12:331:12 | pointer to operator delete output argument | semmle.label | pointer to operator delete output argument |
82+
| test_free.cpp:332:5:332:6 | * ... | semmle.label | * ... |
6983
subpaths
7084
#select
7185
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -84,3 +98,8 @@ subpaths
8498
| test_free.cpp:278:15:278:17 | buf | test_free.cpp:277:8:277:13 | pointer to free output argument | test_free.cpp:278:15:278:17 | buf | Memory may have been previously freed by $@. | test_free.cpp:277:3:277:6 | call to free | call to free |
8599
| test_free.cpp:283:14:283:16 | buf | test_free.cpp:282:8:282:12 | pointer to free output argument | test_free.cpp:283:14:283:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:282:3:282:6 | call to free | call to free |
86100
| test_free.cpp:295:14:295:16 | buf | test_free.cpp:293:8:293:10 | pointer to free output argument | test_free.cpp:295:14:295:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:293:3:293:6 | call to free | call to free |
101+
| test_free.cpp:321:5:321:6 | * ... | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:321:5:321:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:319:9:319:16 | delete | delete |
102+
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:313:16:313:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:313:9:313:16 | delete | delete |
103+
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:319:16:319:16 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:319:9:319:16 | delete | delete |
104+
| test_free.cpp:324:5:324:6 | * ... | test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:322:5:322:12 | delete | delete |
105+
| test_free.cpp:332:5:332:6 | * ... | test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:331:5:331:12 | delete | delete |

cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp

+47-3
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ void test_ref_delete(int *&p) {
264264
}
265265

266266
void test_free_assign() {
267-
void *a = malloc(10);
267+
void *a = malloc(10);
268268
void *b;
269-
free(b = a); // GOOD
269+
free(b = a); // GOOD
270270
}
271271

272272
struct MyStruct {
@@ -300,4 +300,48 @@ void g_free (void*);
300300
void test_g_free(char* buf) {
301301
g_free(buf);
302302
g_free(buf); // BAD
303-
}
303+
}
304+
305+
// inspired by real world FPs
306+
307+
void test_goto() {
308+
int *a = (int *)malloc(sizeof(int));
309+
310+
*a = 1; // GOOD
311+
if (condition())
312+
{
313+
delete a;
314+
goto after;
315+
}
316+
*a = 1; // GOOD
317+
if (condition())
318+
{
319+
delete a;
320+
}
321+
*a = 1; // BAD (use after free)
322+
delete a; // BAD (double free)
323+
after:
324+
*a = 1; // BAD (use after free)
325+
}
326+
327+
void test_reassign() {
328+
int *a = (int *)malloc(sizeof(int));
329+
330+
*a = 1; // GOOD
331+
delete a;
332+
*a = 1; // BAD (use after free)
333+
a = (int *)malloc(sizeof(int));
334+
*a = 1; // GOOD
335+
delete a;
336+
}
337+
338+
struct PtrContainer {
339+
int *ptr;
340+
};
341+
342+
void test_array(PtrContainer *containers) {
343+
delete containers[0].ptr; // GOOD
344+
delete containers[1].ptr; // GOOD [FALSE POSITIVE]
345+
delete containers[2].ptr; // GOOD [FALSE POSITIVE]
346+
delete containers[2].ptr; // BAD (double free)
347+
}

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs

+13-35
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ void exitCallback(int ret, string msg, bool silent)
152152
var sourceGenerators = new ISourceGenerator[]
153153
{
154154
new ImplicitUsingsGenerator(fileContent, logger, tempWorkingDirectory),
155-
new WebViewGenerator(fileProvider, fileContent, dotnet, this, logger, tempWorkingDirectory, usedReferences.Keys)
155+
new RazorGenerator(fileProvider, fileContent, dotnet, this, logger, tempWorkingDirectory, usedReferences.Keys),
156+
new ResxGenerator(fileProvider, fileContent, dotnet, this, logger, nugetPackageRestorer, tempWorkingDirectory, usedReferences.Keys),
156157
};
157158

158159
foreach (var sourceGenerator in sourceGenerators)
@@ -255,35 +256,6 @@ private void RemoveNugetAnalyzerReferences()
255256
}
256257
}
257258

258-
private void SelectNewestFrameworkPath(string frameworkPath, string frameworkType, ISet<AssemblyLookupLocation> dllLocations, ISet<string> frameworkLocations)
259-
{
260-
var versionFolders = GetPackageVersionSubDirectories(frameworkPath);
261-
if (versionFolders.Length > 1)
262-
{
263-
var versions = string.Join(", ", versionFolders.Select(d => d.Name));
264-
logger.LogDebug($"Found multiple {frameworkType} DLLs in NuGet packages at {frameworkPath}. Using the latest version ({versionFolders[0].Name}) from: {versions}.");
265-
}
266-
267-
var selectedFrameworkFolder = versionFolders.FirstOrDefault()?.FullName;
268-
if (selectedFrameworkFolder is null)
269-
{
270-
logger.LogDebug($"Found {frameworkType} DLLs in NuGet packages at {frameworkPath}, but no version folder was found.");
271-
selectedFrameworkFolder = frameworkPath;
272-
}
273-
274-
dllLocations.Add(selectedFrameworkFolder);
275-
frameworkLocations.Add(selectedFrameworkFolder);
276-
logger.LogDebug($"Found {frameworkType} DLLs in NuGet packages at {selectedFrameworkFolder}.");
277-
}
278-
279-
private static DirectoryInfo[] GetPackageVersionSubDirectories(string packagePath)
280-
{
281-
return new DirectoryInfo(packagePath)
282-
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
283-
.OrderByDescending(d => d.Name) // TODO: Improve sorting to handle pre-release versions.
284-
.ToArray();
285-
}
286-
287259
private void RemoveFrameworkNugetPackages(ISet<AssemblyLookupLocation> dllLocations, int fromIndex = 0)
288260
{
289261
var packagesInPrioOrder = FrameworkPackageNames.NetFrameworks;
@@ -310,10 +282,12 @@ private void AddNetFrameworkDlls(ISet<AssemblyLookupLocation> dllLocations, ISet
310282
{
311283
foreach (var fp in frameworkPaths)
312284
{
313-
dotnetFrameworkVersionVariantCount += GetPackageVersionSubDirectories(fp.Path!).Length;
285+
dotnetFrameworkVersionVariantCount += NugetPackageRestorer.GetOrderedPackageVersionSubDirectories(fp.Path!).Length;
314286
}
315287

316-
SelectNewestFrameworkPath(frameworkPath.Path, ".NET Framework", dllLocations, frameworkLocations);
288+
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(frameworkPath.Path, ".NET Framework");
289+
dllLocations.Add(folder);
290+
frameworkLocations.Add(folder);
317291
RemoveFrameworkNugetPackages(dllLocations, frameworkPath.Index + 1);
318292
return;
319293
}
@@ -331,7 +305,7 @@ private void AddNetFrameworkDlls(ISet<AssemblyLookupLocation> dllLocations, ISet
331305
if (runtimeLocation is null)
332306
{
333307
logger.LogInfo("No .NET Desktop Runtime location found. Attempting to restore the .NET Framework reference assemblies manually.");
334-
runtimeLocation = nugetPackageRestorer.TryRestoreLatestNetFrameworkReferenceAssemblies();
308+
runtimeLocation = nugetPackageRestorer.TryRestore(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies);
335309
}
336310
}
337311

@@ -371,7 +345,9 @@ private void AddAspNetCoreFrameworkDlls(ISet<AssemblyLookupLocation> dllLocation
371345
// First try to find ASP.NET Core assemblies in the NuGet packages
372346
if (GetPackageDirectory(FrameworkPackageNames.AspNetCoreFramework) is string aspNetCorePackage)
373347
{
374-
SelectNewestFrameworkPath(aspNetCorePackage, "ASP.NET Core", dllLocations, frameworkLocations);
348+
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(aspNetCorePackage, "ASP.NET Core");
349+
dllLocations.Add(folder);
350+
frameworkLocations.Add(folder);
375351
return;
376352
}
377353

@@ -387,7 +363,9 @@ private void AddMicrosoftWindowsDesktopDlls(ISet<AssemblyLookupLocation> dllLoca
387363
{
388364
if (GetPackageDirectory(FrameworkPackageNames.WindowsDesktopFramework) is string windowsDesktopApp)
389365
{
390-
SelectNewestFrameworkPath(windowsDesktopApp, "Windows Desktop App", dllLocations, frameworkLocations);
366+
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(windowsDesktopApp, "Windows Desktop App");
367+
dllLocations.Add(folder);
368+
frameworkLocations.Add(folder);
391369
}
392370
}
393371

0 commit comments

Comments
 (0)