From 0147b7bdaa075c601607695367bca7735d9b9e43 Mon Sep 17 00:00:00 2001
From: Pierrick Philippe <pierrick.philippe@irisa.fr>
Date: Wed, 24 Apr 2024 13:29:01 +0200
Subject: [PATCH] Global vars handled + output of the problem not using svalue
 anymore (by using get_default_state(region *))

---
 README.md              |  4 ++--
 inc/crypto_taint_sm.h  |  2 +-
 inc/utils.h            |  6 ++++++
 src/attribute.cc       |  2 +-
 src/crypto_taint_sm.cc | 44 +++++++++++++++++++++++++++++++++++++++---
 src/utils.cc           | 18 +++++++++++++++++
 6 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index a27a80c..d9a924d 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@ __analyzer_break()
 
 TODO:
 - return stmt => DONE
-- global vars
-- loop (FREE) => maximum 7 iterations avec l'analyzer
+- global vars => DONE
+- loop (FREE) => maximum 7 iterations avec l'analyzer => DONE
 - pensez au benchmark des tools
 - function hooks
   - toml/yaml load a l'init
diff --git a/inc/crypto_taint_sm.h b/inc/crypto_taint_sm.h
index faab6f8..10fa916 100644
--- a/inc/crypto_taint_sm.h
+++ b/inc/crypto_taint_sm.h
@@ -29,7 +29,7 @@ namespace crypto_taint {
             /* A vfunc for more general handling of inheritance.  */
             virtual state_t alt_get_inherited_state (const sm_state_map &, const svalue *, const extrinsic_state &) const final override;
 
-            virtual state_machine::state_t get_default_state (const svalue *) const final override;
+            virtual state_machine::state_t get_default_state (const region *) const final override;
 
             /* Return true if STMT is a function call recognized by this sm.  */
             virtual bool on_stmt (sm_context *, const supernode *, const gimple *) const final override;
diff --git a/inc/utils.h b/inc/utils.h
index 1bd51d7..eac429d 100644
--- a/inc/utils.h
+++ b/inc/utils.h
@@ -60,6 +60,12 @@ namespace utils {
         NULL_TREE otherwise.*/
     tree is_ssa_name_from_component_ref(tree);
 
+    /* This function check if a given tree is a SSA_NAME, and if so,
+        check whether it's been initialized from a global VAR_DECL.
+        Return that global VAR_DECL in that case,
+        NULL_TREE otherwise.*/
+    tree is_ssa_name_from_global_var_decl(tree);
+
     /* This function check if a given tree is a SSA_NAME, and if so,
         check whether it's been initialized from a ARRAY_REF.
         Return that ARRAY_REF in that case,
diff --git a/src/attribute.cc b/src/attribute.cc
index 066a240..b6a2f57 100644
--- a/src/attribute.cc
+++ b/src/attribute.cc
@@ -68,7 +68,7 @@ void register_attributes(void* event_data, void* data) {
 
 bool has_tainted_attribute(tree t, auto_vec<tree> &v) {
    if(t && !v.contains(t)
-         && DECL_P(t) 
+         && DECL_P(t)
          && lookup_attribute("taint", DECL_ATTRIBUTES(t))) {
       v.safe_push(t);
       auto ctx = DECL_CONTEXT(t) ? ::get_name(DECL_CONTEXT(t)) : "<no_ctx>";
diff --git a/src/crypto_taint_sm.cc b/src/crypto_taint_sm.cc
index aa6ed51..3c4efd6 100644
--- a/src/crypto_taint_sm.cc
+++ b/src/crypto_taint_sm.cc
@@ -78,9 +78,35 @@ namespace crypto_taint {
         return this->m_start;
     }
 
-    state_machine::state_t crypto_taint_state_machine::get_default_state (const svalue * sval) const
+    state_machine::state_t crypto_taint_state_machine::get_default_state (const region *reg) const
     {
-        return this->m_start;
+        auto logger = this->get_logger();
+        LOG_SCOPE(logger);
+
+        auto mutable_this = const_cast<crypto_taint_state_machine *>(this);
+        auto has_attribute = false;
+
+        if (logger) {
+            auto pp = logger->get_printer();
+            logger->start_log_line();
+            logger->log_partial("reg: ");
+            reg->dump_to_pp(pp, false);
+        }
+
+        if (tree t = reg->maybe_get_decl()) {
+            has_attribute = has_tainted_attribute(t, mutable_this->m_tainted_vars);
+            if (logger) {
+                auto pp = logger->get_printer();
+                logger->log_partial(" | t: ");
+                dump_quoted_tree(pp, t);
+                logger->log_partial(" | attribute: %s", has_attribute ? "true" : "false");
+            }
+        }
+
+        if (logger)
+            logger->end_log_line();
+            
+        return has_attribute ? this->m_tainted : this->m_start;
     }
 
     bool crypto_taint_state_machine::on_stmt (sm_context *sm_ctx, const supernode *node, const gimple * stmt) const {
@@ -374,11 +400,17 @@ namespace crypto_taint {
                     make_unique<constant_time_diagnostic>(*this, sm_ctx->get_diagnostic_tree(array_ref)),
                     !any_pointer_p(lhs));
             }
+            else if (tree global = utils::is_ssa_name_from_global_var_decl(lhs)) {
+                utils::dump_warning(logger, sm_ctx, stmt, lhs, global);
+                sm_ctx->warn(node, stmt, global, 
+                    make_unique<constant_time_diagnostic>(*this, sm_ctx->get_diagnostic_tree(global)),
+                    !any_pointer_p(lhs));
+            }
             else {
                 utils::dump_warning(logger, sm_ctx, stmt, lhs);
                 sm_ctx->warn(node, stmt, lhs, 
                     make_unique<constant_time_diagnostic>(*this, sm_ctx->get_diagnostic_tree(lhs)),
-                        true);
+                        !any_pointer_p(lhs));
             }
         }
         if (rhs && this->is_tainted(sm_ctx, stmt, rhs)
@@ -401,6 +433,12 @@ namespace crypto_taint {
                     make_unique<constant_time_diagnostic>(*this, sm_ctx->get_diagnostic_tree(array_ref)),
                     !any_pointer_p(lhs));
             }
+            else if (tree global = utils::is_ssa_name_from_global_var_decl(lhs)) {
+                utils::dump_warning(logger, sm_ctx, stmt, lhs, global);
+                sm_ctx->warn(node, stmt, global, 
+                    make_unique<constant_time_diagnostic>(*this, sm_ctx->get_diagnostic_tree(global)),
+                    !any_pointer_p(lhs));
+            }
             else {
                 utils::dump_warning(logger, sm_ctx, stmt, rhs);
                 sm_ctx->warn(node, stmt, rhs,
diff --git a/src/utils.cc b/src/utils.cc
index cccc64e..43546de 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -256,6 +256,24 @@ namespace utils {
         return NULL_TREE;
     }
 
+    tree is_ssa_name_from_global_var_decl(tree t) {
+        if (t && TREE_CODE(t) == SSA_NAME) {
+            auto def_stmt = SSA_NAME_DEF_STMT(t);
+            if (def_stmt
+                && is_a<gassign *>(def_stmt))
+            {
+                if (tree rhs = gimple_assign_rhs1(def_stmt)) {
+                    if (TREE_CODE(rhs) == VAR_DECL
+                        && DECL_CONTEXT(rhs)
+                        && TREE_CODE(DECL_CONTEXT(rhs)) == TRANSLATION_UNIT_DECL)
+                        return rhs;
+                }
+            }
+        }
+
+        return NULL_TREE;
+    }
+
     tree is_ssa_name_from_array_ref(tree t) {
         if (t && TREE_CODE(t) == SSA_NAME) {
             auto def_stmt = SSA_NAME_DEF_STMT(t);
-- 
GitLab