/* An experimental state machine, for tracking bad calls from within
   signal handlers.

   Copyright (C) 2019-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "function.h"
#include "basic-block.h"
#include "gimple.h"
#include "options.h"
#include "bitmap.h"
#include "diagnostic-path.h"
#include "diagnostic-metadata.h"
#include "function.h"
#include "json.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
#include "analyzer/pending-diagnostic.h"
#include "sbitmap.h"
#include "tristate.h"
#include "ordered-hash-map.h"
#include "selftest.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
#include "analyzer/program-state.h"
#include "analyzer/checker-path.h"
#include "digraph.h"
#include "cfg.h"
#include "gimple-iterator.h"
#include "cgraph.h"
#include "analyzer/supergraph.h"
#include "alloc-pool.h"
#include "fibonacci_heap.h"
#include "analyzer/diagnostic-manager.h"
#include "shortest-paths.h"
#include "analyzer/exploded-graph.h"
#include "analyzer/function-set.h"
#include "analyzer/analyzer-selftests.h"

#if ENABLE_ANALYZER

namespace ana {

namespace {

/* An experimental state machine, for tracking calls to async-signal-unsafe
   functions from within signal handlers.  */

class signal_state_machine : public state_machine
{
public:
  signal_state_machine (logger *logger);

  bool inherited_state_p () const FINAL OVERRIDE { return false; }

  bool on_stmt (sm_context *sm_ctxt,
		const supernode *node,
		const gimple *stmt) const FINAL OVERRIDE;

  bool can_purge_p (state_t s) const FINAL OVERRIDE;

  /* These states are "global", rather than per-expression.  */

  /* State for when we're in a signal handler.  */
  state_t m_in_signal_handler;

  /* Stop state.  */
  state_t m_stop;
};

/* Concrete subclass for describing call to an async-signal-unsafe function
   from a signal handler.  */

class signal_unsafe_call
  : public pending_diagnostic_subclass<signal_unsafe_call>
{
public:
  signal_unsafe_call (const signal_state_machine &sm, const gcall *unsafe_call,
		      tree unsafe_fndecl)
  : m_sm (sm), m_unsafe_call (unsafe_call), m_unsafe_fndecl (unsafe_fndecl)
  {
    gcc_assert (m_unsafe_fndecl);
  }

  const char *get_kind () const FINAL OVERRIDE { return "signal_unsafe_call"; }

  bool operator== (const signal_unsafe_call &other) const
  {
    return m_unsafe_call == other.m_unsafe_call;
  }

  int get_controlling_option () const FINAL OVERRIDE
  {
    return OPT_Wanalyzer_unsafe_call_within_signal_handler;
  }

  bool emit (rich_location *rich_loc) FINAL OVERRIDE
  {
    auto_diagnostic_group d;
    diagnostic_metadata m;
    /* CWE-479: Signal Handler Use of a Non-reentrant Function.  */
    m.add_cwe (479);
    if (warning_meta (rich_loc, m, get_controlling_option (),
		      "call to %qD from within signal handler",
		      m_unsafe_fndecl))
      {
	/* If we know a possible alternative function, add a note
	   suggesting the replacement.  */
	if (const char *replacement = get_replacement_fn ())
	  {
	    location_t note_loc = gimple_location (m_unsafe_call);
	    /* It would be nice to add a fixit, but the gimple call
	       location covers the whole call expression.  It isn't
	       currently possible to cut this down to just the call
	       symbol.  So the fixit would replace too much.
	       note_rich_loc.add_fixit_replace (replacement); */
	    inform (note_loc,
		    "%qs is a possible signal-safe alternative for %qD",
		    replacement, m_unsafe_fndecl);
	  }
	return true;
      }
    return false;
  }

  label_text describe_state_change (const evdesc::state_change &change)
    FINAL OVERRIDE
  {
    if (change.is_global_p ()
	&& change.m_new_state == m_sm.m_in_signal_handler)
      {
	function *handler = change.m_event.get_dest_function ();
	return change.formatted_print ("registering %qD as signal handler",
				       handler->decl);
      }
    return label_text ();
  }

  label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
  {
    return ev.formatted_print ("call to %qD from within signal handler",
			       m_unsafe_fndecl);
  }

private:
  const signal_state_machine &m_sm;
  const gcall *m_unsafe_call;
  tree m_unsafe_fndecl;

  /* Returns a replacement function as text if it exists.  Currently
     only "exit" has a signal-safe replacement "_exit", which does
     slightly less, but can be used in a signal handler.  */
  const char *
  get_replacement_fn ()
  {
    gcc_assert (m_unsafe_fndecl && DECL_P (m_unsafe_fndecl));

    if (id_equal ("exit", DECL_NAME (m_unsafe_fndecl)))
      return "_exit";

    return NULL;
  }
};

/* signal_state_machine's ctor.  */

signal_state_machine::signal_state_machine (logger *logger)
: state_machine ("signal", logger)
{
  m_in_signal_handler = add_state ("in_signal_handler");
  m_stop = add_state ("stop");
}

/* Update MODEL for edges that simulate HANDLER_FUN being called as
   an signal-handler in response to a signal.  */

static void
update_model_for_signal_handler (region_model *model,
				 function *handler_fun)
{
  gcc_assert (model);
  /* Purge all state within MODEL.  */
  *model = region_model (model->get_manager ());
  model->push_frame (handler_fun, NULL, NULL);
}

