Skip to content

Commit

Permalink
Check for ptrace_scope before doing ulp operations
Browse files Browse the repository at this point in the history
YAMA has a security feature that block ptrace of non-child processes.
Check for that when the command is issued to make sure everything will
work as it should.

Signed-off-by: Giuliano Belinassi <[email protected]>
  • Loading branch information
giulianobelinassi committed Apr 10, 2024
1 parent 22bc882 commit 6996bce
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
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

0 comments on commit 6996bce

Please sign in to comment.