/* * Copyright © 2020 Endless OS Foundation, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . * * Author: Philip Withnall */ /* This modelling file needs to be uploaded to GLib’s Coverity configuration at * https://scan.coverity.com/projects/glib?tab=analysis_settings * by someone with the appropriate permissions on Coverity. It should be kept in * sync with what’s there. * * Reference: https://scan.coverity.com/tune */ /* Disable some esoteric options which Coverity doesn't understand because they * delve into assembly. */ #define NVALGRIND 1 #undef HAVE_DTRACE #define TRACE(probe) /* no-op */ /* libc definitions */ #define NULL ((void*)0) void *malloc (size_t); void *calloc (size_t, size_t); void *realloc (void *, size_t); void free (void *); /* Define some standard GLib types. */ typedef size_t gsize; typedef char gchar; typedef unsigned char guchar; typedef int gint; typedef unsigned long gulong; typedef unsigned int guint32; typedef void* gpointer; typedef unsigned int gboolean; typedef enum { /* log flags */ G_LOG_FLAG_RECURSION = 1 << 0, G_LOG_FLAG_FATAL = 1 << 1, /* GLib log levels */ G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */ G_LOG_LEVEL_CRITICAL = 1 << 3, G_LOG_LEVEL_WARNING = 1 << 4, G_LOG_LEVEL_MESSAGE = 1 << 5, G_LOG_LEVEL_INFO = 1 << 6, G_LOG_LEVEL_DEBUG = 1 << 7, G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL) } GLogLevelFlags; typedef struct _GList GList; struct _GList { gpointer data; GList *next; GList *prev; }; typedef struct _GError GError; struct _GError { /* blah */ }; /* Dummied from sys/stat.h. */ struct stat {}; extern int stat (const char *path, struct stat *buf); /* g_stat() can be used to check whether a given path is safe (i.e. exists). * This is not a full solution for sanitising user-provided paths, but goes a * long way, and is the best we can do without more context about how the path * is used. */ typedef struct stat GStatBuf; #undef g_stat int g_stat (const char *filename, GStatBuf *buf) { __coverity_tainted_string_sanitize_content__ (filename); return stat (filename, buf); } /* g_path_skip_root() can be used to validate that a @file_name is absolute. It * returns %NULL otherwise. */ const char * g_path_skip_root (const char *file_name) { int is_ok; if (is_ok) { __coverity_tainted_string_sanitize_content__ (file_name); return file_name; } else { return 0; /* NULL */ } } /* Tainted string sanitiser. */ int g_action_name_is_valid (const char *action_name) { int is_ok; if (is_ok) { __coverity_tainted_string_sanitize_content__ (action_name); return 1; /* TRUE */ } else { return 0; /* FALSE */ } } /* Treat this like an assert(0). */ void g_return_if_fail_warning (const char *log_domain, const char *pretty_function, const char *expression) { __coverity_panic__(); } /* Treat this like an assert(0). */ void g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...) { if (log_level & G_LOG_LEVEL_CRITICAL) __coverity_panic__ (); } #define g_critical(...) __coverity_panic__ (); /* Treat it as a memory sink to hide one-time allocation leaks. */ void (g_once_init_leave) (volatile void *location, gsize result) { __coverity_escape__ (result); } /* Coverity cannot model allocation management for linked lists, so just pretend * that it's a pass-through. */ GList * g_list_reverse (GList *list) { return list; } /* g_ascii_isspace() routinely throws data_index taint errors, saying that * tainted data is being used to index g_ascii_table. This is true, but the * table has defined values for all possible 8-bit indexes. */ gboolean g_ascii_isspace (gchar c) { int is_space; __coverity_tainted_string_sink_content__ (c); if (is_space) return 1; else return 0; } /* Coverity treats byte-swapping operations as suspicious, and taints all data * which is byte-swapped (because it thinks it therefore probably comes from an * external source, which is reasonable). That is not the case for checksum * calculation, however. * * Since the definitions of these two functions depends on the host byte order, * just model them as no-ops. */ void md5_byte_reverse (guchar *buffer, gulong length) { /* No-op. */ } void sha_byte_reverse (guint32 *buffer, gint length) { /* No-op. */ } /* Parse error printing does not care about sanitising the input. */ gchar * g_variant_parse_error_print_context (GError *error, const gchar *source_str) { __coverity_tainted_data_sink__ (source_str); return __coverity_alloc_nosize__ (); } /* Coverity somehow analyses G_LIKELY(x) as sometimes meaning !x, for example * when analysing g_try_realloc(). Ignore that. */ #define G_LIKELY(x) x #define G_UNLIKELY(x) x typedef struct {} DIR; typedef struct _GDir GDir; struct _GDir { DIR *dirp; }; /* This is a private function to libglib, and Coverity can’t peek inside it when * analysing code in (say) GIO. */ GDir * g_dir_new_from_dirp (gpointer dirp) { GDir *dir; if (dirp == 0) __coverity_panic__(); dir = malloc (sizeof (GDir)); dir->dirp = dirp; return dir; }