Skip to content

Commit

Permalink
abrtd: save interesting process details
Browse files Browse the repository at this point in the history
ABRT addons running under unprivileged users make use of the socket API
to report the detected problems. Creating a new ABRT addon requires
knowledge of collected process details which is not very user friendly.
Also, whenever ABRT needs new something new to be collected, then we
have to make sure all ABRT Addon get updated.

This commit moves collecting of essential process details to abrtd
(resp. abrt-server).

The commit also teaches abrt-server to collect additional files required
for debugging of applications running in containers:
- mountinfo
- cgroup

Signed-off-by: Jakub Filak <jfilak@redhat.com>
  • Loading branch information
Jakub Filak committed Oct 6, 2016
1 parent 6337b3a commit da53089
Showing 1 changed file with 93 additions and 5 deletions.
98 changes: 93 additions & 5 deletions src/daemon/abrt-server.c
Expand Up @@ -602,34 +602,122 @@ static int create_problem_dir(GHashTable *problem_info, unsigned pid)
error_msg_and_die("Error creating problem directory '%s'", path);
}

dd_create_basic_files(dd, client_uid, NULL);
dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION);
const int proc_dir_fd = open_proc_pid_dir(pid);
char *rootdir = NULL;

gpointer gpkey = g_hash_table_lookup(problem_info, FILENAME_CMDLINE);
if (!gpkey)
if (proc_dir_fd < 0)
{
pwarn_msg("Cannot open /proc/%d:", pid);
}
else if (process_has_own_root_at(proc_dir_fd))
{
/* Obtain the root directory path only if process' root directory is
* not the same as the init's root directory
*/
rootdir = get_rootdir_at(proc_dir_fd);
}

/* Reading data from an arbitrary root directory is not secure. */
if (proc_dir_fd >= 0 && g_settings_explorechroots)
{
char proc_pid_root[sizeof("/proc/[pid]/root") + sizeof(pid_t) * 3];
const size_t w = snprintf(proc_pid_root, sizeof(proc_pid_root), "/proc/%d/root", pid);
assert(sizeof(proc_pid_root) > w);

/* Yes, test 'rootdir' but use 'source_filename' because 'rootdir' can
* be '/' for a process with own namespace. 'source_filename' is /proc/[pid]/root. */
dd_create_basic_files(dd, client_uid, (rootdir != NULL) ? proc_pid_root : NULL);
}
else
{
dd_create_basic_files(dd, client_uid, NULL);
}

if (proc_dir_fd >= 0)
{
/* Obtain and save the command line. */
char *cmdline = get_cmdline(pid);
char *cmdline = get_cmdline_at(proc_dir_fd);
if (cmdline)
{
dd_save_text(dd, FILENAME_CMDLINE, cmdline);
free(cmdline);
}

/* Obtain and save the environment variables. */
char *environ = get_environ_at(proc_dir_fd);
if (environ)
{
dd_save_text(dd, FILENAME_ENVIRON, environ);
free(environ);
}

dd_copy_file_at(dd, FILENAME_CGROUP, proc_dir_fd, "cgroup");
dd_copy_file_at(dd, FILENAME_MOUNTINFO, proc_dir_fd, "mountinfo");

FILE *open_fds = dd_open_item_file(dd, FILENAME_OPEN_FDS, O_WRONLY);
if (open_fds)
{
if (dump_fd_info_at(proc_dir_fd, open_fds) < 0)
dd_delete_item(dd, FILENAME_OPEN_FDS);
fclose(open_fds);
}

const int init_proc_dir_fd = open_proc_pid_dir(1);
FILE *namespaces = dd_open_item_file(dd, FILENAME_NAMESPACES, O_WRONLY);
if (namespaces && init_proc_dir_fd >= 0)
{
if (dump_namespace_diff_at(init_proc_dir_fd, proc_dir_fd, namespaces) < 0)
dd_delete_item(dd, FILENAME_NAMESPACES);
}
if (init_proc_dir_fd >= 0)
close(init_proc_dir_fd);
if (namespaces)
fclose(namespaces);

/* The process's root directory isn't the same as the init's root
* directory. */
if (rootdir)
{
if (strcmp(rootdir, "/") == 0)
{ /* We are dealing containerized process because root's
* directory path is '/' and that means that the process
* has mounted its own root.
* Seriously, it is possible if the process is running in its
* own MOUNT namespaces.
*/
log_debug("Process %d is considered to be containerized", pid);
pid_t container_pid;
if (get_pid_of_container_at(proc_dir_fd, &container_pid) == 0)
{
char *container_cmdline = get_cmdline(container_pid);
dd_save_text(dd, FILENAME_CONTAINER_CMDLINE, container_cmdline);
free(container_cmdline);
}
}
else
{ /* We are dealing chrooted process. */
dd_save_text(dd, FILENAME_ROOTDIR, rootdir);
}
}
}
free(rootdir);

/* Store id of the user whose application crashed. */
char uid_str[sizeof(long) * 3 + 2];
sprintf(uid_str, "%lu", (long)client_uid);
dd_save_text(dd, FILENAME_UID, uid_str);

GHashTableIter iter;
gpointer gpkey;
gpointer gpvalue;
g_hash_table_iter_init(&iter, problem_info);
while (g_hash_table_iter_next(&iter, &gpkey, &gpvalue))
{
dd_save_text(dd, (gchar *) gpkey, (gchar *) gpvalue);
}

dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION);

dd_close(dd);

/* Not needing it anymore */
Expand Down

0 comments on commit da53089

Please sign in to comment.