diff options
author | Martin Liska <mliska@suse.cz> | 2022-08-01 05:53:37 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-08-01 05:53:37 +0200 |
commit | 89eca196c99645ee1abefcf8b4a9dd84edd87ad6 (patch) | |
tree | 185cc8907ce37e82132f395cb52611f029215355 /gcc/analyzer | |
parent | 3a4cd5dc6faca8fed7fa256c4c06f4999b5a1f9c (diff) | |
parent | 4a7274ddc4970c1ad011343ed285d6219dffa396 (diff) | |
download | gcc-89eca196c99645ee1abefcf8b4a9dd84edd87ad6.zip gcc-89eca196c99645ee1abefcf8b4a9dd84edd87ad6.tar.gz gcc-89eca196c99645ee1abefcf8b4a9dd84edd87ad6.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/analyzer')
-rw-r--r-- | gcc/analyzer/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/analyzer/analyzer.opt | 4 | ||||
-rw-r--r-- | gcc/analyzer/region-model-impl-calls.cc | 117 | ||||
-rw-r--r-- | gcc/analyzer/region-model.cc | 6 | ||||
-rw-r--r-- | gcc/analyzer/region-model.h | 1 | ||||
-rw-r--r-- | gcc/analyzer/region.h | 52 | ||||
-rw-r--r-- | gcc/analyzer/sm-malloc.cc | 1 | ||||
-rw-r--r-- | gcc/analyzer/sm-taint.cc | 1 |
8 files changed, 180 insertions, 21 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index d10a5c8..d1cb3ad 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,22 @@ +2022-07-28 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/105893 + * analyzer.opt (Wanalyzer-putenv-of-auto-var): New. + * region-model-impl-calls.cc (class putenv_of_auto_var): New. + (region_model::impl_call_putenv): New. + * region-model.cc (region_model::on_call_pre): Handle putenv. + * region-model.h (region_model::impl_call_putenv): New decl. + +2022-07-28 David Malcolm <dmalcolm@redhat.com> + + * sm-malloc.cc (free_of_non_heap::emit): Add comment about CWE. + * sm-taint.cc (tainted_size::emit): Likewise. + +2022-07-28 David Malcolm <dmalcolm@redhat.com> + + * region.h: Add notes to the comment describing the region + class hierarchy. + 2022-07-27 Immad Mir <mirimmad@outlook.com> PR analyzer/106286 diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt index 5021376..808ff36 100644 --- a/gcc/analyzer/analyzer.opt +++ b/gcc/analyzer/analyzer.opt @@ -126,6 +126,10 @@ Wanalyzer-null-dereference Common Var(warn_analyzer_null_dereference) Init(1) Warning Warn about code paths in which a NULL pointer is dereferenced. +Wanalyzer-putenv-of-auto-var +Common Var(warn_analyzer_putenv_of_auto_var) Init(1) Warning +Warn about code paths in which an on-stack buffer is passed to putenv. + Wanalyzer-shift-count-negative Common Var(warn_analyzer_shift_count_negative) Init(1) Warning Warn about code paths in which a shift with negative count is attempted. diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 8c38e92..3f821ff 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -549,6 +549,123 @@ region_model::impl_call_memset (const call_details &cd) fill_region (sized_dest_reg, fill_value_u8); } +/* A subclass of pending_diagnostic for complaining about 'putenv' + called on an auto var. */ + +class putenv_of_auto_var +: public pending_diagnostic_subclass<putenv_of_auto_var> +{ +public: + putenv_of_auto_var (tree fndecl, const region *reg) + : m_fndecl (fndecl), m_reg (reg), + m_var_decl (reg->get_base_region ()->maybe_get_decl ()) + { + } + + const char *get_kind () const final override + { + return "putenv_of_auto_var"; + } + + bool operator== (const putenv_of_auto_var &other) const + { + return (m_fndecl == other.m_fndecl + && m_reg == other.m_reg + && same_tree_p (m_var_decl, other.m_var_decl)); + } + + int get_controlling_option () const final override + { + return OPT_Wanalyzer_putenv_of_auto_var; + } + + bool emit (rich_location *rich_loc) final override + { + auto_diagnostic_group d; + diagnostic_metadata m; + + /* SEI CERT C Coding Standard: "POS34-C. Do not call putenv() with a + pointer to an automatic variable as the argument". */ + diagnostic_metadata::precanned_rule + rule ("POS34-C", "https://wiki.sei.cmu.edu/confluence/x/6NYxBQ"); + m.add_rule (rule); + + bool warned; + if (m_var_decl) + warned = warning_meta (rich_loc, m, get_controlling_option (), + "%qE on a pointer to automatic variable %qE", + m_fndecl, m_var_decl); + else + warned = warning_meta (rich_loc, m, get_controlling_option (), + "%qE on a pointer to an on-stack buffer", + m_fndecl); + if (warned) + { + if (m_var_decl) + inform (DECL_SOURCE_LOCATION (m_var_decl), + "%qE declared on stack here", m_var_decl); + inform (rich_loc->get_loc (), "perhaps use %qs rather than %qE", + "setenv", m_fndecl); + } + + return warned; + } + + label_text describe_final_event (const evdesc::final_event &ev) final override + { + if (m_var_decl) + return ev.formatted_print ("%qE on a pointer to automatic variable %qE", + m_fndecl, m_var_decl); + else + return ev.formatted_print ("%qE on a pointer to an on-stack buffer", + m_fndecl); + } + + void mark_interesting_stuff (interesting_t *interest) final override + { + if (!m_var_decl) + interest->add_region_creation (m_reg->get_base_region ()); + } + +private: + tree m_fndecl; // non-NULL + const region *m_reg; // non-NULL + tree m_var_decl; // could be NULL +}; + +/* Handle the on_call_pre part of "putenv". + + In theory we could try to model the state of the environment variables + for the process; for now we merely complain about putenv of regions + on the stack. */ + +void +region_model::impl_call_putenv (const call_details &cd) +{ + tree fndecl = cd.get_fndecl_for_call (); + gcc_assert (fndecl); + region_model_context *ctxt = cd.get_ctxt (); + const svalue *ptr_sval = cd.get_arg_svalue (0); + const region *reg = deref_rvalue (ptr_sval, cd.get_arg_tree (0), ctxt); + m_store.mark_as_escaped (reg); + enum memory_space mem_space = reg->get_memory_space (); + switch (mem_space) + { + default: + gcc_unreachable (); + case MEMSPACE_UNKNOWN: + case MEMSPACE_CODE: + case MEMSPACE_GLOBALS: + case MEMSPACE_HEAP: + case MEMSPACE_READONLY_DATA: + break; + case MEMSPACE_STACK: + if (ctxt) + ctxt->warn (new putenv_of_auto_var (fndecl, reg)); + break; + } +} + /* Handle the on_call_pre part of "operator new". */ void diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index f7df2fc..a140f4d 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1539,6 +1539,12 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, impl_call_memset (cd); return false; } + else if (is_named_call_p (callee_fndecl, "putenv", call, 1) + && POINTER_TYPE_P (cd.get_arg_type (0))) + { + impl_call_putenv (cd); + return false; + } else if (is_named_call_p (callee_fndecl, "strchr", call, 2) && POINTER_TYPE_P (cd.get_arg_type (0))) { diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 42f8abe..a9657e0 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -630,6 +630,7 @@ class region_model void impl_call_malloc (const call_details &cd); void impl_call_memcpy (const call_details &cd); void impl_call_memset (const call_details &cd); + void impl_call_putenv (const call_details &cd); void impl_call_realloc (const call_details &cd); void impl_call_strchr (const call_details &cd); void impl_call_strcpy (const call_details &cd); diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index 1067748..a5b3029 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -72,27 +72,37 @@ enum region_kind region space_region - frame_region (RK_FRAME) - globals_region (RK_GLOBALS) - code_region (RK_CODE) - stack_region (RK_STACK) - heap_region (RK_HEAP) - root_region (RK_ROOT) - function_region (RK_FUNCTION) - label_region (RK_LABEL) - symbolic_region (RK_SYMBOLIC) - decl_region (RK_DECL), - field_region (RK_FIELD) - element_region (RK_ELEMENT) - offset_region (RK_OFFSET) - sized_region (RK_SIZED) - cast_region (RK_CAST) - heap_allocated_region (RK_HEAP_ALLOCATED) - alloca_region (RK_ALLOCA) - string_region (RK_STRING) - bit_range_region (RK_BIT_RANGE) - var_arg_region (RK_VAR_ARG) - unknown_region (RK_UNKNOWN). */ + frame_region (RK_FRAME): a function frame on the stack + globals_region (RK_GLOBALS): holds globals variables (data and bss) + code_region (RK_CODE): represents the code segment, containing functions + stack_region (RK_STACK): a stack, containing all stack frames + heap_region (RK_HEAP): the heap, containing heap_allocated_regions + root_region (RK_ROOT): the top-level region + function_region (RK_FUNCTION): the code for a particular function + label_region (RK_LABEL): a particular label within a function + symbolic_region (RK_SYMBOLIC): dereferencing a symbolic pointer + decl_region (RK_DECL): the memory occupied by a particular global, local, + or SSA name + field_region (RK_FIELD): the memory occupied by a field within a struct + or union + element_region (RK_ELEMENT): an element within an array + offset_region (RK_OFFSET): a byte-offset within another region, for + handling pointer arithmetic as a region + sized_region (RK_SIZED): a subregion of symbolic size (in bytes) + within its parent + cast_region (RK_CAST): a region that views another region using a + different type + heap_allocated_region (RK_HEAP_ALLOCATED): an untyped region dynamically + allocated on the heap via + "malloc" or similar + alloca_region (RK_ALLOCA): an untyped region dynamically allocated on the + stack via "alloca" + string_region (RK_STRING): a region for a STRING_CST + bit_range_region (RK_BIT_RANGE): a region for a specific range of bits + within another region + var_arg_region (RK_VAR_ARG): a region for the N-th vararg within a + frame_region for a variadic call + unknown_region (RK_UNKNOWN): for handling unimplemented tree codes. */ /* Abstract base class for representing ways of accessing chunks of memory. diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 608aceb..73c549f 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -1300,6 +1300,7 @@ public: bool emit (rich_location *rich_loc) final override { + /* "CWE-401: Missing Release of Memory after Effective Lifetime". */ diagnostic_metadata m; m.add_cwe (401); if (m_arg) diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index 51bfe06..549373b 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -435,6 +435,7 @@ public: bool emit (rich_location *rich_loc) override { + /* "CWE-129: Improper Validation of Array Index". */ diagnostic_metadata m; m.add_cwe (129); if (m_arg) |