Permalink
Browse files

Fix DoS condition on recursive logging

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...
cormander committed Nov 28, 2011
1 parent 319e1e2 commit 4cf1548f41a7b88fe5fe443f6f9f7b578921667f
Showing with 21 additions and 1 deletion.
  1. +1 −0 README
  2. +10 −1 core.c
  3. +1 −0 module.h
  4. +9 −0 sysctl.c
View
1 README
@@ -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
View
11 core.c
@@ -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;
}
}
View
@@ -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;
View
@@ -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;
@@ -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",

0 comments on commit 4cf1548

Please sign in to comment.