summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Guy Briggs <rgb@redhat.com>2013-05-03 20:03:50 +0200
committerEric Paris <eparis@redhat.com>2013-04-30 21:31:28 +0200
commit46e959ea2969cc1668d09b0dc55226946cf781f1 (patch)
tree40481f42587257039bd7b898c2aec95e1c01656f
parentaudit: use spin_lock_irqsave/restore in audit tty code (diff)
downloadlinux-46e959ea2969cc1668d09b0dc55226946cf781f1.tar.xz
linux-46e959ea2969cc1668d09b0dc55226946cf781f1.zip
audit: add an option to control logging of passwords with pam_tty_audit
Most commands are entered one line at a time and processed as complete lines in non-canonical mode. Commands that interactively require a password, enter canonical mode to do this while shutting off echo. This pair of features (icanon and !echo) can be used to avoid logging passwords by audit while still logging the rest of the command. Adding a member (log_passwd) to the struct audit_tty_status passed in by pam_tty_audit allows control of canonical mode without echo per task. Signed-off-by: Richard Guy Briggs <rgb@redhat.com> Signed-off-by: Eric Paris <eparis@redhat.com>
-rw-r--r--drivers/tty/tty_audit.c9
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/uapi/linux/audit.h3
-rw-r--r--kernel/audit.c16
4 files changed, 22 insertions, 7 deletions
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index 755d418019c8..5f3868202183 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -138,6 +138,7 @@ void tty_audit_fork(struct signal_struct *sig)
spin_lock_irqsave(&current->sighand->siglock, flags);
sig->audit_tty = current->signal->audit_tty;
+ sig->audit_tty_log_passwd = current->signal->audit_tty_log_passwd;
spin_unlock_irqrestore(&current->sighand->siglock, flags);
}
@@ -275,10 +276,18 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
{
struct tty_audit_buf *buf;
int major, minor;
+ int audit_log_tty_passwd;
+ unsigned long flags;
if (unlikely(size == 0))
return;
+ spin_lock_irqsave(&current->sighand->siglock, flags);
+ audit_log_tty_passwd = current->signal->audit_tty_log_passwd;
+ spin_unlock_irqrestore(&current->sighand->siglock, flags);
+ if (!audit_log_tty_passwd && icanon && !L_ECHO(tty))
+ return;
+
if (tty->driver->type == TTY_DRIVER_TYPE_PTY
&& tty->driver->subtype == PTY_TYPE_MASTER)
return;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d2112477ff5e..c4689fe92864 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -641,6 +641,7 @@ struct signal_struct {
#endif
#ifdef CONFIG_AUDIT
unsigned audit_tty;
+ unsigned audit_tty_log_passwd;
struct tty_audit_buf *tty_audit_buf;
#endif
#ifdef CONFIG_CGROUPS
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 9f096f1c0907..c058c24b97ac 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -369,7 +369,8 @@ struct audit_status {
};
struct audit_tty_status {
- __u32 enabled; /* 1 = enabled, 0 = disabled */
+ __u32 enabled; /* 1 = enabled, 0 = disabled */
+ __u32 log_passwd; /* 1 = enabled, 0 = disabled */
};
/* audit_rule_data supports filter rules with both integer and string
diff --git a/kernel/audit.c b/kernel/audit.c
index 241aa8593fa8..998a0d4155cf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -49,6 +49,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kthread.h>
+#include <linux/kernel.h>
#include <linux/audit.h>
@@ -808,6 +809,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
spin_lock_irqsave(&tsk->sighand->siglock, flags);
s.enabled = tsk->signal->audit_tty != 0;
+ s.log_passwd = tsk->signal->audit_tty_log_passwd;
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
audit_send_reply(NETLINK_CB(skb).portid, seq,
@@ -815,18 +817,20 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break;
}
case AUDIT_TTY_SET: {
- struct audit_tty_status *s;
+ struct audit_tty_status s;
struct task_struct *tsk = current;
unsigned long flags;
- if (nlh->nlmsg_len < sizeof(struct audit_tty_status))
- return -EINVAL;
- s = data;
- if (s->enabled != 0 && s->enabled != 1)
+ memset(&s, 0, sizeof(s));
+ /* guard against past and future API changes */
+ memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len));
+ if ((s.enabled != 0 && s.enabled != 1) ||
+ (s.log_passwd != 0 && s.log_passwd != 1))
return -EINVAL;
spin_lock_irqsave(&tsk->sighand->siglock, flags);
- tsk->signal->audit_tty = s->enabled != 0;
+ tsk->signal->audit_tty = s.enabled;
+ tsk->signal->audit_tty_log_passwd = s.log_passwd;
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
break;
}