From 1e119f37b85b90c5a9a17fdcbc80625727b4ab66 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Dec 2009 19:54:51 +0100 Subject: fix all instances of atoi() usage Signed-off-by: Denys Vlasenko --- src/Hooks/CCpp.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src/Hooks/CCpp.cpp') diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index fd789cf..e38c4f7 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -202,25 +202,26 @@ int main(int argc, char** argv) logmode = LOGMODE_SYSLOG; const char* dddir = argv[1]; - pid_t pid = atoi(argv[2]); + pid_t pid = xatoi_u(argv[2]); const char* signal_str = argv[3]; - int signal = atoi(argv[3]); - uid_t uid = atoi(argv[4]); - - if (signal != SIGQUIT - && signal != SIGILL - && signal != SIGABRT - && signal != SIGFPE - && signal != SIGSEGV + int signal_no = xatoi_u(argv[3]); + uid_t uid = xatoi_u(argv[4]); + + if (signal_no != SIGQUIT + && signal_no != SIGILL + && signal_no != SIGABRT + && signal_no != SIGFPE + && signal_no != SIGSEGV ) { /* not an error, exit silently */ return 0; } - if (pid <= 0 || (int)uid < 0) + if (pid <= 0) { - error_msg_and_die("pid '%s' or uid '%s' are bogus", argv[2], argv[4]); + error_msg_and_die("pid '%s' is bogus", argv[2]); } + char *user_pwd = get_cwd(pid); /* may be NULL on error */ int core_fd = STDIN_FILENO; @@ -299,7 +300,7 @@ int main(int argc, char** argv) } char* cmdline = get_cmdline(pid); /* never NULL */ - const char *signame = strsignal(atoi(signal_str)); + const char *signame = strsignal(signal_no); char *reason = xasprintf("Process was terminated by signal %s (%s)", signal_str, signame ? signame : signal_str); snprintf(path, sizeof(path), "%s/ccpp-%ld-%u", dddir, (long)time(NULL), (int)pid); @@ -388,7 +389,7 @@ int main(int argc, char** argv) if (isdigit(*p)) /* x1.25: go a bit up, so that usual in-daemon trimming * kicks in first, and we don't "fight" with it. */ - setting_MaxCrashReportsSize = (unsigned long)atoi(p) * 5 / 4; + setting_MaxCrashReportsSize = (unsigned long)xatou(p) * 5 / 4; continue; } #undef DIRECTIVE -- cgit From 687be490d8092842f9a016132a4204023d9b8d6e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 16 Dec 2009 19:22:00 +0100 Subject: src/Hooks/CCpp.cpp: use and honour %c (core limit size). Makes MakeCompatCore = yes much more frielndly - now users with ulimit -c 0 won't get unwanted coredumps. Signed-off-by: Denys Vlasenko --- src/Hooks/CCpp.cpp | 171 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 73 deletions(-) (limited to 'src/Hooks/CCpp.cpp') diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index e38c4f7..7a348e5 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -194,19 +194,26 @@ int main(int argc, char** argv) struct stat sb; const char* program_name = argv[0]; - if (argc < 4) + if (argc < 5) { - error_msg_and_die("Usage: %s: ", program_name); + error_msg_and_die("Usage: %s: DUMPDIR PID SIGNO UID CORE_SIZE_LIMIT", program_name); } openlog("abrt", 0, LOG_DAEMON); logmode = LOGMODE_SYSLOG; + errno = 0; const char* dddir = argv[1]; pid_t pid = xatoi_u(argv[2]); const char* signal_str = argv[3]; int signal_no = xatoi_u(argv[3]); uid_t uid = xatoi_u(argv[4]); + off_t ulimit_c = strtoull(argv[5], NULL, 10); + off_t core_size = 0; + if (errno || pid <= 0 || ulimit_c < 0) + { + error_msg_and_die("pid '%s' or limit '%s' is bogus", argv[2], argv[5]); + } if (signal_no != SIGQUIT && signal_no != SIGILL && signal_no != SIGABRT @@ -216,10 +223,6 @@ int main(int argc, char** argv) /* not an error, exit silently */ return 0; } - if (pid <= 0) - { - error_msg_and_die("pid '%s' is bogus", argv[2]); - } char *user_pwd = get_cwd(pid); /* may be NULL on error */ @@ -248,6 +251,65 @@ int main(int argc, char** argv) (int)pid, executable); } + /* Parse abrt.conf and plugins/CCpp.conf */ + unsigned setting_MaxCrashReportsSize = 0; + bool setting_MakeCompatCore = false; + bool abrt_conf = true; + FILE *fp = fopen(CONF_DIR"/abrt.conf", "r"); + if (fp) + { + char line[256]; + while (1) + { + if (fgets(line, sizeof(line), fp) == NULL) + { + /* Next .conf file plz */ + if (abrt_conf) + { + abrt_conf = false; + fp = fopen(CONF_DIR"/plugins/CCpp.conf", "r"); + if (fp) + continue; + } + break; + } + + unsigned len = strlen(line); + if (len > 0 && line[len-1] == '\n') + line[--len] = '\0'; + const char *p = skip_whitespace(line); +#undef DIRECTIVE +#define DIRECTIVE "MaxCrashReportsSize" + if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0) + { + p = skip_whitespace(p + sizeof(DIRECTIVE)-1); + if (*p != '=') + continue; + p = skip_whitespace(p + 1); + if (isdigit(*p)) + /* x1.25: go a bit up, so that usual in-daemon trimming + * kicks in first, and we don't "fight" with it. */ + setting_MaxCrashReportsSize = (unsigned long)xatou(p) * 5 / 4; + continue; + } +#undef DIRECTIVE +#define DIRECTIVE "MakeCompatCore" + if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0) + { + p = skip_whitespace(p + sizeof(DIRECTIVE)-1); + if (*p != '=') + continue; + p = skip_whitespace(p + 1); + setting_MakeCompatCore = string_to_bool(p); + continue; + } +#undef DIRECTIVE + /* add more 'if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0)' here... */ + } + fclose(fp); + } + + char path[PATH_MAX]; /* Check /var/cache/abrt/last-ccpp marker, do not dump repeated crashes @@ -268,7 +330,12 @@ int main(int argc, char** argv) { path[sz] = '\0'; if (strcmp(executable, path) == 0) - error_msg_and_die("not dumping repeating crash in '%s'", executable); + { + error_msg("not dumping repeating crash in '%s'", executable); + if (setting_MakeCompatCore) + goto create_user_core; + return 1; + } } lseek(fd, 0, SEEK_SET); } @@ -287,15 +354,15 @@ int main(int argc, char** argv) */ snprintf(path, sizeof(path), "%s/abrtd-coredump", dddir); core_fd = xopen3(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - off_t size = copyfd_eof(STDIN_FILENO, core_fd); - if (size < 0 || close(core_fd) != 0) + core_size = copyfd_eof(STDIN_FILENO, core_fd); + if (core_size < 0 || close(core_fd) != 0) { unlink(path); /* copyfd_eof logs the error including errno string, * but it does not log file name */ error_msg_and_die("error saving coredump to %s", path); } - log("saved core dump of pid %u (%s) to %s (%llu bytes)", (int)pid, executable, path, (long long)size); + log("saved core dump of pid %u (%s) to %s (%llu bytes)", (int)pid, executable, path, (long long)core_size); return 0; } @@ -326,8 +393,8 @@ int main(int argc, char** argv) dd.Close(); perror_msg_and_die("can't open '%s'", path); } - off_t size = copyfd_eof(STDIN_FILENO, core_fd); - if (size < 0 || fsync(core_fd) != 0) + core_size = copyfd_eof(STDIN_FILENO, core_fd); + if (core_size < 0 || fsync(core_fd) != 0) { unlink(path); dd.Delete(); @@ -338,7 +405,7 @@ int main(int argc, char** argv) } lseek(core_fd, 0, SEEK_SET); /* note: core_fd is still open, we may use it later to copy core to user's dir */ - log("saved core dump of pid %u (%s) to %s (%llu bytes)", (int)pid, executable, path, (long long)size); + log("saved core dump of pid %u (%s) to %s (%llu bytes)", (int)pid, executable, path, (long long)core_size); free(executable); free(cmdline); path[len] = '\0'; /* path now contains directory name */ @@ -351,64 +418,6 @@ int main(int argc, char** argv) */ dd.Close(); - /* Parse abrt.conf and plugins/CCpp.conf */ - unsigned setting_MaxCrashReportsSize = 0; - bool setting_MakeCompatCore = false; - bool abrt_conf = true; - FILE *fp = fopen(CONF_DIR"/abrt.conf", "r"); - if (fp) - { - char line[256]; - while (1) - { - if (fgets(line, sizeof(line), fp) == NULL) - { - /* Next .conf file plz */ - if (abrt_conf) - { - abrt_conf = false; - fp = fopen(CONF_DIR"/plugins/CCpp.conf", "r"); - if (fp) - continue; - } - break; - } - - unsigned len = strlen(line); - if (len > 0 && line[len-1] == '\n') - line[--len] = '\0'; - const char *p = skip_whitespace(line); -#undef DIRECTIVE -#define DIRECTIVE "MaxCrashReportsSize" - if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0) - { - p = skip_whitespace(p + sizeof(DIRECTIVE)-1); - if (*p != '=') - continue; - p = skip_whitespace(p + 1); - if (isdigit(*p)) - /* x1.25: go a bit up, so that usual in-daemon trimming - * kicks in first, and we don't "fight" with it. */ - setting_MaxCrashReportsSize = (unsigned long)xatou(p) * 5 / 4; - continue; - } -#undef DIRECTIVE -#define DIRECTIVE "MakeCompatCore" - if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0) - { - p = skip_whitespace(p + sizeof(DIRECTIVE)-1); - if (*p != '=') - continue; - p = skip_whitespace(p + 1); - setting_MakeCompatCore = string_to_bool(p); - continue; - } -#undef DIRECTIVE - /* add more 'if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0)' here... */ - } - fclose(fp); - } - /* rhbz#539551: "abrt going crazy when crashing process is respawned". * Do we want to protect against or ameliorate this? How? Ideas: * (1) nice ourself? @@ -448,7 +457,12 @@ int main(int argc, char** argv) error_msg_and_die("%s", e.what()); } + create_user_core: + /* note: core_size may be == 0 ("unknown") */ + if (core_size > ulimit_c || ulimit_c == 0) + return 0; + /* Write a core file for user */ struct passwd* pw = getpwuid(uid); @@ -521,8 +535,10 @@ int main(int argc, char** argv) perror_msg_and_die("%s/%s is not a regular file with link count 1", user_pwd, core_basename); } + /* Note: we do not copy more than ulimit_c */ + off_t size; if (ftruncate(usercore_fd, 0) != 0 - || copyfd_eof(core_fd, usercore_fd) < 0 + || (size = copyfd_size(core_fd, usercore_fd, ulimit_c)) < 0 || close(usercore_fd) != 0 ) { /* perror first, otherwise unlink may trash errno */ @@ -530,7 +546,16 @@ int main(int argc, char** argv) unlink(core_basename); return 1; } - log("saved core dump of pid %u to %s/%s", (int)pid, user_pwd, core_basename); + if (size == ulimit_c && size != core_size) + { + /* We copied exactly ulimit_c bytes (and it doesn't accidentally match + * core_size (imagine exactly 1MB coredump with "ulimit -c 1M" - that'd be ok)), + * it means that core is larger than ulimit_c. Abort and delete the dump. + */ + unlink(core_basename); + return 1; + } + log("saved core dump of pid %u to %s/%s (%llu bytes)", (int)pid, user_pwd, core_basename, (long long)size); return 0; } -- cgit From c1766c339b99aa157c589a7e661b2fe3bd04501d Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Fri, 18 Dec 2009 16:56:12 +0100 Subject: large file support for whole abrt --- src/Hooks/CCpp.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/Hooks/CCpp.cpp') diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index 7a348e5..a2db2ec 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -18,14 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -/* Make all file ops "large" and make off_t 64-bit. - * No need to use O_LARGEFILE anywhere - */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _FILE_OFFSET_BITS 64 - #include "abrtlib.h" #include "DebugDump.h" #include "ABRTException.h" -- cgit From f0fe841b0f257ee288b6b88a32597a6282952d34 Mon Sep 17 00:00:00 2001 From: Karel Klic Date: Fri, 18 Dec 2009 17:03:20 +0100 Subject: moved get_cmdline() and daemon_is_ok() to abrtlib --- src/Hooks/CCpp.cpp | 122 ----------------------------------------------------- 1 file changed, 122 deletions(-) (limited to 'src/Hooks/CCpp.cpp') diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp index a2db2ec..3a13358 100644 --- a/src/Hooks/CCpp.cpp +++ b/src/Hooks/CCpp.cpp @@ -24,11 +24,8 @@ #include #define FILENAME_EXECUTABLE "executable" -#define FILENAME_CMDLINE "cmdline" #define FILENAME_COREDUMP "coredump" -#define VAR_RUN_PID_FILE VAR_RUN"/abrt.pid" - using namespace std; static char* malloc_readlink(const char *linkname) @@ -61,125 +58,6 @@ static char* get_cwd(pid_t pid) return malloc_readlink(buf); } -static char *append_escaped(char *start, const char *s) -{ - char hex_char_buf[] = "\\x00"; - - *start++ = ' '; - char *dst = start; - const unsigned char *p = (unsigned char *)s; - - while (1) - { - const unsigned char *old_p = p; - while (*p > ' ' && *p <= 0x7e && *p != '\"' && *p != '\'' && *p != '\\') - p++; - if (dst == start) - { - if (p != (unsigned char *)s && *p == '\0') - { - /* entire word does not need escaping and quoting */ - strcpy(dst, s); - dst += strlen(s); - return dst; - } - *dst++ = '\''; - } - - strncpy(dst, s, (p - old_p)); - dst += (p - old_p); - - if (*p == '\0') - { - *dst++ = '\''; - *dst = '\0'; - return dst; - } - const char *a; - switch (*p) - { - case '\r': a = "\\r"; break; - case '\n': a = "\\n"; break; - case '\t': a = "\\t"; break; - case '\'': a = "\\\'"; break; - case '\"': a = "\\\""; break; - case '\\': a = "\\\\"; break; - case ' ': a = " "; break; - default: - hex_char_buf[2] = "0123456789abcdef"[*p >> 4]; - hex_char_buf[3] = "0123456789abcdef"[*p & 0xf]; - a = hex_char_buf; - } - strcpy(dst, a); - dst += strlen(a); - p++; - } -} - -// taken from kernel -#define COMMAND_LINE_SIZE 2048 -static char* get_cmdline(pid_t pid) -{ - char path[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; - char cmdline[COMMAND_LINE_SIZE]; - char escaped_cmdline[COMMAND_LINE_SIZE*4 + 4]; - - escaped_cmdline[1] = '\0'; - sprintf(path, "/proc/%u/cmdline", (int)pid); - int fd = open(path, O_RDONLY); - if (fd >= 0) - { - int len = read(fd, cmdline, sizeof(cmdline) - 1); - close(fd); - - if (len > 0) - { - cmdline[len] = '\0'; - char *src = cmdline; - char *dst = escaped_cmdline; - while ((src - cmdline) < len) - { - dst = append_escaped(dst, src); - src += strlen(src) + 1; - } - } - } - - return xstrdup(escaped_cmdline + 1); /* +1 skips extraneous leading space */ -} - -static int daemon_is_ok() -{ - int fd = open(VAR_RUN_PID_FILE, O_RDONLY); - if (fd < 0) - { - return 0; - } - - char pid[sizeof(pid_t)*3 + 2]; - int len = read(fd, pid, sizeof(pid)-1); - close(fd); - if (len <= 0) - return 0; - - pid[len] = '\0'; - *strchrnul(pid, '\n') = '\0'; - /* paranoia: we don't want to check /proc//stat or /proc///stat */ - if (pid[0] == '\0' || pid[0] == '/') - return 0; - - /* TODO: maybe readlink and check that it is "xxx/abrt"? */ - char path[sizeof("/proc/%s/stat") + sizeof(pid)]; - sprintf(path, "/proc/%s/stat", pid); - struct stat sb; - if (stat(path, &sb) == -1) - { - return 0; - } - - return 1; -} - int main(int argc, char** argv) { int fd; -- cgit