Skip to content

Commit

Permalink
audit: anchor all pid references in the initial pid namespace
Browse files Browse the repository at this point in the history
Store and log all PIDs with reference to the initial PID namespace and
use the access functions task_pid_nr() and task_tgid_nr() for task->pid
and task->tgid.

Cc: "Eric W. Biederman" <[email protected]>
(informed by ebiederman's c776b5d2)
Signed-off-by: Richard Guy Briggs <[email protected]>
  • Loading branch information
rgbriggs authored and eparis committed Mar 20, 2014
1 parent c92cdeb commit f1dc486
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 16 deletions.
3 changes: 2 additions & 1 deletion drivers/tty/tty_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static void tty_audit_log(const char *description, int major, int minor,
{
struct audit_buffer *ab;
struct task_struct *tsk = current;
pid_t pid = task_pid_nr(tsk);
uid_t uid = from_kuid(&init_user_ns, task_uid(tsk));
uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk));
unsigned int sessionid = audit_get_sessionid(tsk);
Expand All @@ -74,7 +75,7 @@ static void tty_audit_log(const char *description, int major, int minor,
char name[sizeof(tsk->comm)];

audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
" minor=%d comm=", description, tsk->pid, uid,
" minor=%d comm=", description, pid, uid,
loginuid, sessionid, major, minor);
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
Expand Down
5 changes: 3 additions & 2 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
{
int rc = 0;
uid_t uid = from_kuid(&init_user_ns, current_uid());
pid_t pid = task_tgid_nr(current);

if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
*ab = NULL;
Expand All @@ -658,7 +659,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
if (unlikely(!*ab))
return rc;
audit_log_format(*ab, "pid=%d uid=%u", task_tgid_vnr(current), uid);
audit_log_format(*ab, "pid=%d uid=%u", pid, uid);
audit_log_session_info(*ab);
audit_log_task_context(*ab);

Expand Down Expand Up @@ -1823,7 +1824,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
" euid=%u suid=%u fsuid=%u"
" egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
task_ppid_nr(tsk),
tsk->pid,
task_pid_nr(tsk),
from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
from_kuid(&init_user_ns, cred->uid),
from_kgid(&init_user_ns, cred->gid),
Expand Down
17 changes: 16 additions & 1 deletion kernel/auditfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,19 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
f->val = 0;
}

if ((f->type == AUDIT_PID) || (f->type == AUDIT_PPID)) {
struct pid *pid;
rcu_read_lock();
pid = find_vpid(f->val);
if (!pid) {
rcu_read_unlock();
err = -ESRCH;
goto exit_free;
}
f->val = pid_nr(pid);
rcu_read_unlock();
}

err = audit_field_valid(entry, f);
if (err)
goto exit_free;
Expand Down Expand Up @@ -1242,12 +1255,14 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,

for (i = 0; i < rule->field_count; i++) {
struct audit_field *f = &rule->fields[i];
pid_t pid;
int result = 0;
u32 sid;

switch (f->type) {
case AUDIT_PID:
result = audit_comparator(task_pid_vnr(current), f->op, f->val);
pid = task_pid_nr(current);
result = audit_comparator(pid, f->op, f->val);
break;
case AUDIT_UID:
result = audit_uid_comparator(current_uid(), f->op, f->uid);
Expand Down
16 changes: 9 additions & 7 deletions kernel/auditsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,12 @@ static int audit_filter_rules(struct task_struct *tsk,
struct audit_field *f = &rule->fields[i];
struct audit_names *n;
int result = 0;
pid_t pid;

switch (f->type) {
case AUDIT_PID:
result = audit_comparator(tsk->pid, f->op, f->val);
pid = task_pid_nr(tsk);
result = audit_comparator(pid, f->op, f->val);
break;
case AUDIT_PPID:
if (ctx) {
Expand Down Expand Up @@ -2051,7 +2053,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
audit_log_format(ab, "pid=%d uid=%u"
" old-auid=%u new-auid=%u old-ses=%u new-ses=%u"
" res=%d",
current->pid, uid,
task_pid_nr(current), uid,
oldloginuid, loginuid, oldsessionid, sessionid,
!rc);
audit_log_end(ab);
Expand Down Expand Up @@ -2275,7 +2277,7 @@ void __audit_ptrace(struct task_struct *t)
{
struct audit_context *context = current->audit_context;

context->target_pid = t->pid;
context->target_pid = task_pid_nr(t);
context->target_auid = audit_get_loginuid(t);
context->target_uid = task_uid(t);
context->target_sessionid = audit_get_sessionid(t);
Expand All @@ -2300,7 +2302,7 @@ int __audit_signal_info(int sig, struct task_struct *t)

if (audit_pid && t->tgid == audit_pid) {
if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
audit_sig_pid = tsk->pid;
audit_sig_pid = task_pid_nr(tsk);
if (uid_valid(tsk->loginuid))
audit_sig_uid = tsk->loginuid;
else
Expand All @@ -2314,7 +2316,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
/* optimize the common case by putting first signal recipient directly
* in audit_context */
if (!ctx->target_pid) {
ctx->target_pid = t->tgid;
ctx->target_pid = task_tgid_nr(t);
ctx->target_auid = audit_get_loginuid(t);
ctx->target_uid = t_uid;
ctx->target_sessionid = audit_get_sessionid(t);
Expand All @@ -2335,7 +2337,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
}
BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);

axp->target_pid[axp->pid_count] = t->tgid;
axp->target_pid[axp->pid_count] = task_tgid_nr(t);
axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
axp->target_uid[axp->pid_count] = t_uid;
axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
Expand Down Expand Up @@ -2435,7 +2437,7 @@ static void audit_log_task(struct audit_buffer *ab)
from_kgid(&init_user_ns, gid),
sessionid);
audit_log_task_context(ab);
audit_log_format(ab, " pid=%d comm=", current->pid);
audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
audit_log_untrustedstring(ab, current->comm);
if (mm) {
down_read(&mm->mmap_sem);
Expand Down
2 changes: 1 addition & 1 deletion security/integrity/integrity_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,

ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
current->pid,
task_pid_nr(current),
from_kuid(&init_user_ns, current_cred()->uid),
from_kuid(&init_user_ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
Expand Down
11 changes: 7 additions & 4 deletions security/lsm_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
*/
BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);

audit_log_format(ab, " pid=%d comm=", tsk->pid);
audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk));
audit_log_untrustedstring(ab, tsk->comm);

switch (a->type) {
Expand Down Expand Up @@ -278,9 +278,12 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
case LSM_AUDIT_DATA_TASK:
tsk = a->u.tsk;
if (tsk && tsk->pid) {
audit_log_format(ab, " pid=%d comm=", tsk->pid);
audit_log_untrustedstring(ab, tsk->comm);
if (tsk) {
pid_t pid = task_pid_nr(tsk);
if (pid) {
audit_log_format(ab, " pid=%d comm=", pid);
audit_log_untrustedstring(ab, tsk->comm);
}
}
break;
case LSM_AUDIT_DATA_NET:
Expand Down

0 comments on commit f1dc486

Please sign in to comment.