aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_audit.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2013-04-30 11:01:14 -0400
committerEric Paris <eparis@redhat.com>2013-04-30 15:31:28 -0400
commitbde02ca858448cf54a4226774dd1481f3bcc455e (patch)
treed5d7144d1314cba0c055b3804db35e06987a7956 /drivers/tty/tty_audit.c
parent4d3fb709b285ac885c40950a837edbfc90029c5f (diff)
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>
Diffstat (limited to 'drivers/tty/tty_audit.c')
-rw-r--r--drivers/tty/tty_audit.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index ea2e5ad71731..755d418019c8 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -111,11 +111,12 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf)
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)
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)
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,
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,
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,
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,
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,
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;