Skip to content

Commit

Permalink
check for internal memory bounds with new flag "memory-check" (implie…
Browse files Browse the repository at this point in the history
…d with --debug)

related to [bugs:#896]

some validation of internal memory used during CALL; this can help in finding otherwise hard to diagnose overwrite of memory and as it is only done on CALL has a much smaller footprint than -fec=bounds (as both check different aspects at different places it is also reasonable to use both)

cobc:
* flag.def, cobc.c (cobc_deciph_memory_check), tree.h: new compile flag -fmemory-check, implied with --debug
* typeck.c (cb_emit_call), tree.h (cb_field): new field attribute flag_used_in_call
* codegen.c (output_local_base_cache, output_nonlocal_base_cache): generate fencing data fields for fields with flag_used_in_call
* codegen.c (output_call_cache): generate fencing data fields for cob_call_union fields (call pointers)
* codegen.c (output_memory_check_call): new function to output generate fencing data fields for flag_used_in_call
* codeoptim.def, codeoptim.c, codegen.c: new entry COB_CHK_MEMORYFENCE

additional:
* codegen.c: only increment/decrement output_indent_level by indent_adjust_level
* restored some parts of codeoptim.c done by Ron in [r3542] which somehow got lost in 3.x



libcob:
* common.c (cob_check_fence), common.h: new function to check for writing outside of COBOL data, triggered with compile option -fmemory-check
* statement.def (STMT_BEFORE_CALL, STMT_BEFORE_UDF): new internal statements, currently used for cob_check_fence

additional:
* common.c (b2i): include marker for invalid data (previously not set)
  • Loading branch information
sf-mensch committed Jul 10, 2023
1 parent 4e7a61d commit ccd3b7f
Show file tree
Hide file tree
Showing 15 changed files with 537 additions and 84 deletions.
10 changes: 10 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ NEWS - user visible changes -*- outline -*-
the origin of entrypoints and PERFORM, this is used for the internal
stack trace on abort and can be used for improved source level debugging

** new flag -fmemory-check (implied with --debug) to do some validation
of internal memory used during CALL; this can help in finding otherwise
hard to diagnose overwrite of memory and as it is only done on CALL
has a much smaller footprint than -fec=bounds (as both check different
aspects at different places it is also reasonable to use both)

** the option -g does no longer imply -fno-remove-unreachable; if you want to
keep those in you need to explicit specify this

Expand Down Expand Up @@ -408,6 +414,8 @@ NEWS - user visible changes -*- outline -*-
or to use an explicit format (cut at 26 characters, may raise false-positives
in listing tests) e.g. date only `-DLISTING_TIMESTAMP_FORMAT="%Y-%m-%d"`

** new compile options to adjust the listing, see above

* More notable changes

** in 64-bit environments, the maximum field size was increased from
Expand Down Expand Up @@ -494,6 +502,8 @@ NEWS - user visible changes -*- outline -*-
* compile from stdin
* NIST: OBNC1M.CBL false positive (the test runner uses a nonportable way of
emulating a program kill)
* if build with -fsanitize, then some tests will fail; while we accept patches
to improve that, we don't consider the failing tests as bug in GnuCOBOL

** the recent additions of ">> TURN" and "variable LIKE variable" may not work
as expected in all cases
Expand Down
23 changes: 22 additions & 1 deletion cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@

2023-07-10 Simon Sobisch <[email protected]>

check for internal memory bounds with new flag "memory-check"
* flag.def, cobc.c (cobc_deciph_memory_check), tree.h: new compile
flag -fmemory-check, implied with --debug
* typeck.c (cb_emit_call), tree.h (cb_field): new field attribute
flag_used_in_call
* codegen.c (output_local_base_cache, output_nonlocal_base_cache):
generate fencing data fields for fields with flag_used_in_call
* codegen.c (output_call_cache): generate fencing data fields for
cob_call_union fields (call pointers)
* codegen.c (output_memory_check_call): new function to output
generate fencing data fields for flag_used_in_call
* codeoptim.def, codeoptim.c, codegen.c: new entry
COB_CHK_MEMORYFENCE

additional
* codegen.c: only increment/decrement output_indent_level by
indent_adjust_level

2023-07-07 Simon Sobisch <[email protected]>

common preparser cleanup
Expand Down Expand Up @@ -2635,7 +2655,8 @@

* codeoptim.def (COB_GET_NUMDISPS), codeoptim.c, codegen.c: new routine
to convert signed DISPLAY into binary value;
use of register attribute for cob_get_numdisp + cob_get_numdisps
* codeoptim.def (cob_get_numdisp, cob_get_numdisps): use of register
attribute and skipping of leading zeroes

2020-04-23 Simon Sobisch <[email protected]>

Expand Down
47 changes: 47 additions & 0 deletions cobc/cobc.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ enum compile_level {
#define CB_FLAG_GETOPT_NO_DUMP 13
#define CB_FLAG_GETOPT_EBCDIC_TABLE 14
#define CB_FLAG_GETOPT_DEFAULT_COLSEQ 15
#define CB_FLAG_MEMORY_CHECK 16


/* Info display limits */
Expand Down Expand Up @@ -1954,6 +1955,42 @@ cobc_deciph_optarg (const char *p, const int allow_quote)
return (int)n;
}

/* decipher a value for the memory-check flag,
directly setting cb_flag_memory_check,
returns -1 on error */
static int
cobc_deciph_memory_check (const char *p)
{
char buff[8] = { 0 };
const size_t len = strlen (p);
size_t i;

if (len > sizeof(buff)) {
return -1;
}
for (i = 0; i < len; ++i) {
buff[i] = cb_toupper (p[i]);
}

if (len == 3 && memcmp ("ALL", buff, 3) == 0) {
cb_flag_memory_check = CB_MEMCHK_ALL;
return 0;
}
if (len == 4 && memcmp ("NONE", buff, 4) == 0) {
cb_flag_memory_check = CB_MEMCHK_NONE;
return 0;
}
if (len == 5 && memcmp ("USING", buff, 5) == 0) {
cb_flag_memory_check = CB_MEMCHK_USING;
return 0;
}
if (len == 7 && memcmp ("POINTER", buff, 7) == 0) {
cb_flag_memory_check = CB_MEMCHK_POINTER;
return 0;
}
return -1;
}

/* exit to OS before processing a COBOL/C source file */
DECLNORET static void COB_A_NORETURN
cobc_early_exit (int ret_code)
Expand Down Expand Up @@ -3231,6 +3268,7 @@ process_command_line (const int argc, char **argv)
cb_flag_source_location = 1;
cb_flag_stack_extended = 1;
cb_flag_stack_check = 1;
cb_flag_memory_check = CB_MEMCHK_ALL;
cobc_wants_debug = 1;
break;

Expand Down Expand Up @@ -3842,6 +3880,15 @@ process_command_line (const int argc, char **argv)
}
break;

case CB_FLAG_MEMORY_CHECK: /* 16 */
/* -fmemory-check=<scope> : */
if (!cob_optarg) {
cb_flag_memory_check = CB_MEMCHK_ALL;
} else if (cobc_deciph_memory_check (cob_optarg)) {
cobc_err_exit (COBC_INV_PAR, "-fmemory-check");
}
break;

case 'A':
/* -A <xx> : Add options to C compile phase */
COBC_ADD_STR (cobc_cflags, " ", cob_optarg, NULL);
Expand Down
Loading

0 comments on commit ccd3b7f

Please sign in to comment.