+
+
+Using an iterator owned by a container after the lifetime of the container has expired can lead to undefined behavior.
+This is because the iterator may be invalidated when the container is destroyed, and dereferencing an invalidated iterator is undefined behavior.
+These problems can be hard to spot due to C++'s complex rules for temporary object lifetimes and their extensions.
+
+
+
+
+
+
+Never create an iterator to a temporary container when the iterator is expected to be used after the container's lifetime has expired.
+
+
+
+
+
+
+
+
+
+The rules for lifetime extension ensures that the code in lifetime_of_temp_extended
is well-defined. This is because the
+lifetime of the temporary container returned by get_vector
is extended to the end of the loop. However, prior to C++23,
+the lifetime extension rules do not ensure that the container returned by get_vector
is extended in lifetime_of_temp_not_extended
.
+This is because the temporary container is not bound to a rvalue reference.
+
+
+
+
+
+
+CERT C Coding Standard:
+MEM30-C. Do not access freed memory.
+
+OWASP:
+Using freed memory.
+
+
+Lifetime safety: Preventing common dangling
+
+
+Containers library
+
+
+Range-based for loop (since C++11)
+
+
+
+
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
new file mode 100644
index 000000000000..15f34aa8d151
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
@@ -0,0 +1,103 @@
+/**
+ * @name Iterator to expired container
+ * @description Using an iterator owned by a container whose lifetime has expired may lead to unexpected behavior.
+ * @kind problem
+ * @precision high
+ * @id cpp/iterator-to-expired-container
+ * @problem.severity warning
+ * @tags reliability
+ * security
+ * external/cwe/cwe-416
+ * external/cwe/cwe-664
+ */
+
+// IMPORTANT: This query does not currently find anything since it relies on extractor and analysis improvements that hasn't yet been released
+import cpp
+import semmle.code.cpp.ir.IR
+import semmle.code.cpp.dataflow.new.DataFlow
+import semmle.code.cpp.models.implementations.StdContainer
+import semmle.code.cpp.models.implementations.StdMap
+import semmle.code.cpp.models.implementations.Iterator
+
+/**
+ * A configuration to track flow from a temporary variable to the qualifier of
+ * a destructor call
+ */
+module TempToDestructorConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) {
+ source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable
+ }
+
+ predicate isSink(DataFlow::Node sink) {
+ sink.asOperand().(ThisArgumentOperand).getCall().getStaticCallTarget() instanceof Destructor
+ }
+}
+
+module TempToDestructorFlow = DataFlow::Global