Commit 46e959ea authored by Richard Guy Briggs's avatar Richard Guy Briggs Committed by Eric Paris

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: default avatarRichard Guy Briggs <rgb@redhat.com>
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent bde02ca8
...@@ -138,6 +138,7 @@ void tty_audit_fork(struct signal_struct *sig) ...@@ -138,6 +138,7 @@ void tty_audit_fork(struct signal_struct *sig)
spin_lock_irqsave(&current->sighand->siglock, flags); spin_lock_irqsave(&current->sighand->siglock, flags);
sig->audit_tty = current->signal->audit_tty; 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); spin_unlock_irqrestore(&current->sighand->siglock, flags);
} }
...@@ -275,10 +276,18 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, ...@@ -275,10 +276,18 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
{ {
struct tty_audit_buf *buf; struct tty_audit_buf *buf;
int major, minor; int major, minor;
int audit_log_tty_passwd;
unsigned long flags;
if (unlikely(size == 0)) if (unlikely(size == 0))
return; 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 if (tty->driver->type == TTY_DRIVER_TYPE_PTY
&& tty->driver->subtype == PTY_TYPE_MASTER) && tty->driver->subtype == PTY_TYPE_MASTER)
return; return;
......
...@@ -641,6 +641,7 @@ struct signal_struct { ...@@ -641,6 +641,7 @@ struct signal_struct {
#endif #endif
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
unsigned audit_tty; unsigned audit_tty;
unsigned audit_tty_log_passwd;
struct tty_audit_buf *tty_audit_buf; struct tty_audit_buf *tty_audit_buf;
#endif #endif
#ifdef CONFIG_CGROUPS #ifdef CONFIG_CGROUPS
......
...@@ -370,6 +370,7 @@ struct audit_status { ...@@ -370,6 +370,7 @@ struct audit_status {
struct audit_tty_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 /* audit_rule_data supports filter rules with both integer and string
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/kernel.h>
#include <linux/audit.h> #include <linux/audit.h>
...@@ -808,6 +809,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -808,6 +809,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
spin_lock_irqsave(&tsk->sighand->siglock, flags); spin_lock_irqsave(&tsk->sighand->siglock, flags);
s.enabled = tsk->signal->audit_tty != 0; s.enabled = tsk->signal->audit_tty != 0;
s.log_passwd = tsk->signal->audit_tty_log_passwd;
spin_unlock_irqrestore(&tsk->sighand->siglock, flags); spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
audit_send_reply(NETLINK_CB(skb).portid, seq, 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,18 +817,20 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break; break;
} }
case AUDIT_TTY_SET: { case AUDIT_TTY_SET: {
struct audit_tty_status *s; struct audit_tty_status s;
struct task_struct *tsk = current; struct task_struct *tsk = current;
unsigned long flags; unsigned long flags;
if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) memset(&s, 0, sizeof(s));
return -EINVAL; /* guard against past and future API changes */
s = data; memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len));
if (s->enabled != 0 && s->enabled != 1) if ((s.enabled != 0 && s.enabled != 1) ||
(s.log_passwd != 0 && s.log_passwd != 1))
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&tsk->sighand->siglock, flags); 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); spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment