From 02b6067b8856bf5fe115fb90b24fe134727eb057 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Wed, 24 Aug 2011 11:40:13 +0200 Subject: [PATCH] cgconfigparser: Made YY_FATAL_ERROR really fatal when parsing cgconfig.conf 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 --- 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 28519ffd..bed38714 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 8a99bbc9..7a000159 100644 --- a/src/lex.l +++ b/src/lex.l @@ -17,8 +17,13 @@ #include #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 de437e19..7d683f4b 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -25,6 +25,7 @@ __BEGIN_DECLS #include #include #include +#include /* 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); -- 2.47.2