(root)/
glib-2.79.0/
.gitlab-ci/
coverity-model.c
       1  /*
       2   * Copyright © 2020 Endless OS Foundation, LLC
       3   *
       4   * This library is free software; you can redistribute it and/or
       5   * modify it under the terms of the GNU Lesser General Public
       6   * License as published by the Free Software Foundation; either
       7   * version 2.1 of the License, or (at your option) any later version.
       8   *
       9   * This library is distributed in the hope that it will be useful,
      10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12   * Lesser General Public License for more details.
      13   *
      14   * You should have received a copy of the GNU Lesser General Public
      15   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      16   *
      17   * Author: Philip Withnall <withnall@endlessm.com>
      18   */
      19  
      20  /* This modelling file needs to be uploaded to GLib’s Coverity configuration at
      21   * https://scan.coverity.com/projects/glib?tab=analysis_settings
      22   * by someone with the appropriate permissions on Coverity. It should be kept in
      23   * sync with what’s there.
      24   *
      25   * Reference: https://scan.coverity.com/tune
      26   */
      27  
      28  /* Disable some esoteric options which Coverity doesn't understand because they
      29   * delve into assembly. */
      30  #define NVALGRIND 1
      31  #undef HAVE_DTRACE
      32  
      33  #define TRACE(probe)  /* no-op */
      34  
      35  /* libc definitions */
      36  #define NULL ((void*)0)
      37  
      38  void *malloc (size_t);
      39  void *calloc (size_t, size_t);
      40  void *realloc (void *, size_t);
      41  void free (void *);
      42  
      43  /* Define some standard GLib types. */
      44  typedef size_t gsize;
      45  typedef char gchar;
      46  typedef unsigned char guchar;
      47  typedef int gint;
      48  typedef unsigned long gulong;
      49  typedef unsigned int guint32;
      50  typedef void* gpointer;
      51  typedef unsigned int gboolean;
      52  
      53  typedef enum
      54  {
      55    /* log flags */
      56    G_LOG_FLAG_RECURSION          = 1 << 0,
      57    G_LOG_FLAG_FATAL              = 1 << 1,
      58  
      59    /* GLib log levels */
      60    G_LOG_LEVEL_ERROR             = 1 << 2,       /* always fatal */
      61    G_LOG_LEVEL_CRITICAL          = 1 << 3,
      62    G_LOG_LEVEL_WARNING           = 1 << 4,
      63    G_LOG_LEVEL_MESSAGE           = 1 << 5,
      64    G_LOG_LEVEL_INFO              = 1 << 6,
      65    G_LOG_LEVEL_DEBUG             = 1 << 7,
      66  
      67    G_LOG_LEVEL_MASK              = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL)
      68  } GLogLevelFlags;
      69  
      70  typedef struct _GList GList;
      71  
      72  struct _GList
      73  {
      74    gpointer data;
      75    GList *next;
      76    GList *prev;
      77  };
      78  
      79  typedef struct _GError GError;
      80  
      81  struct _GError
      82  {
      83    /* blah */
      84  };
      85  
      86  /* Dummied from sys/stat.h. */
      87  struct stat {};
      88  extern int stat (const char *path, struct stat *buf);
      89  
      90  /* g_stat() can be used to check whether a given path is safe (i.e. exists).
      91   * This is not a full solution for sanitising user-provided paths, but goes a
      92   * long way, and is the best we can do without more context about how the path
      93   * is used. */
      94  typedef struct stat GStatBuf;
      95  #undef g_stat
      96  
      97  int
      98  g_stat (const char *filename, GStatBuf *buf)
      99  {
     100    __coverity_tainted_string_sanitize_content__ (filename);
     101    return stat (filename, buf);
     102  }
     103  
     104  /* g_path_skip_root() can be used to validate that a @file_name is absolute. It
     105   * returns %NULL otherwise. */
     106  const char *
     107  g_path_skip_root (const char *file_name)
     108  {
     109    int is_ok;
     110    if (is_ok)
     111      {
     112        __coverity_tainted_string_sanitize_content__ (file_name);
     113        return file_name;
     114      }
     115    else
     116      {
     117        return 0;  /* NULL */
     118      }
     119  }
     120  
     121  /* Tainted string sanitiser. */
     122  int
     123  g_action_name_is_valid (const char *action_name)
     124  {
     125    int is_ok;
     126    if (is_ok)
     127      {
     128        __coverity_tainted_string_sanitize_content__ (action_name);
     129        return 1;  /* TRUE */
     130      }
     131    else
     132      {
     133        return 0;  /* FALSE */
     134      }
     135  }
     136  
     137  /* Treat this like an assert(0). */
     138  void
     139  g_return_if_fail_warning (const char *log_domain,
     140                            const char *pretty_function,
     141                            const char *expression)
     142  {
     143    __coverity_panic__();
     144  }
     145  
     146  /* Treat this like an assert(0). */
     147  void
     148  g_log (const gchar   *log_domain,
     149         GLogLevelFlags log_level,
     150         const gchar   *format,
     151         ...)
     152  {
     153    if (log_level & G_LOG_LEVEL_CRITICAL)
     154      __coverity_panic__ ();
     155  }
     156  
     157  #define g_critical(...) __coverity_panic__ ();
     158  
     159  /* Treat it as a memory sink to hide one-time allocation leaks. */
     160  void
     161  (g_once_init_leave) (volatile void *location,
     162                       gsize          result)
     163  {
     164    __coverity_escape__ (result);
     165  }
     166  
     167  /* Coverity cannot model allocation management for linked lists, so just pretend
     168   * that it's a pass-through. */
     169  GList *
     170  g_list_reverse (GList *list)
     171  {
     172    return list;
     173  }
     174  
     175  /* g_ascii_isspace() routinely throws data_index taint errors, saying that
     176   * tainted data is being used to index g_ascii_table. This is true, but the
     177   * table has defined values for all possible 8-bit indexes. */
     178  gboolean
     179  g_ascii_isspace (gchar c)
     180  {
     181    int is_space;
     182    __coverity_tainted_string_sink_content__ (c);
     183    if (is_space)
     184      return 1;
     185    else
     186      return 0;
     187  }
     188  
     189  /* Coverity treats byte-swapping operations as suspicious, and taints all data
     190   * which is byte-swapped (because it thinks it therefore probably comes from an
     191   * external source, which is reasonable). That is not the case for checksum
     192   * calculation, however.
     193   *
     194   * Since the definitions of these two functions depends on the host byte order,
     195   * just model them as no-ops. */
     196  void
     197  md5_byte_reverse (guchar *buffer,
     198                    gulong  length)
     199  {
     200    /* No-op. */
     201  }
     202  
     203  void
     204  sha_byte_reverse (guint32 *buffer,
     205                    gint     length)
     206  {
     207    /* No-op. */
     208  }
     209  
     210  /* Parse error printing does not care about sanitising the input. */
     211  gchar *
     212  g_variant_parse_error_print_context (GError      *error,
     213                                       const gchar *source_str)
     214  {
     215    __coverity_tainted_data_sink__ (source_str);
     216    return __coverity_alloc_nosize__ ();
     217  }
     218  
     219  /* Coverity somehow analyses G_LIKELY(x) as sometimes meaning !x, for example
     220   * when analysing g_try_realloc(). Ignore that. */
     221  #define G_LIKELY(x) x
     222  #define G_UNLIKELY(x) x
     223  
     224  typedef struct {} DIR;
     225  typedef struct _GDir GDir;
     226  
     227  struct _GDir
     228  {
     229    DIR *dirp;
     230  };
     231  
     232  /* This is a private function to libglib, and Coverity can’t peek inside it when
     233   * analysing code in (say) GIO. */
     234  GDir *
     235  g_dir_new_from_dirp (gpointer dirp)
     236  {
     237    GDir *dir;
     238  
     239    if (dirp == 0)
     240      __coverity_panic__();
     241  
     242    dir = malloc (sizeof (GDir));
     243    dir->dirp = dirp;
     244  
     245    return dir;
     246  }