The error macro should stop all processing, otherwise some NULL pointers might get dereferenced (e.g. lex.c:1323). It uses setjmp/longjmp to return from depths of the bison/lex routines. As obvious consequence, all memory allocated in the parsers is lost and is never freed. Still, it should be better than exit() I proposed before.
Changelog: - use setjmp/longjmp instead of exit() Signed-off-by: Jan Safranek <jsafr...@redhat.com> --- src/config.c | 12 +++++++++++- src/lex.l | 7 ++++++- src/libcgroup-internal.h | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 28519ff..bed3871 100644 --- a/src/config.c +++ b/src/config.c @@ -741,6 +741,7 @@ int cgroup_config_load_config(const char *pathname) int namespace_enabled = 0; int mount_enabled = 0; yyin = fopen(pathname, "re"); + int ret; if (!yyin) { cgroup_dbg("Failed to open file %s\n", pathname); @@ -754,7 +755,16 @@ int cgroup_config_load_config(const char *pathname) init_cgroup_table(config_cgroup_table, MAX_CGROUPS); - if (yyparse() != 0) { + /* + * Parser calls longjmp() on really fatal error (like out-of-memory). + */ + ret = setjmp(parser_error_env); + if (!ret) + ret = yyparse(); + if (ret) { + /* + * Either yyparse failed or longjmp() was called. + */ cgroup_dbg("Failed to parse file %s\n", pathname); fclose(yyin); free(config_cgroup_table); diff --git a/src/lex.l b/src/lex.l index 8a99bbc..7a00015 100644 --- a/src/lex.l +++ b/src/lex.l @@ -17,8 +17,13 @@ #include <libcgroup-internal.h> #include "parse.h" int line_no = 1; +jmp_buf parser_error_env; -#define YY_FATAL_ERROR(msg) fprintf(stderr, "%s\n", msg) +#define YY_FATAL_ERROR(msg) \ + do { \ + fprintf(stderr, "%s\n", msg); \ + longjmp(parser_error_env, 1); \ + } while(0); %} %option nounput noinput diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index de437e1..7d683f4 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -25,6 +25,7 @@ __BEGIN_DECLS #include <pthread.h> #include <sys/stat.h> #include <sys/types.h> +#include <setjmp.h> /* Maximum number of mount points/controllers */ #define MAX_MNT_ELEMENTS 8 @@ -185,6 +186,11 @@ struct cgroup_dictionary_iterator { */ extern __thread int last_errno; +/** + * 'Exception handler' for lex parser. + */ +extern jmp_buf parser_error_env; + /* Internal API */ char *cg_build_path(const char *name, char *path, const char *type); int cgroup_get_uid_gid_from_procfs(pid_t pid, uid_t *euid, gid_t *egid); ------------------------------------------------------------------------------ EMC VNX: the world's simplest storage, starting under $10K The only unified storage solution that offers unified management Up to 160% more powerful than alternatives and 25% more efficient. Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel