Index: bootstat_log.c |
diff --git a/bootstat_log.c b/bootstat_log.c |
index 64bfe5dcc171814267a337fb7ab5b7c779efcc84..31565ee17b99bfb1b6c82b12ba6301a511fcce3a 100644 |
--- a/bootstat_log.c |
+++ b/bootstat_log.c |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
@@ -9,8 +9,10 @@ |
#include "bootstat_test.h" |
#include <assert.h> |
+#include <errno.h> |
#include <stddef.h> |
#include <stdio.h> |
+#include <string.h> |
#include <sys/fcntl.h> |
#include <sys/param.h> |
@@ -19,9 +21,22 @@ |
#include <unistd.h> |
// |
-// Default path to directory where output statistics will be stored. |
+// Variables relating to the directory where output statistics will |
+// be stored. |
// |
+static char output_directory_buffer[PATH_MAX+1]; |
static const char kDefaultOutputDirectoryName[] = "/tmp"; |
+static const char *output_directory_name = kDefaultOutputDirectoryName; |
+ |
+// The longest path we allow to be stored in output_directory_buffer. |
+// The buffer is filled by the snprintf() in append_logdata() (the |
+// format string is "%s/%s-%.*s"). |
+// |
+// The "+ 2" in the formula accounts for '\0' characters counted in |
+// BOOTSTAT_MAX_EVENT_LEN and the 'sizeof' expression. |
+// |
+const int kMaxOutputDirectoryPath = (sizeof(output_directory_buffer) - |
+ BOOTSTAT_MAX_EVENT_LEN - sizeof("/uptime-") + 1); |
// |
// Paths to the statistics files we snapshot as part of the data to |
@@ -37,10 +52,10 @@ static const char kDefaultDiskStatisticsFileName[] = "/sys/block/mmcblk0/stat"; |
#error "unknown processor type?" |
#endif |
-static const char *output_directory_name = kDefaultOutputDirectoryName; |
static const char *uptime_statistics_file_name = |
kDefaultUptimeStatisticsFileName; |
-static const char *disk_statistics_file_name = kDefaultDiskStatisticsFileName; |
+static const char *disk_statistics_file_name = |
+ kDefaultDiskStatisticsFileName; |
static void append_logdata(const char* input_path, |
const char* output_name_prefix, |
@@ -98,12 +113,35 @@ void bootstat_log(const char* event_name) |
} |
-void bootstat_set_output_directory(const char* dirname) |
+int bootstat_set_output_directory(const char* dirname) |
{ |
- if (dirname != NULL) |
- output_directory_name = dirname; |
- else |
+ int rv; |
+ char namebuffer[kMaxOutputDirectoryPath + 3]; |
+ |
+ if (dirname == NULL) { |
output_directory_name = kDefaultOutputDirectoryName; |
+ return 0; |
+ } |
+ |
+ if (strlen(dirname) > kMaxOutputDirectoryPath) { |
+ errno = ENAMETOOLONG; |
+ return -1; |
+ } |
+ |
+ // We test for "%s/." rather than "%s" as a cheap way to force |
+ // euidaccess() to confirm that the path is a directory, in |
+ // addition to being writable and executable. |
+ // |
+ // sprintf() is safe, because we checked strlen() above. |
+ sprintf(namebuffer, "%s/.", dirname); |
+ rv = euidaccess(namebuffer, W_OK | X_OK); |
+ if (rv < 0) { |
+ return -1; |
+ } |
+ |
+ strcpy(output_directory_buffer, dirname); |
+ output_directory_name = output_directory_buffer; |
+ return 0; |
} |