/* Custom exploded_edge info: entry into a signal-handler.  */

class signal_delivery_edge_info_t : public custom_edge_info
{
public:
  void print (pretty_printer *pp) const FINAL OVERRIDE
  {
    pp_string (pp, "signal delivered");
  }

  json::object *to_json () const
  {
    json::object *custom_obj = new json::object ();
    return custom_obj;
  }

  bool update_model (region_model *model,
		     const exploded_edge *eedge,
		     region_model_context *) const FINAL OVERRIDE
  {
    gcc_assert (eedge);
    update_model_for_signal_handler (model, eedge->m_dest->get_function ());
    return true;
  }

  void add_events_to_path (checker_path *emission_path,
			   const exploded_edge &eedge ATTRIBUTE_UNUSED)
    const FINAL OVERRIDE
  {
    emission_path->add_event
      (new precanned_custom_event
       (UNKNOWN_LOCATION, NULL_TREE, 0,
	"later on,"
	" when the signal is delivered to the process"));
  }
};

/* Concrete subclass of custom_transition for modeling registration of a
   signal handler and the signal handler later being called.  */

class register_signal_handler : public custom_transition
{
public:
  register_signal_handler (const signal_state_machine &sm,
			   tree fndecl)
  : m_sm (sm), m_fndecl (fndecl) {}

  /* Model a signal-handler FNDECL being called at some later point
     by injecting an edge to a new function-entry node with an empty
     callstring, setting the 'in-signal-handler' global state
     on the node.  */
  void impl_transition (exploded_graph *eg,
			exploded_node *src_enode,
			int sm_idx) FINAL OVERRIDE
  {
    function *handler_fun = DECL_STRUCT_FUNCTION (m_fndecl);
    if (!handler_fun)
      return;
    program_point entering_handler
      = program_point::from_function_entry (eg->get_supergraph (),
					    handler_fun);

    program_state state_entering_handler (eg->get_ext_state ());
    update_model_for_signal_handler (state_entering_handler.m_region_model,
				     handler_fun);
    state_entering_handler.m_checker_states[sm_idx]->set_global_state
      (m_sm.m_in_signal_handler);

    exploded_node *dst_enode = eg->get_or_create_node (entering_handler,
						       state_entering_handler,
						       src_enode);
    if (dst_enode)
      eg->add_edge (src_enode, dst_enode, NULL, /*state_change (),*/
		    new signal_delivery_edge_info_t ());
  }

  const signal_state_machine &m_sm;
  tree m_fndecl;
};

/* Get a set of functions that are known to be unsafe to call from an
   async signal handler.  */

static function_set
get_async_signal_unsafe_fns ()
{
  // TODO: populate this list more fully
  static const char * const async_signal_unsafe_fns[] = {
    /* This array must be kept sorted.  */
    "exit",
    "fprintf",
    "free",
    "malloc",
    "printf",
    "snprintf",
    "sprintf",
    "vfprintf",
    "vprintf",
    "vsnprintf",
    "vsprintf"
  };
  const size_t count
    = sizeof(async_signal_unsafe_fns) / sizeof (async_signal_unsafe_fns[0]);
  function_set fs (async_signal_unsafe_fns, count);
  return fs;
}

/* Return true if FNDECL is known to be unsafe to call from a signal
   handler.  */

static bool
signal_unsafe_p (tree fndecl)
{
  function_set fs = get_async_signal_unsafe_fns ();
  return fs.contains_decl_p (fndecl);
}

/* Implementation of state_machine::on_stmt vfunc for signal_state_machine.  */

bool
signal_state_machine::on_stmt (sm_context *sm_ctxt,
			       const supernode *node,
			       const gimple *stmt) const
{
  const state_t global_state = sm_ctxt->get_global_state ();
  if (global_state == m_start)
    {
      if (const gcall *call = dyn_cast <const gcall *> (stmt))
	if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
	  if (is_named_call_p (callee_fndecl, "signal", call, 2))
	    {
	      tree handler = gimple_call_arg (call, 1);
	      if (TREE_CODE (handler) == ADDR_EXPR
		  && TREE_CODE (TREE_OPERAND (handler, 0)) == FUNCTION_DECL)
		{
		  tree fndecl = TREE_OPERAND (handler, 0);
		  register_signal_handler rsh (*this, fndecl);
		  sm_ctxt->on_custom_transition (&rsh);
		}
	    }
    }
  else if (global_state == m_in_signal_handler)
    {
      if (const gcall *call = dyn_cast <const gcall *> (stmt))
	if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
	  if (signal_unsafe_p (callee_fndecl))
	    if (sm_ctxt->get_global_state () == m_in_signal_handler)
	      sm_ctxt->warn (node, stmt, NULL_TREE,
			     new signal_unsafe_call (*this, call,
						     callee_fndecl));
    }

  return false;
}

bool
signal_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
{
  return true;
}

} // anonymous namespace

/* Internal interface to this file. */

state_machine *
make_signal_state_machine (logger *logger)
{
  return new signal_state_machine (logger);
}

#if CHECKING_P

namespace selftest {

/* Run all of the selftests within this file.  */

void
analyzer_sm_signal_cc_tests ()
{
  function_set fs = get_async_signal_unsafe_fns ();
  fs.assert_sorted ();
  fs.assert_sane ();
}

} // namespace selftest

#endif /* CHECKING_P */

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
