gcc-local - local modifications to gcc
Some OpenBSD platforms use a derivative of gcc 2.95.3, others use a
derivative of gcc 3.3.2. In both cases, the gcc software
comes with specific
modifications for OpenBSD.
- gcc does not search under /usr/local for include files
nor for libraries:
as a system compiler, it only searches the system paths by
default.
- On OpenBSD, the -pthread option should be used to link
threaded code,
isolating the program from operating system details.
- On most architectures, trampoline code marks the smallest possible
area around the trampoline stub executable using mprotect(2), since
the stack area is by default non-executable.
- The -O2 option does not include -fstrict-aliasing, as
this option
causes issues on some legacy code. -fstrict-aliasing is
very unsafe
with code that plays tricks with casts, bypassing the
already weak
type system of C.
- The option -fno-builtin-<function> was backported from
gcc 3.3.2, to
gcc 2.95.3, and can be used without having to differentiate between
both compilers.
- gcc recognizes the extra format attribute syslog, to
better match the
definition of syslog(3), and silence erroneous warnings
when used
with -pedantic.
- Even in 2.95.3, gcc recognizes the attribute __nonnull__, which can
be used to mark arguments that can't be NULL. The
printf format attribute
does not imply __nonnull__ for the format. This
allows for
correct format checking on the err(3) function family.
- gcc recognizes the extra attribute __sentinel__, which
can be used to
mark varargs function that need a NULL pointer to mark
argument termination,
like execl(3). This exposes latent bugs for
64-bit architectures,
where a terminating 0 will expand to a 32-bit
int, and not
a full-fledged 64-bits pointer.
- On some OpenBSD platforms, gcc still uses setjmp(3)/
longjmp(3)-
style exceptions, and so needs extra fixes beyond the
pure 2.95.3 release.
- On a few platforms (mostly a.out), gcc uses a linker
wrapper to write
stubs that call global constructors and destructors.
Those platforms
use gcc 2.95.3, and those calls can be traced using
-Wl,-trace-ctors-
dtors, using syslog_r(3).
- On i386, the optimizer for gcc 2.95.3 features an extra
peephole
which reduces the function prologues enough to allow for
the ramdisk
to fit on one floppy.
- On OpenBSD, gcc comes with the ``ProPolice'' stack protection extension,
which is enabled by default. This extension reorders local
variable declarations and adds stack consistency checks
at run time,
in order to detect stack overflows, and will attempt to
report the
problem in the system logs, and abort the faulting process. It can
be turned off using the -fno-stack-protector commandline
option.
Note that the stack protector relies on some support
code in libc.
Stand-alone programs not linked against libc must either
provide
their own support bits, or use the -fno-stack-protector
option.
- gcc recognizes a new flag, -Wbounded, to perform basic
checks on
functions which accept buffers and sizes. An extra attribute,
__bounded__, has been added to mark functions that can
be checked
this way.
- gcc recognizes a new format attribute, kprintf, to deal
with the extra
format arguments `%b', `%r', and `%z' used in the
OpenBSD kernel.
- gcc does not store its version string in objects. This
behavior can
be restored with -fident.
The __bounded__ attribute is used to type-check functions
whose parameters
pass fixed-length buffers and their sizes. The syntax
for normal
buffers is:
__attribute__ ((__bounded__ ( __buffer__, buffer, length )))
where buffer contains the parameter number (starting from 1)
of the
pointer to the buffer, and length contains the parameter
number of the
buffer length argument.
gcc will emit a warning if the length argument is a constant
larger than
the actual size of the buffer. If the buffer is not a statically declared
array of fixed length, no warnings will be generated.
Refer to
memcpy(3) for an example of a function with this check.
For checking strings, just use __string__ instead of
__buffer__:
__attribute__ ((__bounded__ ( __string__, buffer, length )))
In addition to the checks described above, this also tests
if the length
argument was wrongly derived from a sizeof(void *) operation. strlcpy(3)
is a good example of a string function with this check.
Some functions specify the length as two arguments: the number of elements
and the size of each element. In this case, use the
__size__ attribute:
__attribute__ ((__bounded__ ( __size__, buffer, nmemb, size
)))
where buffer contains the parameter number of the pointer to
the buffer,
nmemb contains the parameter number of the number of members, and size
has the parameter number of the size of each element. The
type checks
performed by __size__ are the same as the __buffer__ attribute. See
fread(3) for an example of this type of function.
If a function accepts a buffer parameter and specifies that
it has to be
of a minimum length, the __minbytes__ attribute can be used:
__attribute__ ((__bounded__ ( __minbytes__, buffer, minsize
)))
where buffer contains the parameter number of the pointer to
the buffer,
and minsize specifies the minimum number of bytes that the
buffer should
be. ctime_r(3) is an example of this type of function.
If -Wbounded is specified with -Wformat, additional checks
are performed
on sscanf(3) format strings. The `%s' fields are checked
for incorrect
bound lengths by checking the size of the buffer associated
with the format
argument.
gcc(1)
http://www.research.ibm.com/trl/projects/security/ssp/
The -Wbounded flag only works with statically allocated
fixed-size
buffers. Since it is applied at compile-time, dynamically
allocated memory
buffers and non-constant arguments are ignored.
The __sentinel__ attribute is not yet fully implemented for
gcc 3.3.2.
OpenBSD 3.6 December 1, 2002
[ Back ] |