[rrd-developers] [PATCH] rrdcached enforces no-link policy for base path
kevin brintnall
kbrint at rufus.net
Tue Oct 14 14:37:09 CEST 2008
Now, the daemon will check that a base directory is NOT reached via
symbolic link. Documentation added to illustrate the restriction.
This allows several simplifying (and performance-enhancing) assumptions to
be made elsewhere in the code:
* it ensures that paths resolved in the client via realpath() will match
our data structure keys
* it's possible to generate the correct absolute path when given a
relative path by simply prepending the base directory
* it's not necessary to resolve paths that begin with '/'
---
doc/rrdcached.pod | 12 ++++++++++++
src/rrd_daemon.c | 22 ++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/doc/rrdcached.pod b/doc/rrdcached.pod
index 4d079a9..d8f0c73 100644
--- a/doc/rrdcached.pod
+++ b/doc/rrdcached.pod
@@ -125,6 +125,18 @@ used.
updated by the daemon, assuming the base directory
"/tmp".
+B<WARNING:> The paths up to and including the base directory B<MUST NOT BE>
+symbolic links. In other words, if the base directory is
+specified as:
+
+ -b /base/dir/somewhere
+
+... then B<NONE> of the following should be symbolic links:
+
+ /base
+ /base/dir
+ /base/dir/somewhere
+
=item B<-B>
Only permit writes into the base directory specified in B<-b> (and any
diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
index 8b23e52..511b04e 100644
--- a/src/rrd_daemon.c
+++ b/src/rrd_daemon.c
@@ -2493,6 +2493,7 @@ static int read_options (int argc, char **argv) /* {{{ */
case 'b':
{
size_t len;
+ char base_realpath[PATH_MAX];
if (config_base_dir != NULL)
free (config_base_dir);
@@ -2503,6 +2504,27 @@ static int read_options (int argc, char **argv) /* {{{ */
return (3);
}
+ /* make sure that the base directory is not resolved via
+ * symbolic links. this makes some performance-enhancing
+ * assumptions possible (we don't have to resolve paths
+ * that start with a "/")
+ */
+ if (realpath(config_base_dir, base_realpath) == NULL)
+ {
+ fprintf (stderr, "Invalid base directory '%s'.\n", config_base_dir);
+ return 5;
+ }
+ else if (strncmp(config_base_dir,
+ base_realpath, sizeof(base_realpath)) != 0)
+ {
+ fprintf(stderr,
+ "Base directory (-b) resolved via file system links!\n"
+ "Please consult rrdcached '-b' documentation!\n"
+ "Consider specifying the real directory (%s)\n",
+ base_realpath);
+ return 5;
+ }
+
len = strlen (config_base_dir);
while ((len > 0) && (config_base_dir[len - 1] == '/'))
{
--
1.6.0.2
More information about the rrd-developers
mailing list