JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.
If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.
If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.
| CodeSonar® 9.2p0 | CONFIDENTIAL | CodeSecure Inc |
This tutorial illustrates the use of the CodeSonar extension API to model taint-related properties of program artifacts, and check for uses of tainted values in sensitive contexts.
If you have not already done so, work through the following tutorials before doing this one.
Note: Depending on the hub configuration, you may be prompted for hub user account credentials to authenticate and authorize codesonar build and codesonar analyze commands. See Hub Authentication: Authenticated codesonar Subcommands for more information.
This example is based on a sample I/O library, with declarations in iolibrary.h and definitions in iolibrary.c.
We create CodeSonar models for some of the library functions. (The remaining functions do not require additional modeling work: they are implemented using libc functions with existing CodeSonar library models that provide sufficient checking and taint handling).
In this section (and throughout this manual), $CSONAR indicates the CodeSonar installation directory.
The following files are used:
| iolibrary.h | Declarations for the I/O library. |
|---|---|
| iolibrary.c | Definitions for the I/O library. |
| check_iolibrary.c | CodeSonar models for the I/O library , including checks for unsafe use of tainted values. |
| use_iolibrary.c | A program that uses some of the I/O library functions (not always safely). |
The following functions are declared in iolibrary.h and defined in iolibrary.c.
| FILE *open_a_file(char *); | Opens a file for updating. |
|---|---|
| int close_a_file(FILE*); | Closes a file. |
| char * read_string_from_file(char*, size_t, FILE*); | Reads a string from a file. This function contains a taint source. |
| int write_string_to_file(char*, FILE*); | Writes a string to a file. |
| int sanitized_size(char*); | Computes the amount of space required to hold the 'sanitized' version of a string. |
| int sanitize_file_string(char*, char*); | Generates a 'sanitized' version of a string. This function performs taint cleansing. |
| int print_important_data(char*); | Prints a piece of important data (determined by the char* argument) to stdout. This function contains a taint sink. |
File check_iolibrary.c is reproduced below.
/* * Copyright (c) 2023, an unpublished work by CodeSecure, Inc. * ALL RIGHTS RESERVED * * Copyright (c) 2014-2023, an unpublished work by GrammaTech, Inc. * ALL RIGHTS RESERVED * * This software is furnished under a license and may be used and * copied only in accordance with the terms of such license and the * inclusion of the above copyright notice. This software or any * other copies thereof may not be provided or otherwise made * available to any other person. Title to and ownership of the * software is retained by CodeSecure, Inc. */ /* check_iolibrary.c * * Contains CodeSonar models and checks for the functions in iolibrary.h. */ #ifdef __CODESONAR__ /* All files that use the Extension API must include csonar.h and * stdlib.h. */ #include <stdlib.h> #include <stdio.h> #include "csonar.h" #include "iolibrary.h" /* We define a new taint kind to track taint entering the program through functions * in this library. See documentation for CSONAR_DEFINE_TAINT_SOURCE. */ CSONAR_DEFINE_TAINT_SOURCE(iolibrary); #define __CSURF_MARKER_LIBRARY_FUNCTION__ 1 /* Some of the library functions are defined (in iolibrary.c) in terms * of libc functions that already have CodeSonar models. The * following functions do not require additional modeling work because * all necessary checking and taint handling is already accomplished * by the libc models. * * +-------------------------+------------+ * | iolibrary function | libc model | * +-------------------------+------------+ * | open_a_file() | fopen() | * | close_a_file() | fclose() | * | write_string_to_file() | fputs() | * +-------------------------+------------+ */ /* The specially-named csonar_replace_open_a_file() will intercept * all calls to open_a_file (and similarly for all other * procedures with names of the form csonar_replace_functionname). * * Note that the symbol __CSURF_MARKER_LIBRARY_FUNCTION__ is defined * (as 1) before the definitions of the csonar_replace_* * functions. This marks them as LIBRARY FUNCTIONS: any warnings * triggered inside a replacement function will be reported at the * appropriate call site to that function, not inside the function * itself. * * Our replacement for read_string_from_file() calls the actual * read_string_from_file() function so that its implementation can be * checked by CodeSonar. Additionally, it specifies that the string * read from the file has all of the taint determined by analyzing * read_string_from_file(), plus taint of kind 'iolibrary'. */ char * csonar_replace_read_string_from_file(char *dest, size_t numchars, FILE *src){ char * retval; size_t len; int taintunion; retval = read_string_from_file(dest, numchars, src); if (retval && CSM_UNKNOWN_INTEGER()){ /* We want this code to be visible to the taint analysis phase * only. If it were analyzed during other phases it could cause * CodeSonar to become confused about the size of the buffer. */ csonar_assert_taint_enabled(); /* Construct a value with "iolibrary" taint plus all the taint * previously associated with dest. */ taintunion = csonar_taint_union2(csonar_string_taint(dest), csonar_taint_source_iolibrary()); /* Model taint on the contents of the string. */ *dest = taintunion; /* Model taint on the length of the string.*/ len = csonar_bounded_value(taintunion, 0, numchars - 1 ); dest[len] = '\0'; } return retval; } /* We model sanitized_size() to call the actual sanitized_size() * function so that its implementation can be checked by * CodeSonar. The model uses analysis 'assertions' to inform the * CodeSonar analysis that the return must be either -1, or at least * as large as the length of 'raw'. * The model cleanses all taint from the return value before returning * it: the sanitized size is derived from the size of the 'raw' * string, but we have determined it to be safe. */ int csonar_replace_sanitized_size(char *raw){ int retval; retval = sanitized_size(raw); if (retval < strlen(raw)){ if (retval != -1){ abort(); } } csonar_taint_clear_int(&retval); return retval; } /* We model sanitize_file_string() to call the actual * sanitize_file_string() function so that its implementation can be * checked by CodeSonar. Additionally, the model uses csonar_taint_clear_* to specify that the resulting string * has no taint. * - The "int" attribute of an address is an alias for the memory contents * at that address. * - The "term" attribute of an address is an alias for the distance * (in bits) between that address and the null sentinel. */ int csonar_replace_sanitize_file_string(char *raw, char *sanitized){ int retval; retval = sanitize_file_string(raw, sanitized); csonar_taint_clear_int(sanitized); csonar_taint_clear_term(sanitized); return retval; } /* If a tainted string is passed to print_important_data(), we want to * issue a warning. csonar_taint_sink() performs the taint check and * specifies the warning class to use. In this case, we specify a * custom warning class. */ int csonar_replace_print_important_data(char *str){ csonar_taint_sink(csonar_taint_source_any(), *str, "Tainted Input to print_important_data", "CWE:20", csws_security); return print_important_data(str); } #endif
We want to compile check_iolibrary.c and include it in the CodeSonar project.
| host:port | the hub location. |
|---|---|
| libmodels_path | the full path to the codesonar/libmodels subdirectory of your CodeSonar installation. |
| [-remote analysis-launchd] | if you are using CodeSonar SaaS, include -remote "/saas/*" codesonar analyze command (you do not need to specify it with codesonar build). Otherwise, you can omit this option. For more information, see the documentation for -remote. |
| With gcc: |
codesonar build test_iolibrary host:port
\
gcc "-Ilibmodels_path" -c check_iolibrary.c |
||||||
|---|---|---|---|---|---|---|---|
| With cl: |
codesonar build test_iolibrary host:port
^
cl "/Ilibmodels_path" /c check_iolibrary.c |
||||||
| Otherwise: |
Use a command of the form:
codesonar build test_iolibrary host:port
\
where:
compiler_command include_libmodels options check_iolibrary.c
|
If you are not already familiar with the CodeSonar build and analysis steps, you may wish to refer the following sections.
Now build the project and run the CodeSonar analysis.
| With gcc: |
codesonar analyze test_iolibrary \
[-no-services] [-remote analysis-launchd] [host:port] gcc -c iolibrary.c use_iolibrary.c |
||||||
|---|---|---|---|---|---|---|---|
| With cl: |
codesonar analyze test_iolibrary ^
[-no-services] [-remote analysis-launchd] [host:port] cl /c iolibrary.c use_iolibrary.c |
||||||
| Otherwise: |
Use a command of the form:
codesonar analyze test_iolibrary [-remote
analysis-launchd] [host:port]
\
where:
compiler_command include_libmodels options iolibrary.c use_iolibrary.c
|
We might also want to know if values with iolibrary taint are being passed to write_string_to_file().
Add a write_string_to_file() model to check_iolibrary.c and test it:
| taint_kind | Specify csonar_taint_source_iolibrary(): for the purpose of this exercise we are interested only in the iolibrary taint kind. |
| val | Specify *src (the contents of of the char* argument to write_string_to_file() - if you change the argument names in the write_string_to_file() header, adjust your val argument accordingly) |
| warning_class | Choose and specify a name for the new warning class. |
| categories | Choose and specify one or more categories for the new warning class (or use the empty string if you don't want any categories). |
| sig | Use of tainted values is a security issue, so specify csws_security. |
To report problems with this documentation, please visit https://support.codesecure.com/.