audit: use spin_lock_irqsave/restore in audit tty code
Some of the callers of the audit tty function use spin_lock_irqsave/restore. We were using the forced always enable version, which seems really bad. Since I don't know every one of these code paths well enough, it makes sense to just switch everything to the safe version. Maybe it's a little overzealous, but it's a lot better than an unlucky deadlock when we return to a caller with irq enabled and they expect it to be disabled. Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
parent
4d3fb709b2
commit
bde02ca858
|
@ -111,11 +111,12 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf)
|
|||
void tty_audit_exit(void)
|
||||
{
|
||||
struct tty_audit_buf *buf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
buf = current->signal->tty_audit_buf;
|
||||
current->signal->tty_audit_buf = NULL;
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
|
@ -133,9 +134,11 @@ void tty_audit_exit(void)
|
|||
*/
|
||||
void tty_audit_fork(struct signal_struct *sig)
|
||||
{
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
sig->audit_tty = current->signal->audit_tty;
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,13 +148,14 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
|
|||
{
|
||||
struct tty_audit_buf *buf;
|
||||
int major, minor, should_audit;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
should_audit = current->signal->audit_tty;
|
||||
buf = current->signal->tty_audit_buf;
|
||||
if (buf)
|
||||
atomic_inc(&buf->count);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
|
||||
major = tty->driver->major;
|
||||
minor = tty->driver->minor_start + tty->index;
|
||||
|
@ -221,10 +225,11 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
|
|||
unsigned icanon)
|
||||
{
|
||||
struct tty_audit_buf *buf, *buf2;
|
||||
unsigned long flags;
|
||||
|
||||
buf = NULL;
|
||||
buf2 = NULL;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
if (likely(!current->signal->audit_tty))
|
||||
goto out;
|
||||
buf = current->signal->tty_audit_buf;
|
||||
|
@ -232,7 +237,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
|
|||
atomic_inc(&buf->count);
|
||||
goto out;
|
||||
}
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
|
||||
buf2 = tty_audit_buf_alloc(tty->driver->major,
|
||||
tty->driver->minor_start + tty->index,
|
||||
|
@ -242,7 +247,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
if (!current->signal->audit_tty)
|
||||
goto out;
|
||||
buf = current->signal->tty_audit_buf;
|
||||
|
@ -254,7 +259,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
|
|||
atomic_inc(&buf->count);
|
||||
/* Fall through */
|
||||
out:
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
if (buf2)
|
||||
tty_audit_buf_free(buf2);
|
||||
return buf;
|
||||
|
@ -317,16 +322,17 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
|
|||
void tty_audit_push(struct tty_struct *tty)
|
||||
{
|
||||
struct tty_audit_buf *buf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
if (likely(!current->signal->audit_tty)) {
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
return;
|
||||
}
|
||||
buf = current->signal->tty_audit_buf;
|
||||
if (buf)
|
||||
atomic_inc(&buf->count);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
|
||||
if (buf) {
|
||||
int major, minor;
|
||||
|
|
|
@ -804,10 +804,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
case AUDIT_TTY_GET: {
|
||||
struct audit_tty_status s;
|
||||
struct task_struct *tsk = current;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
spin_lock_irqsave(&tsk->sighand->siglock, flags);
|
||||
s.enabled = tsk->signal->audit_tty != 0;
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
||||
|
||||
audit_send_reply(NETLINK_CB(skb).portid, seq,
|
||||
AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
|
||||
|
@ -816,6 +817,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
case AUDIT_TTY_SET: {
|
||||
struct audit_tty_status *s;
|
||||
struct task_struct *tsk = current;
|
||||
unsigned long flags;
|
||||
|
||||
if (nlh->nlmsg_len < sizeof(struct audit_tty_status))
|
||||
return -EINVAL;
|
||||
|
@ -823,9 +825,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (s->enabled != 0 && s->enabled != 1)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
spin_lock_irqsave(&tsk->sighand->siglock, flags);
|
||||
tsk->signal->audit_tty = s->enabled != 0;
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue