/
githubmirror
/
strace
Обзор
Документация
Войти
/
githubmirror
/
strace
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v5.13
src/secontext.c
139 строк
3 KB
Renaud Métrich
Implement --secontext[=full] option to display SELinux contexts
04 апр 2021, 15:04
04 апр 2021, 15:04
e921913
Код
Авторство
О чём код?
/* * Copyright (c) 2020-2021 The strace developers. * All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-or-later */ #include "defs.h" #include <stdlib.h> #include <fcntl.h> #include <limits.h> #include <selinux/selinux.h> #include "secontext.h" #include "xstring.h" bool selinux_context = false; bool selinux_context_full = false; static int getcontext(int rc, char **secontext, char **result) { if (rc < 0) return rc; *result = NULL; if (!selinux_context_full) { char *saveptr = NULL; char *secontext_copy = xstrdup(*secontext); const char *token; unsigned int i; /* * We only want to keep the type (3rd field, ':' separator). */ for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; token; token = strtok_r(NULL, ":", &saveptr), i++) { if (i == 2) { *result = xstrdup(token); break; } } free(secontext_copy); } if (*result == NULL) { /* * On the CI at least, the context may have a trailing \n, * let's remove it just in case. */ size_t len = strlen(*secontext); for (; len > 0; --len) { if ((*secontext)[len - 1] != '\n') break; } *result = xstrndup(*secontext, len); } freecon(*secontext); return 0; } /* * Retrieves the SELinux context of the given PID (extracted from the tcb). * Memory must be freed. * Returns 0 on success, -1 on failure. */ int selinux_getpidcon(struct tcb *tcp, char **result) { if (!selinux_context) return -1; int proc_pid = 0; translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); if (!proc_pid) return -1; char *secontext; return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); } /* * Retrieves the SELinux context of the given pid and descriptor. * Memory must be freed. * Returns 0 on success, -1 on failure. */ int selinux_getfdcon(pid_t pid, int fd, char **result) { if (!selinux_context || pid <= 0 || fd < 0) return -1; int proc_pid = 0; translate_pid(NULL, pid, PT_TID, &proc_pid); if (!proc_pid) return -1; char linkpath[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3]; xsprintf(linkpath, "/proc/%u/fd/%u", proc_pid, fd); char *secontext; return getcontext(getfilecon(linkpath, &secontext), &secontext, result); } /* * Retrieves the SELinux context of the given path. * Memory must be freed. * Returns 0 on success, -1 on failure. */ int selinux_getfilecon(struct tcb *tcp, const char *path, char **result) { if (!selinux_context) return -1; int proc_pid = 0; translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); if (!proc_pid) return -1; int ret = -1; char fname[PATH_MAX]; if (path[0] == '/') ret = snprintf(fname, sizeof(fname), "/proc/%u/root%s", proc_pid, path); else if (tcp->last_dirfd == AT_FDCWD) ret = snprintf(fname, sizeof(fname), "/proc/%u/cwd/%s", proc_pid, path); else if (tcp->last_dirfd >= 0 ) ret = snprintf(fname, sizeof(fname), "/proc/%u/fd/%u/%s", proc_pid, tcp->last_dirfd, path); if ((unsigned int) ret >= sizeof(fname)) return -1; char *secontext; return getcontext(getfilecon(fname, &secontext), &secontext, result); }