diff --git a/CHANGES b/CHANGES index 684ce0b7..b0288064 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ SVN-HEAD libsensors: Add support for instantaneous power sensors Add support for current sensors Fix error propagation during expression evaluation + Detect excessive recursion depth during expression evaluation maxilife scripts: Delete (driver never ported to Linux 2.6) sensord: Accept negative temperatures in RRD database Don't bail out on transient errors (#2330) diff --git a/doc/libsensors-API.txt b/doc/libsensors-API.txt index 8530de9b..06e38606 100644 --- a/doc/libsensors-API.txt +++ b/doc/libsensors-API.txt @@ -20,6 +20,8 @@ given new feature. enum sensors_subfeature_type SENSORS_SUBFEATURE_CURR_MIN_ALARM enum sensors_subfeature_type SENSORS_SUBFEATURE_CURR_MAX_ALARM enum sensors_subfeature_type SENSORS_SUBFEATURE_CURR_BEEP +* Added error value for excessive recursion depth + #define SENSORS_ERR_RECURSION 11 0x401 lm-sensors 3.0.2 to 3.0.3 * Added bus type "virtual": diff --git a/lib/access.c b/lib/access.c index 4e36df9a..231d5355 100644 --- a/lib/access.c +++ b/lib/access.c @@ -1,7 +1,7 @@ /* access.c - Part of libsensors, a Linux library for reading sensor data. Copyright (c) 1998, 1999 Frodo Looijaard - Copyright (C) 2007 Jean Delvare + Copyright (C) 2007, 2008 Jean Delvare This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,9 +29,13 @@ #include "sysfs.h" #include "general.h" +/* We watch the recursion depth for variables only, as an easy way to + detect cycles. */ +#define DEPTH_MAX 8 + static int sensors_eval_expr(const sensors_chip_features *chip_features, const sensors_expr *expr, - double val, double *result); + double val, int depth, double *result); /* Compare two chips name descriptions, to see whether they could match. Return 0 if it does not match, return 1 if it does match. */ @@ -221,8 +225,8 @@ static int sensors_get_ignored(const sensors_chip_name *name, /* Read the value of a subfeature of a certain chip. Note that chip should not contain wildcard values! This function will return 0 on success, and <0 on failure. */ -int sensors_get_value(const sensors_chip_name *name, int subfeat_nr, - double *result) +static int __sensors_get_value(const sensors_chip_name *name, int subfeat_nr, + int depth, double *result) { const sensors_chip_features *chip_features; const sensors_subfeature *subfeature; @@ -230,6 +234,8 @@ int sensors_get_value(const sensors_chip_name *name, int subfeat_nr, double val; int res, i; + if (depth >= DEPTH_MAX) + return -SENSORS_ERR_RECURSION; if (sensors_chip_name_has_wildcards(name)) return -SENSORS_ERR_WILDCARDS; if (!(chip_features = sensors_lookup_chip(name))) @@ -265,11 +271,18 @@ int sensors_get_value(const sensors_chip_name *name, int subfeat_nr, return res; if (!expr) *result = val; - else if ((res = sensors_eval_expr(chip_features, expr, val, result))) + else if ((res = sensors_eval_expr(chip_features, expr, val, depth, + result))) return res; return 0; } +int sensors_get_value(const sensors_chip_name *name, int subfeat_nr, + double *result) +{ + return __sensors_get_value(name, subfeat_nr, 0, result); +} + /* Set the value of a subfeature of a certain chip. Note that chip should not contain wildcard values! This function will return 0 on success, and <0 on failure. */ @@ -315,7 +328,7 @@ int sensors_set_value(const sensors_chip_name *name, int subfeat_nr, to_write = value; if (expr) if ((res = sensors_eval_expr(chip_features, expr, - value, &to_write))) + value, 0, &to_write))) return res; return sensors_write_sysfs_attr(name, subfeature, to_write); } @@ -419,7 +432,7 @@ sensors_get_subfeature(const sensors_chip_name *name, /* Evaluate an expression */ int sensors_eval_expr(const sensors_chip_features *chip_features, const sensors_expr *expr, - double val, double *result) + double val, int depth, double *result) { double res1, res2; int res; @@ -437,15 +450,16 @@ int sensors_eval_expr(const sensors_chip_features *chip_features, if (!(subfeature = sensors_lookup_subfeature_name(chip_features, expr->data.var))) return -SENSORS_ERR_NO_ENTRY; - return sensors_get_value(&chip_features->chip, - subfeature->number, result); + return __sensors_get_value(&chip_features->chip, + subfeature->number, depth + 1, + result); } if ((res = sensors_eval_expr(chip_features, expr->data.subexpr.sub1, - val, &res1))) + val, depth, &res1))) return res; if (expr->data.subexpr.sub2 && (res = sensors_eval_expr(chip_features, expr->data.subexpr.sub2, - val, &res2))) + val, depth, &res2))) return res; switch (expr->data.subexpr.op) { case sensors_add: @@ -504,7 +518,7 @@ static int sensors_do_this_chip_sets(const sensors_chip_name *name) res = sensors_eval_expr(chip_features, chip->sets[i].value, 0, - &value); + 0, &value); if (res) { sensors_parse_error("Error parsing expression", chip->sets[i].lineno); diff --git a/lib/error.c b/lib/error.c index d9509553..7472c59b 100644 --- a/lib/error.c +++ b/lib/error.c @@ -1,7 +1,7 @@ /* error.c - Part of libsensors, a Linux library for reading sensor data. Copyright (c) 1998, 1999 Frodo Looijaard - Copyright (C) 2007 Jean Delvare + Copyright (C) 2007, 2008 Jean Delvare This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ static const char *errorlist[] = { /* SENSORS_ERR_PARSE */ "General parse error", /* SENSORS_ERR_ACCESS_W */ "Can't write", /* SENSORS_ERR_IO */ "I/O error", + /* SENSORS_ERR_RECURSION */ "Evaluation recurses too deep", }; const char *sensors_strerror(int errnum) diff --git a/lib/error.h b/lib/error.h index 8ab30d1e..74a71732 100644 --- a/lib/error.h +++ b/lib/error.h @@ -1,7 +1,7 @@ /* error.h - Part of libsensors, a Linux library for reading sensor data. Copyright (c) 1998, 1999 Frodo Looijaard - Copyright (C) 2007 Jean Delvare + Copyright (C) 2007, 2008 Jean Delvare This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,6 +32,7 @@ #define SENSORS_ERR_PARSE 8 /* General parse error */ #define SENSORS_ERR_ACCESS_W 9 /* Can't write */ #define SENSORS_ERR_IO 10 /* I/O error */ +#define SENSORS_ERR_RECURSION 11 /* Evaluation recurses too deep */ #ifdef __cplusplus extern "C" {