Skip to content

Commit

Permalink
Add func-level OSC-METRICS for GNU fortify-source compiling
Browse files Browse the repository at this point in the history
  • Loading branch information
yonhan3 committed Dec 18, 2020
1 parent 928aef0 commit a71741e
Show file tree
Hide file tree
Showing 20 changed files with 2,682 additions and 81 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Table of Contents
* [Overview](#Overview)
* [Design Considerations](#Design-Considerations)
* [Relationship to FORTIFY_SOURCE](#Relationship-to-FORTIFY_SOURCE)
* [Metric-only Mode for FORTIFY_SOURCE](#Metric-only-Mode-for-FORTIFY_SOURCE)
* [How to Build OpenOSC Library](#How-to-Build-OpenOSC-Library)
* [How to Build Packages with OpenOSC Library](#How-to-Build-Packages-with-OpenOSC-Library)
* [Tested Platforms](#Tested-Platforms)
Expand Down Expand Up @@ -177,6 +178,68 @@ Here is a comparison summary table:
| Logging | No syslog | Syslog/Configurable |
| Cover new routine | Not easy | Easy |

Metric-only Mode for FORTIFY_SOURCE
------------------------------
The OpenOSC OSC-METRICS feature has been enhanced to work with FORTIFY_SOURCE
feature enabled.

It is enabled by adding `-DOPENOSC_METRIC_ONLY_MODE` option to CFLAGS.

CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -D_FORTIFY_SOURCE=2"

This does not turn on OSC-METRICS for objsize/copylen. If you want it, add the
OPENOSC_METRIC_OBJSIZE_ENABLED flag.

CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -DOPENOSC_METRIC_OBJSIZE_ENABLED -D_FORTIFY_SOURCE=2"

This will generate the same OSC-METRICS watermarks for the compiled binary
file with the OPENOSC_METRIC_FEATURE_ENABLED flag. And you can use the same
tools/oscmetrics.py script to decode the OSC-METRICS watermarks.

With this OPENOSC_METRIC_ONLY_MODE flag, the memory/string functions will
always be mapped to itself, except for the addition of OSC-METRICS. The
generated assembly/binary code should also be the same as before, except for
the addition of OSC-METRICS. Of course, out-of-order generation of some assembly
instructions are expected, and still considered the same code.

The nice thing about this metric-only mode is that you don't need to build the
libopenosc.so library. You don't need to change your linking LDFLAGS, since you
don't link with any additional library. The only change required is CFLAGS.

Note this Metric-only mode also works without FORTIFY_SOURCE feature. It will
map all functions to themselves, except for the addition of OSC-METRICS. There
is no need to change LDFLAGS and no need to build the libopenosc.so library.

CFLAGS += "-include openosc.h -DOPENOSC_METRIC_ONLY_MODE -U_FORTIFY_SOURCE"

There are multiple flags to control the set of memory/string functions to
cover. For example, defining OPENOSC_DISABLE_SOCKET_H_FUNCS will not cover
all functions declared in the sys/socket.h header file, and defining the
OPENOSC_DISABLE_STDIO_H_FUNCS flag will not cover all functions in the stdio.h
header file. Defining OPENOSC_POLL_DISABLE will not cover the poll function.

You can also control the level of OSC-METRICS details. For example, you
can define OPENOSC_NOMAP_METRIC_ONLY to always map all functions to CASE0,
i.e., the NOMAP case, instead of more detailed CASE1/CASE2/CASE3/CASE4,
which correnspond to Safe/Overflow/Runtime-protection/Unknown cases,
respectively. This can help quickly find the occurrences of all function
invocations in your code. By default, source buffer overread feature is ON,
but you can define the OPENOSC_SRC_OVERREAD_DISABLE flag to turn if off.

One disadvantage of this Metric-only mode is: it can suppress some
compile-time warning messages that are defined by function attributes
of the OpenOSC covered functions, for example, the warn-unused-result
or nonnull function attribute.

The clang compiler seems to implement its fortify-source buffer-overflow warning
messages with function attributes, thus the buffer-overflow warnings messages
are also suppressed with the Metric-only mode in clang. If clang can also check
the warning condition in the optimization phase, in addition to the front-end
(pre-optimization phase), then this issue can be fixed.

The gcc and icc compiler have no such issue, and are able to report compile-time
buffer-overflow warning messages, with Metric-only mode.

How to Build OpenOSC Library
----------------------------
The build system for the OpenOSC library is the well known GNU build system,
Expand Down Expand Up @@ -319,6 +382,11 @@ Known Issues
However, OPENOSC_METRIC_OBJSIZE_ENABLED impacts the compilation performance
significantly, especially for Clang.

3. OPENOSC_METRIC_ONLY_MODE suppresses some compile-time warning messages that
are implemented by function attributes of the covered functions, like
-Wunused-result. Fortify-source buffer-overflow warnings are suppressed for
clang, but not for gcc/icc.

References
----------
- [1] OpenOSC: Open Source Object Size Checking Library With Built-in
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.4
1.0.5
20 changes: 10 additions & 10 deletions configure
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for openosc 1.0.4.
# Generated by GNU Autoconf 2.69 for openosc 1.0.5.
#
# Report bugs to <yonhan@cisco.com>.
#
Expand Down Expand Up @@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='openosc'
PACKAGE_TARNAME='openosc'
PACKAGE_VERSION='1.0.4'
PACKAGE_STRING='openosc 1.0.4'
PACKAGE_VERSION='1.0.5'
PACKAGE_STRING='openosc 1.0.5'
PACKAGE_BUGREPORT='yonhan@cisco.com'
PACKAGE_URL=''

Expand Down Expand Up @@ -1329,7 +1329,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures openosc 1.0.4 to adapt to many kinds of systems.
\`configure' configures openosc 1.0.5 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

Expand Down Expand Up @@ -1399,7 +1399,7 @@ fi

if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of openosc 1.0.4:";;
short | recursive ) echo "Configuration of openosc 1.0.5:";;
esac
cat <<\_ACEOF

Expand Down Expand Up @@ -1508,7 +1508,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
openosc configure 1.0.4
openosc configure 1.0.5
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
Expand Down Expand Up @@ -1998,7 +1998,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by openosc $as_me 1.0.4, which was
It was created by openosc $as_me 1.0.5, which was
generated by GNU Autoconf 2.69. Invocation command line was

$ $0 $@
Expand Down Expand Up @@ -2861,7 +2861,7 @@ fi

# Define the identity of the package.
PACKAGE='openosc'
VERSION='1.0.4'
VERSION='1.0.5'


cat >>confdefs.h <<_ACEOF
Expand Down Expand Up @@ -16738,7 +16738,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by openosc $as_me 1.0.4, which was
This file was extended by openosc $as_me 1.0.5, which was
generated by GNU Autoconf 2.69. Invocation command line was

CONFIG_FILES = $CONFIG_FILES
Expand Down Expand Up @@ -16804,7 +16804,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
openosc config.status 1.0.4
openosc config.status 1.0.5
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

Expand Down
32 changes: 28 additions & 4 deletions include/openosc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@

#include "openosc_header_metric.h"

/* define the object size checking type in builtin function */
#define OSC_OBJECT_SIZE_CHECK_0 0
#define OSC_OBJECT_SIZE_CHECK_1 1

#ifndef NULL
#define NULL ((void *)0)
#endif

/* Source over-read is enabled by default, but can be disabled */
#ifndef OPENOSC_SRC_OVERREAD_DISABLE
#define _OPENOSC_SRC_OVERREAD_ENABLED
#endif

/*
* There are two methods to remap a function to openosc_* function:
* 1. The function redirect via ASM-label mechanism.
Expand Down Expand Up @@ -40,10 +53,25 @@
#define NO_OBJECT_SIZE_CHECKING
#endif

#ifdef OPENOSC_SKIP_CSTRING_HEADER
#ifdef __cplusplus
#if OPENOSC_MAPPING_METHOD == OPENOSC_FUNC_MACRO_REDEFINE_METHOD || defined OPENOSC_METRIC_ONLY_MODE
/* define the below macro to avoid including <cstring> header, which #undef >10 memcpy/strcpy functions */
#ifndef _GLIBCXX_CSTRING
#define _GLIBCXX_CSTRING 2
#endif
#endif
#endif
#endif


#ifdef NO_OBJECT_SIZE_CHECKING
#pragma message ("OSC-WARN-DISABLED: OpenOSC disabled due to NO_OBJECT_SIZE_CHECKING, contact OpenOSC package owner for guidance")
#elif defined __ASSEMBLER__
#pragma message ("OSC-WARN-ASM: OpenOSC disabled due to __ASSEMBLER__, contact OpenOSC package owner for guidance")
#elif defined OPENOSC_METRIC_ONLY_MODE
#pragma message ("OSC-WARN-METRICONLY: OpenOSC disabled due to METRIC_ONLY_MODE, contact OpenOSC package owner for guidance")
#include "openosc_metric_only.h"
#elif !defined __OPTIMIZE__
/* #error "OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance" */
#pragma message ("OSC-ERR-NOOPT: OpenOSC disabled due to NO OPTIMIZATION, contact OpenOSC package owner for guidance")
Expand Down Expand Up @@ -148,10 +176,6 @@
**********************************************************************************
**********************************************************************************/

/* define the object size checking type in builtin function */
#define OSC_OBJECT_SIZE_CHECK_0 0
#define OSC_OBJECT_SIZE_CHECK_1 1

#include "openosc_map.h"

#ifdef HAS_SAFEC
Expand Down
2 changes: 2 additions & 0 deletions include/openosc_extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
typedef __builtin_va_list va_list;
#endif

#ifndef OSC_THROW
#ifdef __cplusplus
#define OSC_THROW __THROW
#else
#define OSC_THROW
#endif
#endif

/* libC APIs */
extern void *memcpy(void *dst, const void *src, size_t len) OSC_THROW;
Expand Down
4 changes: 0 additions & 4 deletions include/openosc_fortify.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,6 @@
#endif


/* Source over-read is enabled by default, but can be disabled */
#ifndef OPENOSC_SRC_OVERREAD_DISABLE
#define _OPENOSC_SRC_OVERREAD_ENABLED
#endif
/* Errors are reported at compile-time unless you disable it explicitly */
#ifndef OPENOSC_OVERFLOW_ERROR_OUT_DISABLE
/* Do we want to error out at compile-time when detecting overflow/overread */
Expand Down
2 changes: 2 additions & 0 deletions include/openosc_fortify_extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
typedef __builtin_va_list va_list;
#endif

#ifndef OSC_THROW
#ifdef __cplusplus
#define OSC_THROW __THROW
#else
#define OSC_THROW
#endif
#endif


/* The below data type forward declarations are required */
Expand Down
4 changes: 4 additions & 0 deletions include/openosc_fortify_redefine_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,8 @@ openosc_gethostname (char *name, size_t len)
#define gethostname(name, len) openosc_gethostname(name, len)


#ifndef OPENOSC_GETS_DISABLE

#ifndef __cplusplus
/* Mapping for gets */

Expand All @@ -1123,6 +1125,8 @@ openosc_gets (char *s)
#define gets(s) openosc_gets(s)
#endif /* __cplusplus */

#endif /* OPENOSC_GETS_DISABLE */


/* Mapping for getwd */

Expand Down
4 changes: 4 additions & 0 deletions include/openosc_fortify_redefine_nomap.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ openosc_gethostname (char *name, size_t len)
#define gethostname(name, len) openosc_gethostname(name, len)


#ifndef OPENOSC_GETS_DISABLE

/* Mapping for gets */

static inline __attribute__ ((always_inline))
Expand All @@ -318,6 +320,8 @@ openosc_gets (char *s)
#undef gets
#define gets(s) openosc_gets(s)

#endif /* OPENOSC_GETS_DISABLE */


/* Mapping for getwd */

Expand Down
4 changes: 4 additions & 0 deletions include/openosc_fortify_redirect_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,8 @@ __clang_warn_or_error_if(__size_too_small (__bos1, name, len), __dst_overflow_ms
}


#ifndef OPENOSC_GETS_DISABLE

/* Mapping for gets */

extern char *
Expand All @@ -727,6 +729,8 @@ gets (char * __pass_objsize1 s)
#endif
}

#endif /* OPENOSC_GETS_DISABLE */


/* Mapping for getwd */

Expand Down
4 changes: 4 additions & 0 deletions include/openosc_fortify_redirect_nomap.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ __NTH (gethostname(char *name, size_t len))
}


#ifndef OPENOSC_GETS_DISABLE

/* Mapping for gets */

extern char * __REDIRECT (__openosc_gets_alias,
Expand All @@ -287,6 +289,8 @@ gets(char *s)
return (GETS_NOMAP_CASE __openosc_gets_alias(s));
}

#endif /* OPENOSC_GETS_DISABLE */


/* Mapping for getwd */

Expand Down
12 changes: 0 additions & 12 deletions include/openosc_map_metric.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@
#ifndef __OPENOSC_MAP_METRIC_H__
#define __OPENOSC_MAP_METRIC_H__

#ifdef OPENOSC_HEADER_METRIC_FEATURE_ENABLED

/* always insert a magic word if osc_map.h is included */
#if defined __BIG_ENDIAN__ || defined __BIG_ENDIAN || (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define MAGIC_OSC_MAP_H_INCLUDED 0x80818d8f80818d8e
#else
#define MAGIC_OSC_MAP_H_INCLUDED 0x8e8d81808f8d8180
#endif
long long int __attribute__((weak)) rtd_osc_map_h_included_int = MAGIC_OSC_MAP_H_INCLUDED;

#endif /* OPENOSC_HEADER_METRIC_FEATURE_ENABLED */

#ifdef OPENOSC_METRIC_FEATURE_ENABLED

#include "openosc_metric_objsize.h"
Expand Down
Loading

0 comments on commit a71741e

Please sign in to comment.