History

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.

Eric Paris committed 13 years ago

Commit bde02ca1 parent 4d3fb702 files · +25 −17Browse files

Unified · Split

2 files
  1. drivers/tty/tty_audit.c +19 −13
  2. kernel/audit.c +6 −4
drivers/tty/tty_audit.c+19−13
@@ -111,11 +111,12 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf) · 110 unmodified lines
111void tty_audit_exit(void)111void tty_audit_exit(void)
112{112{
113 struct tty_audit_buf *buf;113 struct tty_audit_buf *buf;
114 unsigned long flags;
114 115
115 spin_lock_irq(&current->sighand->siglock);116 spin_lock_irqsave(&current->sighand->siglock, flags);
116 buf = current->signal->tty_audit_buf;117 buf = current->signal->tty_audit_buf;
117 current->signal->tty_audit_buf = NULL;118 current->signal->tty_audit_buf = NULL;
118 spin_unlock_irq(&current->sighand->siglock);119 spin_unlock_irqrestore(&current->sighand->siglock, flags);
119 if (!buf)120 if (!buf)
120 return;121 return;
121 122
@@ -133,9 +134,11 @@ void tty_audit_exit(void) · 11 unmodified lines
133 */134 */
134void tty_audit_fork(struct signal_struct *sig)135void tty_audit_fork(struct signal_struct *sig)
135{136{
136 spin_lock_irq(&current->sighand->siglock);137 unsigned long flags;
138
139 spin_lock_irqsave(&current->sighand->siglock, flags);
137 sig->audit_tty = current->signal->audit_tty;140 sig->audit_tty = current->signal->audit_tty;
138 spin_unlock_irq(&current->sighand->siglock);141 spin_unlock_irqrestore(&current->sighand->siglock, flags);
139}142}
140 143
141/**144/**
@@ -145,13 +148,14 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) · 3 unmodified lines
145{148{
146 struct tty_audit_buf *buf;149 struct tty_audit_buf *buf;
147 int major, minor, should_audit;150 int major, minor, should_audit;
151 unsigned long flags;
148 152
149 spin_lock_irq(&current->sighand->siglock);153 spin_lock_irqsave(&current->sighand->siglock, flags);
150 should_audit = current->signal->audit_tty;154 should_audit = current->signal->audit_tty;
151 buf = current->signal->tty_audit_buf;155 buf = current->signal->tty_audit_buf;
152 if (buf)156 if (buf)
153 atomic_inc(&buf->count);157 atomic_inc(&buf->count);
154 spin_unlock_irq(&current->sighand->siglock);158 spin_unlock_irqrestore(&current->sighand->siglock, flags);
155 159
156 major = tty->driver->major;160 major = tty->driver->major;
157 minor = tty->driver->minor_start + tty->index;161 minor = tty->driver->minor_start + tty->index;
@@ -221,10 +225,11 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, · 63 unmodified lines
221 unsigned icanon)225 unsigned icanon)
222{226{
223 struct tty_audit_buf *buf, *buf2;227 struct tty_audit_buf *buf, *buf2;
228 unsigned long flags;
224 229
225 buf = NULL;230 buf = NULL;
226 buf2 = NULL;231 buf2 = NULL;
227 spin_lock_irq(&current->sighand->siglock);232 spin_lock_irqsave(&current->sighand->siglock, flags);
228 if (likely(!current->signal->audit_tty))233 if (likely(!current->signal->audit_tty))
229 goto out;234 goto out;
230 buf = current->signal->tty_audit_buf;235 buf = current->signal->tty_audit_buf;
@@ -232,7 +237,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, · 1 unmodified line
232 atomic_inc(&buf->count);237 atomic_inc(&buf->count);
233 goto out;238 goto out;
234 }239 }
235 spin_unlock_irq(&current->sighand->siglock);240 spin_unlock_irqrestore(&current->sighand->siglock, flags);
236 241
237 buf2 = tty_audit_buf_alloc(tty->driver->major,242 buf2 = tty_audit_buf_alloc(tty->driver->major,
238 tty->driver->minor_start + tty->index,243 tty->driver->minor_start + tty->index,
@@ -242,7 +247,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, · 3 unmodified lines
242 return NULL;247 return NULL;
243 }248 }
244 249
245 spin_lock_irq(&current->sighand->siglock);250 spin_lock_irqsave(&current->sighand->siglock, flags);
246 if (!current->signal->audit_tty)251 if (!current->signal->audit_tty)
247 goto out;252 goto out;
248 buf = current->signal->tty_audit_buf;253 buf = current->signal->tty_audit_buf;
@@ -254,7 +259,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, · 5 unmodified lines
254 atomic_inc(&buf->count);259 atomic_inc(&buf->count);
255 /* Fall through */260 /* Fall through */
256 out:261 out:
257 spin_unlock_irq(&current->sighand->siglock);262 spin_unlock_irqrestore(&current->sighand->siglock, flags);
258 if (buf2)263 if (buf2)
259 tty_audit_buf_free(buf2);264 tty_audit_buf_free(buf2);
260 return buf;265 return buf;
@@ -317,16 +322,17 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, · 56 unmodified lines
317void tty_audit_push(struct tty_struct *tty)322void tty_audit_push(struct tty_struct *tty)
318{323{
319 struct tty_audit_buf *buf;324 struct tty_audit_buf *buf;
325 unsigned long flags;
320 326
321 spin_lock_irq(&current->sighand->siglock);327 spin_lock_irqsave(&current->sighand->siglock, flags);
322 if (likely(!current->signal->audit_tty)) {328 if (likely(!current->signal->audit_tty)) {
323 spin_unlock_irq(&current->sighand->siglock);329 spin_unlock_irqrestore(&current->sighand->siglock, flags);
324 return;330 return;
325 }331 }
326 buf = current->signal->tty_audit_buf;332 buf = current->signal->tty_audit_buf;
327 if (buf)333 if (buf)
328 atomic_inc(&buf->count);334 atomic_inc(&buf->count);
329 spin_unlock_irq(&current->sighand->siglock);335 spin_unlock_irqrestore(&current->sighand->siglock, flags);
330 336
331 if (buf) {337 if (buf) {
332 int major, minor;338 int major, minor;
kernel/audit.c+6−4
@@ -804,10 +804,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) · 803 unmodified lines
804 case AUDIT_TTY_GET: {804 case AUDIT_TTY_GET: {
805 struct audit_tty_status s;805 struct audit_tty_status s;
806 struct task_struct *tsk = current;806 struct task_struct *tsk = current;
807 unsigned long flags;
807 808
808 spin_lock_irq(&tsk->sighand->siglock);809 spin_lock_irqsave(&tsk->sighand->siglock, flags);
809 s.enabled = tsk->signal->audit_tty != 0;810 s.enabled = tsk->signal->audit_tty != 0;
810 spin_unlock_irq(&tsk->sighand->siglock);811 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
811 812
812 audit_send_reply(NETLINK_CB(skb).portid, seq,813 audit_send_reply(NETLINK_CB(skb).portid, seq,
813 AUDIT_TTY_GET, 0, 0, &s, sizeof(s));814 AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
@@ -816,6 +817,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) · 2 unmodified lines
816 case AUDIT_TTY_SET: {817 case AUDIT_TTY_SET: {
817 struct audit_tty_status *s;818 struct audit_tty_status *s;
818 struct task_struct *tsk = current;819 struct task_struct *tsk = current;
820 unsigned long flags;
819 821
820 if (nlh->nlmsg_len < sizeof(struct audit_tty_status))822 if (nlh->nlmsg_len < sizeof(struct audit_tty_status))
821 return -EINVAL;823 return -EINVAL;
@@ -823,9 +825,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) · 1 unmodified line
823 if (s->enabled != 0 && s->enabled != 1)825 if (s->enabled != 0 && s->enabled != 1)
824 return -EINVAL;826 return -EINVAL;
825 827
826 spin_lock_irq(&tsk->sighand->siglock);828 spin_lock_irqsave(&tsk->sighand->siglock, flags);
827 tsk->signal->audit_tty = s->enabled != 0;829 tsk->signal->audit_tty = s->enabled != 0;
828 spin_unlock_irq(&tsk->sighand->siglock);830 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
829 break;831 break;
830 }832 }
831 default:833 default:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t