Try to prevent direct use of exit(), malloc(), etc
Use `#pragma GCC poison` (supported since GCC 3, maybe earlier) when compiling with GCC to help prevent direct uses being introduced for functions which DOH provides a wrapper for.
This commit is contained in:
parent
6d29260a1a
commit
747a51f095
4 changed files with 50 additions and 16 deletions
|
|
@ -25,6 +25,15 @@
|
||||||
%{
|
%{
|
||||||
#define yylex yylex
|
#define yylex yylex
|
||||||
|
|
||||||
|
/* doh.h uses #pragma GCC posion with GCC to prevent direct calls to certain
|
||||||
|
* standard C library functions being introduced, but those cause errors due
|
||||||
|
* to checks like `#if defined YYMALLOC || defined malloc` in the bison
|
||||||
|
* template code. We can't easily arrange to include headers after that
|
||||||
|
* template code, so instead we disable the problematic poisoning for this
|
||||||
|
* file.
|
||||||
|
*/
|
||||||
|
#define DOH_NO_POISON_MALLOC_FREE
|
||||||
|
|
||||||
#include "swig.h"
|
#include "swig.h"
|
||||||
#include "cparse.h"
|
#include "cparse.h"
|
||||||
#include "preprocessor.h"
|
#include "preprocessor.h"
|
||||||
|
|
@ -34,6 +43,9 @@
|
||||||
#undef alloca
|
#undef alloca
|
||||||
#define alloca Malloc
|
#define alloca Malloc
|
||||||
|
|
||||||
|
#define YYMALLOC Malloc
|
||||||
|
#define YYFREE Free
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Externals
|
* Externals
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,9 @@
|
||||||
#include "swigconfig.h"
|
#include "swigconfig.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Set the namespace prefix for DOH API functions. This can be used to control
|
/* Set the namespace prefix for DOH API functions. This can be used to control
|
||||||
visibility of the functions in libraries */
|
visibility of the functions in libraries */
|
||||||
|
|
@ -278,18 +279,18 @@ extern int DohGetmark(DOH *obj);
|
||||||
|
|
||||||
/* Set the function for DohExit() to call instead of exit().
|
/* Set the function for DohExit() to call instead of exit().
|
||||||
*
|
*
|
||||||
* The registered function can perform clean up, etc and then should call
|
* The registered function can perform clean up, etc. It should simply
|
||||||
* exit(status) to end the process. Bear in mind that this can be called
|
* return when done and then exit() will get called. Bear in mind that
|
||||||
* after malloc() has failed, so avoiding allocating additional memory in
|
* the handler function can be called after malloc() has failed, so it's
|
||||||
* the registered function is a good idea.
|
* a good idea for it to avoid allocating additional memory.
|
||||||
*
|
*
|
||||||
* The registered function is unregistered by DohExit() before calling it to
|
* The registered handler function is unregistered by DohExit() before calling
|
||||||
* avoid the potential for infinite loops.
|
* it to avoid the potential for infinite loops.
|
||||||
*
|
*
|
||||||
* Note: This is sort of like C's atexit(), only for DohExit(). However
|
* Note: This is sort of like C's atexit(), only for DohExit(). However
|
||||||
* only one function can be registered (setting a new function overrides the
|
* only one function can be registered (setting a new function overrides the
|
||||||
* previous one) and the registered function is passed the exit status and
|
* previous one) and the registered function is passed the exit status so can
|
||||||
* should itself call exit().
|
* vary its actions based on that.
|
||||||
*/
|
*/
|
||||||
extern void DohSetExitHandler(void (*new_handler)(int));
|
extern void DohSetExitHandler(void (*new_handler)(int));
|
||||||
extern void DohExit(int status);
|
extern void DohExit(int status);
|
||||||
|
|
@ -477,5 +478,29 @@ extern void DohMemoryDebug(void);
|
||||||
|
|
||||||
#define NIL (char *) NULL
|
#define NIL (char *) NULL
|
||||||
|
|
||||||
|
/* Defines to allow use of poisoned identifiers.
|
||||||
|
*
|
||||||
|
* For DOH-internal use only!
|
||||||
|
*/
|
||||||
|
#define doh_internal_calloc calloc
|
||||||
|
#define doh_internal_exit exit
|
||||||
|
/* doh_internal_free not needed as Free() is a macro defined above. */
|
||||||
|
#define doh_internal_malloc malloc
|
||||||
|
#define doh_internal_realloc realloc
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with
|
||||||
|
* an error rather than return NULL).
|
||||||
|
*/
|
||||||
|
# ifndef DOH_NO_POISON_MALLOC_FREE
|
||||||
|
/* This works around bison's template checking if malloc and free are defined,
|
||||||
|
* which triggers GCC's poison checks.
|
||||||
|
*/
|
||||||
|
# pragma GCC poison malloc free
|
||||||
|
# pragma GCC poison realloc calloc
|
||||||
|
# endif
|
||||||
|
/* Use Exit() instead (which will remove output files on error). */
|
||||||
|
# pragma GCC poison abort exit
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* DOH_H */
|
#endif /* DOH_H */
|
||||||
|
|
|
||||||
|
|
@ -250,9 +250,8 @@ void DohExit(int status) {
|
||||||
*/
|
*/
|
||||||
doh_exit_handler = NULL;
|
doh_exit_handler = NULL;
|
||||||
handler(status);
|
handler(status);
|
||||||
} else {
|
|
||||||
exit(status);
|
|
||||||
}
|
}
|
||||||
|
doh_internal_exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void allocation_failed(size_t n, size_t size) {
|
static void allocation_failed(size_t n, size_t size) {
|
||||||
|
|
@ -275,19 +274,19 @@ static void allocation_failed(size_t n, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DohMalloc(size_t size) {
|
void *DohMalloc(size_t size) {
|
||||||
void *p = malloc(size);
|
void *p = doh_internal_malloc(size);
|
||||||
if (!p) allocation_failed(1, size);
|
if (!p) allocation_failed(1, size);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DohRealloc(void *ptr, size_t size) {
|
void *DohRealloc(void *ptr, size_t size) {
|
||||||
void *p = realloc(ptr, size);
|
void *p = doh_internal_realloc(ptr, size);
|
||||||
if (!p) allocation_failed(1, size);
|
if (!p) allocation_failed(1, size);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DohCalloc(size_t n, size_t size) {
|
void *DohCalloc(size_t n, size_t size) {
|
||||||
void *p = calloc(n, size);
|
void *p = doh_internal_calloc(n, size);
|
||||||
if (!p) allocation_failed(n, size);
|
if (!p) allocation_failed(n, size);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1417,6 +1417,4 @@ static void SWIG_exit_handler(int status) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(status);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue