]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
cgconfigparser: Made YY_FATAL_ERROR really fatal when parsing cgconfig.conf
authorJan Safranek <jsafrane@redhat.com>
Wed, 24 Aug 2011 09:40:13 +0000 (11:40 +0200)
committerJan Safranek <jsafrane@redhat.com>
Wed, 14 Sep 2011 11:21:38 +0000 (13:21 +0200)
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 <jsafrane@redhat.com>
src/config.c
src/lex.l
src/libcgroup-internal.h

index 28519ffdd385388647929411a1ac462115fe793b..bed387147d401baeeb1db99cf790d67ab98f1f19 100644 (file)
@@ -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);
index 8a99bbc91b14541fb739f6117b72cf0d2f9f98c9..7a00015971f25df23517e6f4e92f83a8fc6e3834 100644 (file)
--- a/src/lex.l
+++ b/src/lex.l
 #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
index de437e19300df6e3f4f4935c1787776316a77583..7d683f4b29fd6927b4116867136e5fb1c267b435 100644 (file)
@@ -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);