Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for ptrace_scope before doing ulp operations #201

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tools/patches.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,11 @@ process_list_end(struct ulp_process_iterator *it)
{
if (it->now == NULL) {
release_ulp_process(it->last);
producer_consumer_delete(it->pcqueue);
if (enable_threading) {
/* Make sure the threads stopped before destroying the queue. */
pthread_join(process_list_thread, NULL);
}
producer_consumer_delete(it->pcqueue);

/* In case threads were disabled because of some special case, then enable
it now. */
Expand Down
35 changes: 33 additions & 2 deletions tools/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>

#include "error_common.h"
#include "introspection.h"
Expand Down Expand Up @@ -401,15 +402,15 @@ attach(int pid)

if (ulp_ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
DEBUG("PTRACE_ATTACH error: %s.\n", strerror(errno));
return 1;
return errno;
}

while (true) {
pid_t ret = waitpid(pid, &status, WSTOPPED);

if (ret == -1) {
DEBUG("waitpid error (pid %d): %s.\n", pid, strerror(errno));
return 1;
return errno;
}
else if (ret == pid) {

Expand Down Expand Up @@ -608,3 +609,33 @@ run_and_redirect(int pid, struct user_regs_struct *regs, ElfW(Addr) routine)

return 0;
}


/** @brief Check ptrace scope security option.
*
* In some systems, ptracing a simbling process is disalowed with a permission
* error. This function will check if we are in such case, which we should
* error out and instruct the user what to do.
*
* @return: true if ptrace of simblings works.
**/
bool
check_ptrace_scope(void)
{
if (geteuid() == 0) {
/* Running as root. No problem. */
return true;
}

FILE *f = fopen("/proc/sys/kernel/yama/ptrace_scope", "r");
if (f == NULL) {
/* YAMA is not running. */
return true;
}

unsigned char buf[4] = {0};
size_t n = fread(buf, sizeof(unsigned char), 4, f);
assert(n == 2 && "What is in the ptrace_scope?");
fclose(f);
return buf[0] == '0' ? true : false;
}
4 changes: 4 additions & 0 deletions tools/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <stdbool.h>

#include "ulp_common.h"

/* System configuration options. */
bool check_ptrace_scope(void);

/* Memory read/write helper functions */

int write_bytes_ptrace(const void *buf, size_t n, int pid, Elf64_Addr addr);
Expand Down
33 changes: 33 additions & 0 deletions tools/ulp.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,28 @@ change_color(const char *ansi_escape)
}
}

static bool
requires_ptrace(command_t command)
{
switch(command) {
case ULP_NONE:
case ULP_DUMP:
case ULP_POST:
case ULP_EXTRACT:
case ULP_PACKER:
case ULP_LIVEPATCHABLE:
return false;

case ULP_PATCHES:
case ULP_TRIGGER:
case ULP_CHECK:
case ULP_MESSAGES:
case ULP_SET_PATCHABLE:
return true;
}
return false;
}

int
main(int argc, char **argv, char *envp[] __attribute__((unused)))
{
Expand All @@ -476,6 +498,17 @@ main(int argc, char **argv, char *envp[] __attribute__((unused)))

argp_parse(&argp, argc, argv, 0, 0, &arguments);


/* Check if command requires ptrace. */
if (requires_ptrace(arguments.command) &&
check_ptrace_scope() == false) {
WARN("System has 'ptrace_scope' enabled. Please become root or disable it"
"by setting:\n\n"
"$ sudo echo 0 > /proc/sys/kernel/yama/ptrace_scope\n\n"
"and try again.");
return EPERM;
}

switch (arguments.command) {
case ULP_NONE:
ret = 1;
Expand Down
Loading