summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Moskovcak <jmoskovc@redhat.com>2010-11-16 15:51:58 +0100
committerJiri Moskovcak <jmoskovc@redhat.com>2010-11-16 15:51:58 +0100
commit3627275be945b31e71d059e3eaa5ea0592d42f17 (patch)
tree23f5dc00d575bdc15df5dc12da73c20981a54bf0
parent246c10e47ba9abe539378a2e4cdf341d8ae7b415 (diff)
downloadabrt-3627275be945b31e71d059e3eaa5ea0592d42f17.tar.gz
abrt-3627275be945b31e71d059e3eaa5ea0592d42f17.tar.xz
abrt-3627275be945b31e71d059e3eaa5ea0592d42f17.zip
fixed segv in abrt-hook-ccpp rhbz#652338
- the hook wasn't ready for situations where /proc/<PID>/ doesn't exist, this patch makes the hook die gracefully
-rw-r--r--src/Hooks/abrt-hook-ccpp.cpp66
1 files changed, 36 insertions, 30 deletions
diff --git a/src/Hooks/abrt-hook-ccpp.cpp b/src/Hooks/abrt-hook-ccpp.cpp
index e53007a4..9b0d4383 100644
--- a/src/Hooks/abrt-hook-ccpp.cpp
+++ b/src/Hooks/abrt-hook-ccpp.cpp
@@ -139,6 +139,8 @@ static char* get_executable(pid_t pid, int *fd_p)
sprintf(buf, "/proc/%lu/exe", (long)pid);
*fd_p = open(buf, O_RDONLY); /* might fail and return -1, it's ok */
char *executable = malloc_readlink(buf);
+ if (!executable)
+ return NULL;
/* find and cut off " (deleted)" from the path */
char *deleted = executable + strlen(executable) - strlen(" (deleted)");
if (deleted > executable && strcmp(deleted, " (deleted)") == 0)
@@ -178,7 +180,7 @@ static int open_user_core(const char *user_pwd, uid_t uid, pid_t pid)
|| chdir(user_pwd) != 0
) {
perror_msg("can't cd to %s", user_pwd);
- return 0;
+ return -1;
}
/* Mimic "core.PID" if requested */
@@ -291,12 +293,8 @@ int main(int argc, char** argv)
}
int src_fd_binary;
- char* executable = get_executable(pid, &src_fd_binary);
- if (executable == NULL)
- {
- perror_msg_and_die("can't read /proc/%lu/exe link", (long)pid);
- }
- if (strstr(executable, "/abrt-hook-ccpp"))
+ char *executable = get_executable(pid, &src_fd_binary);
+ if (executable && strstr(executable, "/abrt-hook-ccpp"))
{
error_msg_and_die("pid %lu is '%s', not dumping it to avoid recursion",
(long)pid, executable);
@@ -318,37 +316,45 @@ int main(int argc, char** argv)
/* Open a fd to compat coredump, if requested and is possible */
int user_core_fd = -1;
if (setting_MakeCompatCore && ulimit_c != 0)
+ /* note: checks "user_pwd == NULL" inside */
user_core_fd = open_user_core(user_pwd, uid, pid);
- const char *signame = NULL;
- /* Tried to use array for this but C++ does not support v[] = { [IDX] = "str" } */
- switch (signal_no)
- {
- case SIGILL : signame = "ILL" ; break;
- case SIGFPE : signame = "FPE" ; break;
- case SIGSEGV: signame = "SEGV"; break;
- case SIGBUS : signame = "BUS" ; break; //Bus error (bad memory access)
- case SIGABRT: signame = "ABRT"; break; //usually when abort() was called
- //case SIGQUIT: signame = "QUIT"; break; //Quit from keyboard
- //case SIGSYS : signame = "SYS" ; break; //Bad argument to routine (SVr4)
- //case SIGTRAP: signame = "TRAP"; break; //Trace/breakpoint trap
- //case SIGXCPU: signame = "XCPU"; break; //CPU time limit exceeded (4.2BSD)
- //case SIGXFSZ: signame = "XFSZ"; break; //File size limit exceeded (4.2BSD)
- default: goto create_user_core; // not a signal we care about
- }
-
- if (!daemon_is_ok())
+ if (executable == NULL)
{
- /* not an error, exit with exitcode 0 */
- log("abrt daemon is not running. If it crashed, "
- "/proc/sys/kernel/core_pattern contains a stale value, "
- "consider resetting it to 'core'"
- );
+ /* readlink on /proc/$PID/exe failed, don't create abrt dump dir */
+ error_msg("can't read /proc/%lu/exe link", (long)pid);
goto create_user_core;
}
try
{
+ const char *signame = NULL;
+ /* Tried to use array for this but C++ does not support v[] = { [IDX] = "str" } */
+ switch (signal_no)
+ {
+ case SIGILL : signame = "ILL" ; break;
+ case SIGFPE : signame = "FPE" ; break;
+ case SIGSEGV: signame = "SEGV"; break;
+ case SIGBUS : signame = "BUS" ; break; //Bus error (bad memory access)
+ case SIGABRT: signame = "ABRT"; break; //usually when abort() was called
+ //case SIGQUIT: signame = "QUIT"; break; //Quit from keyboard
+ //case SIGSYS : signame = "SYS" ; break; //Bad argument to routine (SVr4)
+ //case SIGTRAP: signame = "TRAP"; break; //Trace/breakpoint trap
+ //case SIGXCPU: signame = "XCPU"; break; //CPU time limit exceeded (4.2BSD)
+ //case SIGXFSZ: signame = "XFSZ"; break; //File size limit exceeded (4.2BSD)
+ default: goto create_user_core; // not a signal we care about
+ }
+
+ if (!daemon_is_ok())
+ {
+ /* not an error, exit with exitcode 0 */
+ log("abrt daemon is not running. If it crashed, "
+ "/proc/sys/kernel/core_pattern contains a stale value, "
+ "consider resetting it to 'core'"
+ );
+ goto create_user_core;
+ }
+
if (setting_MaxCrashReportsSize > 0)
{
check_free_space(setting_MaxCrashReportsSize);