glib2.0/.gitlab-ci/coverity-model.c

247 lines
6.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author: Philip Withnall <withnall@endlessm.com>
*/
/* This modelling file needs to be uploaded to GLibs 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 whats 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 cant 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;
}