CWE-134¶
Use of Externally-Controlled Format String. [String-Errors, Improper-Control-Of-A-Resource-Through-Its-Lifetime]
Required inputs: IR, StaticSemanticAnalysis
When an attacker can modify an externally-controlled format string, this can lead to buffer overflows, denial of service, or data representation problems.
It should be noted that in some circumstances, such as internationalization, the set of format strings is externally controlled by design. If the source of these format strings is trusted (e.g. only contained in library files that are only modifiable by the system administrator), then the external control might not itself pose a vulnerability.
Demonstrative Examples Functional Areas
Example 1
The following program prints a string provided as an argument.
Example Language:C
#include <stdio.h>
void printWrapper(char *string) {
printf(string);
}
int main(int argc, char **argv) {
char buf[5012];
memcpy(buf, argv[1], 5012);
printWrapper(argv[1]);
return (0);
}
The example is exploitable, because of the call to printf() in the printWrapper() function. Note: The stack buffer was added to make exploitation more simple.
Example 2
The following code copies a command line argument into a buffer using snprintf().
Example Language:C
int main(int argc, char **argv){
char buf[128];
...
snprintf(buf,128,argv[1]);
}
This code allows an attacker to view the contents of the stack and write to the stack using a command line argument containing a sequence of formatting directives. The attacker can read from the stack by providing more formatting directives, such as %x, than the function takes as arguments to be formatted. (In this example, the function takes no arguments to be formatted.) By using the %n formatting directive, the attacker can write to the stack, causing snprintf() to write the number of bytes output thus far to the specified argument (rather than reading a value from the argument, which is the intended behavior). A sophisticated version of this attack will use four staggered writes to completely control the value of a pointer on the stack.
Example 3
Certain implementations make more advanced attacks even easier by providing format directives that control the location in memory to read from or write to. An example of these directives is shown in the following code, written for glibc:
Example Language:C
printf("%d %d %1$d %1$d\n", 5, 9);
This code produces the following output: 5 9 5 5 It is also possible to use half-writes (%hn) to accurately control arbitrary DWORDS in memory, which greatly reduces the complexity needed to execute an attack that would otherwise require four staggered writes, such as the one mentioned in the first example.
Demonstrative Examples Functional Areas
- Logging
- Error Handling
- String Processing
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
invalid_conversion |
Invalid or non-standard conversion specification |
None |
False |
unchecked_external_value |
The validity of values received from external sources shall be checked. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
all_external_functions_as_sinks¶
all_external_functions_as_sinks : bool = False
all_external_functions_as_sources¶
all_external_functions_as_sources : bool = True
allow_extra_args¶
allow_extra_args : bool = False
allow_gnu_extensions¶
allow_gnu_extensions : bool = False
allow_unknown_specs¶
allow_unknown_specs : bool = False
external_sources¶
Description of the possible sources of external values.
external_sources.arguments_of
Description of functions for which pointer arguments should be treated as an external value that must be checked after calling the function. For each function, an argument specifier needs to be set that describes a selection of argument numbers that shall be considered. A numberxis considered iff(x >= argument_range_min and x <= argument_range_max and argument_numbers_set.empty())orx in argument_numbers_set. If the table is empty, all non-const pointer parameters of external functions are checked.
external_sources.arguments_of.excluded
Functions which should be exempt from the set of functions for which the arguments should be checked before using them.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{ '__axivion_add_local_static__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), '__axivion_get_array_size__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__axivion_get_polymorphic_size__': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin___strcat_chk': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin___strcpy_chk': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), '__builtin_memcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '__sigsetjmp': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'bcopy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'confstr': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'fclose': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'ferror': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fflush': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fgetc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'fileno': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'free': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'fstat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'getcwd': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'getgroups': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'gethostname': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'getrlimit': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'getrusage': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'memcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'memmove': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'memset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'mremap': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'munmap': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'operator delete': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'operator delete[]': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'pclose': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pipe': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'printf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_destroy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_init': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_lock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_trylock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutex_unlock': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_destroy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_init': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'pthread_mutexattr_settype': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'putc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'qsort': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'read': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'realloc': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'regfree': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigaddset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigdelset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigemptyset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sigfillset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'sprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'std::operator<<': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'strcat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strncat': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'strncpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0, 1}, argument_range_max=4294967295, argument_range_min=0 ), 'tcgetattr': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'time': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'vsnprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'waitpid': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'wmemset': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ) }
external_sources.arguments_of.functions
Table of functions and argument specifiers where the function sets the matched arguments to an external value that must be checked before use. If the table is empty, all non-const pointer parameters of external functions are checked, except for functions listed in theType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}arguments_of.excludedoption.
external_sources.parameters_of
Functions configured as entry points (including main) for which the parameters should be checked before using them. If the set is empty, all entry points are checked.
external_sources.parameters_of.excluded : set[bauhaus.analysis.config.QualifiedName] =
Functions which should be exempt from the set of functions for which the parameters should be checked before using them.set()
external_sources.parameters_of.functions : set[bauhaus.analysis.config.QualifiedName] =
Functions configured as entry points (including main) for which the parameters should be checked before using them. If the set is empty, all entry points are checked.set()
external_sources.return_values_of
Functions for which the return value should be considered an external value that must be checked before use.
external_sources.return_values_of.excluded
Functions which should be exempt from the set of functions for which the return value should be treated as an external value.Type: set[bauhaus.analysis.config.QualifiedName]
Default:
{'__acrt_iob_func', '__builtin_alloca', '__builtin_ctz', '__builtin_ia32_pblendw128', '__builtin_ia32_pshufd', '__builtin_ia32_pshufhw', '__builtin_ia32_pshuflw', '__builtin_ia32_pslldqi128', '__builtin_ia32_psrldqi128', '__builtin_ia32_shufps', '__builtin_isinf', '__builtin_isinff', '__builtin_isnan', '__builtin_isnanf', '__ctype_b_loc', '__ctype_get_mb_cur_max', '__errno_location', '__iob_func', '__sigsetjmp', '_mm256_abs_epi16', '_mm256_abs_epi32', '_mm256_abs_epi8', '_mm256_add_epi16', '_mm256_add_epi32', '_mm256_add_epi64', '_mm256_add_epi8', '_mm256_add_pd', '_mm256_add_ps', '_mm256_adds_epi16', '_mm256_adds_epi8', '_mm256_adds_epu16', '_mm256_adds_epu8', '_mm256_alignr_epi8', '_mm256_and_pd', '_mm256_and_ps', '_mm256_and_si256', '_mm256_blend_epi32', '_mm256_blend_pd', '_mm256_blend_ps', '_mm256_blendv_epi8', '_mm256_blendv_pd', '_mm256_blendv_ps', '_mm256_broadcastsi128_si256', '_mm256_castpd128_pd256', '_mm256_castpd256_pd128', '_mm256_castpd_ps', '_mm256_castpd_si256', '_mm256_castps128_ps256', '_mm256_castps256_ps128', '_mm256_castps_pd', '_mm256_castps_si256', '_mm256_castsi128_si256', '_mm256_castsi256_pd', '_mm256_castsi256_ps', '_mm256_castsi256_si128', '_mm256_cmp_pd', '_mm256_cmp_ps', '_mm256_cmpeq_epi16', '_mm256_cmpeq_epi32', '_mm256_cmpeq_epi64', '_mm256_cmpeq_epi8', '_mm256_cmpgt_epi16', '_mm256_cmpgt_epi32', '_mm256_cmpgt_epi8', '_mm256_cvtepi16_epi32', '_mm256_cvtepi32_epi64', '_mm256_cvtepi32_pd', '_mm256_cvtepi32_ps', '_mm256_cvtepi8_epi16', '_mm256_cvtepi8_epi32', '_mm256_cvtepu16_epi32', '_mm256_cvtepu32_epi64', '_mm256_cvtepu8_epi16', '_mm256_cvtepu8_epi32', '_mm256_cvtpd_epi32', '_mm256_cvtpd_ps', '_mm256_cvtph_ps', '_mm256_cvtps_epi32', '_mm256_cvtps_pd', '_mm256_cvtps_ph', '_mm256_cvttpd_epi32', '_mm256_cvttps_epi32', '_mm256_div_pd', '_mm256_div_ps', '_mm256_extractf128_pd', '_mm256_extractf128_ps', '_mm256_extracti128_si256', '_mm256_fmadd_pd', '_mm256_fmadd_ps', '_mm256_hadd_epi32', '_mm256_hadd_ps', '_mm256_i32gather_epi32', '_mm256_i32gather_epi64', '_mm256_i32gather_pd', '_mm256_i32gather_ps', '_mm256_insertf128_pd', '_mm256_insertf128_ps', '_mm256_inserti128_si256', '_mm256_load_pd', '_mm256_load_ps', '_mm256_load_si256', '_mm256_loadu_pd', '_mm256_loadu_ps', '_mm256_loadu_si256', '_mm256_madd_epi16', '_mm256_max_epi16', '_mm256_max_epi32', '_mm256_max_epi8', '_mm256_max_epu16', '_mm256_max_epu32', '_mm256_max_epu8', '_mm256_max_pd', '_mm256_max_ps', '_mm256_min_epi16', '_mm256_min_epi32', '_mm256_min_epi8', '_mm256_min_epu16', '_mm256_min_epu32', '_mm256_min_epu8', '_mm256_min_pd', '_mm256_min_ps', '_mm256_movemask_epi8', '_mm256_movemask_pd', '_mm256_movemask_ps', '_mm256_mul_epi32', '_mm256_mul_epu32', '_mm256_mul_pd', '_mm256_mul_ps', '_mm256_mulhi_epi16', '_mm256_mulhi_epu16', '_mm256_mullo_epi16', '_mm256_mullo_epi32', '_mm256_or_pd', '_mm256_or_ps', '_mm256_or_si256', '_mm256_packs_epi32', '_mm256_packus_epi32', '_mm256_permute2f128_pd', '_mm256_permute2f128_ps', '_mm256_permute2x128_si256', '_mm256_permute4x64_epi64', '_mm256_permute4x64_pd', '_mm256_permute_ps', '_mm256_permutevar8x32_epi32', '_mm256_permutevar8x32_ps', '_mm256_round_pd', '_mm256_round_ps', '_mm256_rsqrt_ps', '_mm256_sad_epu8', '_mm256_set1_epi16', '_mm256_set1_epi32', '_mm256_set1_epi64x', '_mm256_set1_epi8', '_mm256_set1_pd', '_mm256_set1_ps', '_mm256_set_epi64x', '_mm256_setr_epi16', '_mm256_setr_epi32', '_mm256_setr_epi8', '_mm256_setzero_pd', '_mm256_setzero_ps', '_mm256_setzero_si256', '_mm256_shuffle_epi32', '_mm256_shuffle_epi8', '_mm256_shuffle_pd', '_mm256_slli_epi16', '_mm256_slli_epi32', '_mm256_slli_epi64', '_mm256_slli_si256', '_mm256_sqrt_pd', '_mm256_sqrt_ps', '_mm256_srai_epi16', '_mm256_srai_epi32', '_mm256_srli_epi16', '_mm256_srli_epi32', '_mm256_srli_epi64', '_mm256_srli_si256', '_mm256_sub_epi16', '_mm256_sub_epi32', '_mm256_sub_epi64', '_mm256_sub_epi8', '_mm256_sub_pd', '_mm256_sub_ps', '_mm256_subs_epi16', '_mm256_subs_epi8', '_mm256_subs_epu16', '_mm256_subs_epu8', '_mm256_unpackhi_epi16', '_mm256_unpackhi_epi32', '_mm256_unpackhi_epi64', '_mm256_unpackhi_epi8', '_mm256_unpackhi_pd', '_mm256_unpackhi_ps', '_mm256_unpacklo_epi16', '_mm256_unpacklo_epi32', '_mm256_unpacklo_epi64', '_mm256_unpacklo_epi8', '_mm256_unpacklo_pd', '_mm256_unpacklo_ps', '_mm256_xor_pd', '_mm256_xor_ps', '_mm256_xor_si256', '_mm_add_epi16', '_mm_add_epi32', '_mm_add_epi64', '_mm_add_epi8', '_mm_add_pd', '_mm_add_ps', '_mm_adds_epi16', '_mm_adds_epi8', '_mm_adds_epu16', '_mm_adds_epu8', '_mm_addsub_ps', '_mm_and_pd', '_mm_and_ps', '_mm_and_si128', '_mm_andnot_si128', '_mm_blend_epi16', '_mm_blendv_epi8', '_mm_blendv_pd', '_mm_blendv_ps', '_mm_castpd_ps', '_mm_castpd_si128', '_mm_castps_pd', '_mm_castps_si128', '_mm_castsi128_pd', '_mm_castsi128_ps', '_mm_cmpeq_epi16', '_mm_cmpeq_epi32', '_mm_cmpeq_epi64', '_mm_cmpeq_epi8', '_mm_cmpeq_pd', '_mm_cmpeq_ps', '_mm_cmpge_pd', '_mm_cmpge_ps', '_mm_cmpgt_epi16', '_mm_cmpgt_epi32', '_mm_cmpgt_epi8', '_mm_cmpgt_pd', '_mm_cmpgt_ps', '_mm_cmple_pd', '_mm_cmple_ps', '_mm_cmplt_pd', '_mm_cmplt_ps', '_mm_cmpneq_pd', '_mm_cmpneq_ps', '_mm_cmpord_pd', '_mm_cmpord_ps', '_mm_cvt_ss2si', '_mm_cvtepi16_epi32', '_mm_cvtepi32_epi64', '_mm_cvtepi32_pd', '_mm_cvtepi32_ps', '_mm_cvtepi8_epi16', '_mm_cvtepi8_epi32', '_mm_cvtepu16_epi32', '_mm_cvtepu32_epi64', '_mm_cvtepu8_epi16', '_mm_cvtepu8_epi32', '_mm_cvtpd_epi32', '_mm_cvtpd_ps', '_mm_cvtph_ps', '_mm_cvtps_epi32', '_mm_cvtps_pd', '_mm_cvtps_ph', '_mm_cvtsd_f64', '_mm_cvtsd_si32', '_mm_cvtsi128_si32', '_mm_cvtsi128_si64', '_mm_cvtss_f32', '_mm_cvttpd_epi32', '_mm_cvttps_epi32', '_mm_div_pd', '_mm_div_ps', '_mm_fmadd_pd', '_mm_fmadd_ps', '_mm_hadd_ps', '_mm_load_pd', '_mm_load_ps', '_mm_load_si128', '_mm_load_ss', '_mm_loadh_pi', '_mm_loadl_epi64', '_mm_loadl_pi', '_mm_loadu_pd', '_mm_loadu_ps', '_mm_loadu_si128', '_mm_madd_epi16', '_mm_max_epi16', '_mm_max_epi32', '_mm_max_epi8', '_mm_max_epu16', '_mm_max_epu32', '_mm_max_epu8', '_mm_max_pd', '_mm_max_ps', '_mm_min_epi16', '_mm_min_epi32', '_mm_min_epi8', '_mm_min_epu16', '_mm_min_epu32', '_mm_min_epu8', '_mm_min_pd', '_mm_min_ps', '_mm_movehdup_ps', '_mm_movehl_ps', '_mm_moveldup_ps', '_mm_movelh_ps', '_mm_movemask_epi8', '_mm_movemask_pd', '_mm_movemask_ps', '_mm_mul_epi32', '_mm_mul_epu32', '_mm_mul_pd', '_mm_mul_ps', '_mm_mulhi_epi16', '_mm_mulhi_epu16', '_mm_mullo_epi16', '_mm_mullo_epi32', '_mm_or_pd', '_mm_or_ps', '_mm_or_si128', '_mm_packs_epi16', '_mm_packs_epi32', '_mm_packus_epi16', '_mm_packus_epi32', '_mm_permute_ps', '_mm_popcnt_u32', '_mm_popcnt_u64', '_mm_rsqrt_ps', '_mm_sad_epu8', '_mm_set1_epi16', '_mm_set1_epi32', '_mm_set1_epi64x', '_mm_set1_epi8', '_mm_set1_pd', '_mm_set_epi32', '_mm_set_epi64x', '_mm_set_ps', '_mm_set_ps1', '_mm_set_sd', '_mm_set_ss', '_mm_setr_epi16', '_mm_setr_epi32', '_mm_setr_epi8', '_mm_setr_pd', '_mm_setr_ps', '_mm_setzero_pd', '_mm_setzero_ps', '_mm_setzero_si128', '_mm_shuffle_epi32', '_mm_shuffle_epi8', '_mm_shuffle_ps', '_mm_shufflehi_epi16', '_mm_shufflelo_epi16', '_mm_sll_epi32', '_mm_slli_epi16', '_mm_slli_epi32', '_mm_slli_epi64', '_mm_slli_si128', '_mm_sqrt_pd', '_mm_sqrt_ps', '_mm_srai_epi16', '_mm_srai_epi32', '_mm_srli_epi16', '_mm_srli_epi32', '_mm_srli_epi64', '_mm_srli_si128', '_mm_sub_epi16', '_mm_sub_epi32', '_mm_sub_epi64', '_mm_sub_epi8', '_mm_sub_pd', '_mm_sub_ps', '_mm_subs_epi16', '_mm_subs_epi8', '_mm_subs_epu16', '_mm_subs_epu8', '_mm_unpackhi_epi16', '_mm_unpackhi_epi32', '_mm_unpackhi_epi64', '_mm_unpackhi_epi8', '_mm_unpackhi_pd', '_mm_unpackhi_ps', '_mm_unpacklo_epi16', '_mm_unpacklo_epi32', '_mm_unpacklo_epi64', '_mm_unpacklo_epi8', '_mm_unpacklo_pd', '_mm_unpacklo_ps', '_mm_xor_pd', '_mm_xor_ps', '_mm_xor_si128', 'a64l', 'abs', 'acos', 'atan', 'atan2', 'atof', 'atoi', 'atol', 'calloc', 'close', 'cos', 'cvAlloc', 'dup', 'dup2', 'exp', 'fabs', 'fastMalloc', 'fchmod', 'fchown', 'fcntl', 'fileno', 'floor', 'fork', 'fputs', 'ftell', 'ftruncate', 'fwrite', 'getaddrinfo', 'getdtablesize', 'getegid', 'geteuid', 'getgid', 'getgrent', 'getgroups', 'getpagesize', 'getpgrp', 'getpid', 'getppid', 'getpwent', 'getpwnam', 'getpwuid', 'getservent', 'gettext', 'getuid', 'htonl', 'htons', 'iconv_open', 'inet_addr', 'ippicvMalloc_L', 'iswctype', 'localtime', 'log', 'log10', 'lseek', 'malloc', 'mblen', 'mbrlen', 'mbrtowc', 'mbsnrtowcs', 'mbstowcs', 'memcmp', 'memcpy', 'mmap', 'mremap', 'munmap', 'ntohl', 'ntohs', 'operator new', 'operator new[]', 'operator=', 'pow', 'printf', 'pthread_self', 'rand', 'readlink', 'realloc', 'rmdir', 'sbrk', 'setlocale', 'sigprocmask', 'sin', 'socket', 'sqrt', 'std::abs', 'std::acos', 'std::atan', 'std::atan2', 'std::basic_ostream::operator<<', 'std::floor', 'std::make_error_code', 'std::operator<<', 'std::operator|', 'strchr', 'strchrnul', 'strcmp', 'strcpy', 'strdup', 'strerror', 'strlen', 'strncasecmp', 'strncmp', 'strncpy', 'strnlen', 'strpbrk', 'strrchr', 'strsignal', 'strstr', 'strtod', 'strtoimax', 'strtol', 'strtold', 'strtoul', 'strtoull', 'strtoumax', 'strtouq', 'sysconf', 'tcgetpgrp', 'tcsetattr', 'time', 'tmpnam', 'tolower', 'toupper', 'towlower', 'towupper', 'ttyname', 'umask', 'unlink', 'vsnprintf', 'wcrtomb', 'wcscat', 'wcscpy', 'wcsdup', 'wcslen', 'wcsrtombs', 'wcswidth', 'wctob', 'wctomb', 'wctype', 'wcwidth', 'write'}
external_sources.return_values_of.functions : set[bauhaus.analysis.config.QualifiedName] =
Functions for which the return value should be considered an external value that must be checked before use. If the set is empty, all return values of external functions are checked.set()
functions¶
functions
A dictionary mapping the names of the functions to check, to a tripleType: dict[bauhaus.analysis.config.QualifiedName, typing.Tuple[str, int, typing.Optional[int]]]
Default:
{ '_printf_l': ('printf', 1, 3), 'fprintf': ('printf', 1, 2), 'fscanf': ('scanf', 1, 2), 'printf': ('printf', 0, 1), 'scanf': ('scanf', 0, 1), 'snprintf': ('printf', 2, 3), 'sprintf': ('printf', 1, 2), 'sscanf': ('scanf', 1, 2), 'vfprintf': ('printf', 1, None), 'vfscanf': ('scanf', 1, None), 'vprintf': ('printf', 0, None), 'vscanf': ('scanf', 0, None), 'vsnprintf': ('printf', 2, None), 'vsprintf': ('printf', 1, None), 'vsscanf': ('scanf', 1, None) }
(function_kind, fmt_param_index, arg_start_index) where
function_kind is either printf or scanf,
fmt_param_index is the index of the format-string parameter, and
arg_start_index is the index of the first variadic argument.
is_acceptable_use_in_condition¶
is_acceptable_use_in_condition
If given, this predicate is used to check a condition further that involves the value received from an external source. The predicate receives the following arguments: check: The PIR node of type Conditional_Interface in whose condition the external value is used, or a Relational_Operator using it inside the operands val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value use: The LIR node corresponding to the use The return value should be True iff the use of the external value inside this condition is ok (e.g. because that's a check validating the value).Type: typing.Callable[[bauhaus.ir.Node, bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node], bool] | None
Default:
None
is_relevant_usage¶
is_relevant_usage
If given, this predicate is used to check if a usage of tainted input is relevant for the analysis. This can be used to restrict the analysis to certain types of usages only. The predicate receives the following arguments: val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value use: The LIR node corresponding to the use The return value should be True if the use of the external value inside this condition is relevant, i.e., if an error message should be issued by the rule. If the return value is False, the message is discarded.Type: typing.Callable[[bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node], bool] | None
Default:
None
is_sufficient_preceding_check¶
is_sufficient_preceding_check
If given, this predicate is used to check a condition further that involves the value received from an external source and which happens before the use being checked. It should also check whether the right branch was taken. The predicate receives the following arguments: check: The PIR node of type Conditional_Interface in which's condition the external value is used val: The ExternalValue object representing the value received from an external source node: The PIR node representing the use of the external value inside the condition use: The LIR node for the use being checked (after the condition) branch: The iranalysis block representing the branch taken at the condition The return value should be True iff the condition is sufficiently checking the validity of this external value.Type: typing.Callable[[bauhaus.ir.Node, bauhaus.rules.axivion.expressions.generic.taint_analysis.ExternalValue, bauhaus.ir.Node, bauhaus.ir.Node, _iranalysis.Basic_Block], bool] | None
Default:
None
maximum_reports_per_source_location¶
maximum_reports_per_source_location : int = 10
omit_implicitly_passed_this¶
omit_implicitly_passed_this : bool = True
only_report_arguments¶
only_report_arguments : bool = True
sanitizer_functions¶
sanitizer_functions
Description of sanitizing functions with the number of the sanitized argument.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}
sanitizer_macros¶
sanitizer_macros
Description of sanitizing macros with the number of the sanitized argument.Type: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{}
sinks¶
Description of the possible sinks for which flows of unchecked external values are reported
sinks.excluded
Functions which should be exempt from the set of functions considered as sinksType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{ 'memcpy': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=0 ), 'sprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ) }
sinks.functions
Functions which should be in the set of functions considered as sinksType: dict[bauhaus.analysis.config.QualifiedName, ArgumentSpecifier]
Default:
{ '__builtin___snprintf_chk': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set=set(), argument_range_max=4294967295, argument_range_min=4 ), '_printf_l': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), '_snprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), '_snwprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), '_vsnwprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), 'dprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'fprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'fscanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'fwprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'printf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'scanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'snprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), 'sprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'sscanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'swprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), 'syslog': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vdprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vfprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vfscanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vfwprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'vscanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'vsnprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), 'vsprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vsscanf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={1}, argument_range_max=4294967295, argument_range_min=0 ), 'vswprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={2}, argument_range_max=4294967295, argument_range_min=0 ), 'vwprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ), 'wprintf': bauhaus.rules.axivion.expressions.generic.taint_analysis.ArgumentSpecifier( argument_numbers_set={0}, argument_range_max=4294967295, argument_range_min=0 ) }
use_static_semantic_analysis¶
use_static_semantic_analysis : bool = True
StaticSemanticAnalysis
to be enabled, but will produce less accurate results if it is not.
Option Types¶
These types are used by options listed above:
ArgumentSpecifier¶
Specification of which argument positions to consider: An argument at position x is included if ALL of the following conditions are met: * x is within the specified range: argument_range_min ≤ x ≤ argument_range_max * Either no specific arguments are listed (argument_numbers_set is empty), OR x is explicitly listed in argument_numbers_set Examples: * To target the first 5 variadic arguments of sscanf (positions 2-6): set argument_range_min = 2, argument_range_max = 6, leave argument_numbers_set empty * To target only the format string of sscanf (position 1): set argument_numbers_set = {1} and keep default values for argument_range_min and argument_range_maxargument_numbers_set : set[int] = set()
argument_range_max : int = 4294967295
argument_range_min : int = 0