Skip to content

Commit

Permalink
Fix DoS condition on recursive logging
Browse files Browse the repository at this point in the history
This patch fixes a denial-of-service condition when exec is denied on a process
with a lot of parents. It's caused by the parent_task_walk() being a recursive
function.

Recursive function in the linux kernel? What was I thinking? I wasn't,
actually, as my main goal with the project initially was proof-of-concept. Now
that I'm actually using the thing in ad-hoc production environments, it's time
I search the code for problems. Well, I found one!

This patch also introduces a new sysctl entry: log_max
  • Loading branch information
Corey Henderson committed Nov 28, 2011
1 parent 319e1e2 commit 4cf1548
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
1 change: 1 addition & 0 deletions README
Expand Up @@ -52,6 +52,7 @@ check_file - check file owner/mode in addition to directory. default on
kill - kill the offending process and its parent when it gets denied
execution from TPE, unless it's root. default off
log - whether to log denied execs to the ring buffer. default on
log_max - maximun parent processes in a single log entry. default 50
log_floodburst - number of log entries before logging is disabled. default 5
log_floodtime - seconds until re-enabling logging after floodburst. default 5
paranoid - denies execs for root of files not owned by root. default off
Expand Down
11 changes: 10 additions & 1 deletion core.c
Expand Up @@ -62,16 +62,25 @@ void parent_task_walk(struct task_struct *task) {

struct task_struct *parent;
char filename[MAX_FILE_LEN];
int c = 0;

walk:
c++;
if (task && task->mm) {

if (tpe_log_max && c > tpe_log_max) {
printk("tpe log_max %d reached", tpe_log_max);
return;
}

parent = get_task_parent(task);

printk("%s (uid:%d)", exe_from_mm(task->mm, filename, MAX_FILE_LEN), get_task_uid(task));

if (parent && task->pid != 1) {
printk(", ");
parent_task_walk(parent);
task = parent;
goto walk;
}
}

Expand Down
1 change: 1 addition & 0 deletions module.h
Expand Up @@ -76,6 +76,7 @@ extern int tpe_check_file;
extern int tpe_paranoid;
extern int tpe_kill;
extern int tpe_log;
extern int tpe_log_max;
extern int tpe_log_floodtime;
extern int tpe_log_floodburst;
extern int tpe_dmesg;
Expand Down
9 changes: 9 additions & 0 deletions sysctl.c
Expand Up @@ -10,6 +10,7 @@ int tpe_check_file = 1;
int tpe_paranoid = 0;
int tpe_kill = 0;
int tpe_log = 1;
int tpe_log_max = 50;
int tpe_log_floodtime = LOG_FLOODTIME;
int tpe_log_floodburst = LOG_FLOODBURST;
int tpe_dmesg = 0;
Expand Down Expand Up @@ -117,6 +118,14 @@ static ctl_table tpe_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = CTL_UNNUMBERED,
.procname = "log_max",
.data = &tpe_log_max,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = CTL_UNNUMBERED,
.procname = "log_floodtime",
Expand Down

0 comments on commit 4cf1548

Please sign in to comment.