Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: user_collector.cc

Issue 4603001: crash-reporter: Avoid writing through symlinks. (Closed) Base URL: http://git.chromium.org/git/crash-reporter.git@master
Patch Set: Respond to review Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « user_collector.h ('k') | user_collector_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "crash-reporter/user_collector.h" 5 #include "crash-reporter/user_collector.h"
6 6
7 #include <fcntl.h> // For creat.
8 #include <grp.h> // For struct group. 7 #include <grp.h> // For struct group.
9 #include <pwd.h> // For struct passwd. 8 #include <pwd.h> // For struct passwd.
10 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS. 9 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS.
11 #include <sys/wait.h> // For waitpid.
12 #include <unistd.h> // For execv and fork.
13 10
14 #include <string> 11 #include <string>
15 #include <vector> 12 #include <vector>
16 13
17 #include "base/eintr_wrapper.h"
18 #include "base/file_util.h" 14 #include "base/file_util.h"
19 #include "base/logging.h" 15 #include "base/logging.h"
20 #include "base/string_util.h" 16 #include "base/string_util.h"
21 #include "crash-reporter/system_logging.h" 17 #include "crash-reporter/system_logging.h"
22 #include "gflags/gflags.h" 18 #include "gflags/gflags.h"
23 19
24 #pragma GCC diagnostic ignored "-Wstrict-aliasing" 20 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
25 DEFINE_bool(core2md_failure_test, false, "Core2md failure test"); 21 DEFINE_bool(core2md_failure_test, false, "Core2md failure test");
26 DEFINE_bool(directory_failure_test, false, "Spool directory failure test"); 22 DEFINE_bool(directory_failure_test, false, "Spool directory failure test");
27 DEFINE_string(filter_in, "", 23 DEFINE_string(filter_in, "",
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 const std::string &exec) { 165 const std::string &exec) {
170 FilePath crash_path; 166 FilePath crash_path;
171 logger_->LogInfo("Writing conversion problems as separate crash report."); 167 logger_->LogInfo("Writing conversion problems as separate crash report.");
172 if (!GetCreatedCrashDirectoryByEuid(0, &crash_path, NULL)) { 168 if (!GetCreatedCrashDirectoryByEuid(0, &crash_path, NULL)) {
173 logger_->LogError("Could not even get log directory; out of space?"); 169 logger_->LogError("Could not even get log directory; out of space?");
174 return; 170 return;
175 } 171 }
176 std::string dump_basename = FormatDumpBasename(exec, time(NULL), pid); 172 std::string dump_basename = FormatDumpBasename(exec, time(NULL), pid);
177 FilePath log_path = GetCrashPath(crash_path, dump_basename, "log"); 173 FilePath log_path = GetCrashPath(crash_path, dump_basename, "log");
178 FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta"); 174 FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta");
179 file_util::WriteFile(log_path, 175 // We must use WriteNewFile instead of file_util::WriteFile as we do
180 error_log_.data(), 176 // not want to write with root access to a symlink that an attacker
181 error_log_.length()); 177 // might have created.
178 WriteNewFile(log_path, error_log_.data(), error_log_.length());
182 AddCrashMetaData("sig", kCollectionErrorSignature); 179 AddCrashMetaData("sig", kCollectionErrorSignature);
183 WriteCrashMetaData(meta_path, exec, log_path.value()); 180 WriteCrashMetaData(meta_path, exec, log_path.value());
184 } 181 }
185 182
186 bool UserCollector::CopyOffProcFiles(pid_t pid, 183 bool UserCollector::CopyOffProcFiles(pid_t pid,
187 const FilePath &container_dir) { 184 const FilePath &container_dir) {
188 if (!file_util::CreateDirectory(container_dir)) { 185 if (!file_util::CreateDirectory(container_dir)) {
189 LogCollectionError(StringPrintf("Could not create %s", 186 LogCollectionError(StringPrintf("Could not create %s",
190 container_dir.value().c_str())); 187 container_dir.value().c_str()));
191 return false; 188 return false;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if (file_util::CopyFile(stdin_path, core_path)) { 245 if (file_util::CopyFile(stdin_path, core_path)) {
249 return true; 246 return true;
250 } 247 }
251 248
252 LogCollectionError("Could not write core file"); 249 LogCollectionError("Could not write core file");
253 // If the file system was full, make sure we remove any remnants. 250 // If the file system was full, make sure we remove any remnants.
254 file_util::Delete(core_path, false); 251 file_util::Delete(core_path, false);
255 return false; 252 return false;
256 } 253 }
257 254
258 int UserCollector::ForkExecAndPipe(std::vector<const char *> &arguments,
259 const char *output_file) {
260 // Copy off a writeable version of arguments.
261 scoped_array<char*> argv(new char *[arguments.size() + 1]);
262 int total_args_size = 0;
263 for (size_t i = 0; i < arguments.size(); ++i) {
264 if (arguments[i] == NULL) {
265 logger_->LogError("Bad parameter");
266 return -1;
267 }
268 total_args_size += strlen(arguments[i]) + 1;
269 }
270 scoped_array<char> buffer(new char[total_args_size]);
271 char *buffer_pointer = &buffer[0];
272
273 for (size_t i = 0; i < arguments.size(); ++i) {
274 argv[i] = buffer_pointer;
275 strcpy(buffer_pointer, arguments[i]);
276 buffer_pointer += strlen(arguments[i]);
277 *buffer_pointer = '\0';
278 ++buffer_pointer;
279 }
280 argv[arguments.size()] = NULL;
281
282 int pid = fork();
283 if (pid < 0) {
284 logger_->LogError("Fork failed: %d", errno);
285 return -1;
286 }
287
288 if (pid == 0) {
289 int output_handle = creat(output_file, 0700);
290 if (output_handle < 0) {
291 logger_->LogError("Could not create %s: %d", output_file, errno);
292 // Avoid exit() to avoid atexit handlers from parent.
293 _exit(127);
294 }
295 dup2(output_handle, 1);
296 dup2(output_handle, 2);
297 execv(argv[0], &argv[0]);
298 logger_->LogError("Exec failed: %d", errno);
299 _exit(127);
300 }
301
302 int status = 0;
303 if (HANDLE_EINTR(waitpid(pid, &status, 0)) < 0) {
304 logger_->LogError("Problem waiting for pid: %d", errno);
305 return -1;
306 }
307 if (!WIFEXITED(status)) {
308 logger_->LogError("Process did not exit normally: %d", status);
309 return -1;
310 }
311 return WEXITSTATUS(status);
312 }
313
314 bool UserCollector::RunCoreToMinidump(const FilePath &core_path, 255 bool UserCollector::RunCoreToMinidump(const FilePath &core_path,
315 const FilePath &procfs_directory, 256 const FilePath &procfs_directory,
316 const FilePath &minidump_path, 257 const FilePath &minidump_path,
317 const FilePath &temp_directory) { 258 const FilePath &temp_directory) {
318 FilePath output_path = temp_directory.Append("output"); 259 FilePath output_path = temp_directory.Append("output");
319 std::vector<const char *> core2md_arguments; 260 std::vector<const char *> core2md_arguments;
320 core2md_arguments.push_back(kCoreToMinidumpConverterPath); 261 core2md_arguments.push_back(kCoreToMinidumpConverterPath);
321 core2md_arguments.push_back(core_path.value().c_str()); 262 core2md_arguments.push_back(core_path.value().c_str());
322 core2md_arguments.push_back(procfs_directory.value().c_str()); 263 core2md_arguments.push_back(procfs_directory.value().c_str());
323 core2md_arguments.push_back(minidump_path.value().c_str()); 264 core2md_arguments.push_back(minidump_path.value().c_str());
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) { 394 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) {
454 if (!out_of_capacity) 395 if (!out_of_capacity)
455 EnqueueCollectionErrorLog(pid, exec); 396 EnqueueCollectionErrorLog(pid, exec);
456 return false; 397 return false;
457 } 398 }
458 } 399 }
459 } 400 }
460 401
461 return true; 402 return true;
462 } 403 }
OLDNEW
« no previous file with comments | « user_collector.h ('k') | user_collector_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698