aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Guy Briggs <rgb@redhat.com>2013-05-03 14:03:50 -0400
committerEric Paris <eparis@redhat.com>2013-04-30 15:31:28 -0400
commit46e959ea2969cc1668d09b0dc55226946cf781f1 (patch)
tree40481f42587257039bd7b898c2aec95e1c01656f
parentbde02ca858448cf54a4226774dd1481f3bcc455e (diff)
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)
138 138
139 spin_lock_irqsave(&current->sighand->siglock, flags); 139 spin_lock_irqsave(&current->sighand->siglock, flags);
140 sig->audit_tty = current->signal->audit_tty; 140 sig->audit_tty = current->signal->audit_tty;
141 sig->audit_tty_log_passwd = current->signal->audit_tty_log_passwd;
141 spin_unlock_irqrestore(&current->sighand->siglock, flags); 142 spin_unlock_irqrestore(&current->sighand->siglock, flags);
142} 143}
143 144
@@ -275,10 +276,18 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
275{ 276{
276 struct tty_audit_buf *buf; 277 struct tty_audit_buf *buf;
277 int major, minor; 278 int major, minor;
279 int audit_log_tty_passwd;
280 unsigned long flags;
278 281
279 if (unlikely(size == 0)) 282 if (unlikely(size == 0))
280 return; 283 return;
281 284
285 spin_lock_irqsave(&current->sighand->siglock, flags);
286 audit_log_tty_passwd = current->signal->audit_tty_log_passwd;
287 spin_unlock_irqrestore(&current->sighand->siglock, flags);
288 if (!audit_log_tty_passwd && icanon && !L_ECHO(tty))
289 return;
290
282 if (tty->driver->type == TTY_DRIVER_TYPE_PTY 291 if (tty->driver->type == TTY_DRIVER_TYPE_PTY
283 && tty->driver->subtype == PTY_TYPE_MASTER) 292 && tty->driver->subtype == PTY_TYPE_MASTER)
284 return; 293 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 {
641#endif 641#endif
642#ifdef CONFIG_AUDIT 642#ifdef CONFIG_AUDIT
643 unsigned audit_tty; 643 unsigned audit_tty;
644 unsigned audit_tty_log_passwd;
644 struct tty_audit_buf *tty_audit_buf; 645 struct tty_audit_buf *tty_audit_buf;
645#endif 646#endif
646#ifdef CONFIG_CGROUPS 647#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 {
369}; 369};
370 370
371struct audit_tty_status { 371struct audit_tty_status {
372 __u32 enabled; /* 1 = enabled, 0 = disabled */ 372 __u32 enabled; /* 1 = enabled, 0 = disabled */
373 __u32 log_passwd; /* 1 = enabled, 0 = disabled */
373}; 374};
374 375
375/* audit_rule_data supports filter rules with both integer and string 376/* 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 @@
49#include <linux/slab.h> 49#include <linux/slab.h>
50#include <linux/err.h> 50#include <linux/err.h>
51#include <linux/kthread.h> 51#include <linux/kthread.h>
52#include <linux/kernel.h>
52 53
53#include <linux/audit.h> 54#include <linux/audit.h>
54 55
@@ -808,6 +809,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
808 809
809 spin_lock_irqsave(&tsk->sighand->siglock, flags); 810 spin_lock_irqsave(&tsk->sighand->siglock, flags);
810 s.enabled = tsk->signal->audit_tty != 0; 811 s.enabled = tsk->signal->audit_tty != 0;
812 s.log_passwd = tsk->signal->audit_tty_log_passwd;
811 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 813 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
812 814
813 audit_send_reply(NETLINK_CB(skb).portid, seq, 815 audit_send_reply(NETLINK_CB(skb).portid, seq,
@@ -815,18 +817,20 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
815 break; 817 break;
816 } 818 }
817 case AUDIT_TTY_SET: { 819 case AUDIT_TTY_SET: {
818 struct audit_tty_status *s; 820 struct audit_tty_status s;
819 struct task_struct *tsk = current; 821 struct task_struct *tsk = current;
820 unsigned long flags; 822 unsigned long flags;
821 823
822 if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) 824 memset(&s, 0, sizeof(s));
823 return -EINVAL; 825 /* guard against past and future API changes */
824 s = data; 826 memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len));
825 if (s->enabled != 0 && s->enabled != 1) 827 if ((s.enabled != 0 && s.enabled != 1) ||
828 (s.log_passwd != 0 && s.log_passwd != 1))
826 return -EINVAL; 829 return -EINVAL;
827 830
828 spin_lock_irqsave(&tsk->sighand->siglock, flags); 831 spin_lock_irqsave(&tsk->sighand->siglock, flags);
829 tsk->signal->audit_tty = s->enabled != 0; 832 tsk->signal->audit_tty = s.enabled;
833 tsk->signal->audit_tty_log_passwd = s.log_passwd;
830 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 834 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
831 break; 835 break;
832 } 836 }