aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_audit.c')
-rw-r--r--drivers/tty/tty_audit.c104
1 files changed, 45 insertions, 59 deletions
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index 6953dc82850c..a4fdce74f883 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -60,24 +60,22 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
60 tty_audit_buf_free(buf); 60 tty_audit_buf_free(buf);
61} 61}
62 62
63static void tty_audit_log(const char *description, struct task_struct *tsk, 63static void tty_audit_log(const char *description, int major, int minor,
64 kuid_t loginuid, unsigned sessionid, int major, 64 unsigned char *data, size_t size)
65 int minor, unsigned char *data, size_t size)
66{ 65{
67 struct audit_buffer *ab; 66 struct audit_buffer *ab;
67 struct task_struct *tsk = current;
68 uid_t uid = from_kuid(&init_user_ns, task_uid(tsk));
69 uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk));
70 u32 sessionid = audit_get_sessionid(tsk);
68 71
69 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); 72 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
70 if (ab) { 73 if (ab) {
71 char name[sizeof(tsk->comm)]; 74 char name[sizeof(tsk->comm)];
72 kuid_t uid = task_uid(tsk); 75
73 76 audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
74 audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u " 77 " minor=%d comm=", description, tsk->pid, uid,
75 "major=%d minor=%d comm=", description, 78 loginuid, sessionid, major, minor);
76 tsk->pid,
77 from_kuid(&init_user_ns, uid),
78 from_kuid(&init_user_ns, loginuid),
79 sessionid,
80 major, minor);
81 get_task_comm(name, tsk); 79 get_task_comm(name, tsk);
82 audit_log_untrustedstring(ab, name); 80 audit_log_untrustedstring(ab, name);
83 audit_log_format(ab, " data="); 81 audit_log_format(ab, " data=");
@@ -90,11 +88,9 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,
90 * tty_audit_buf_push - Push buffered data out 88 * tty_audit_buf_push - Push buffered data out
91 * 89 *
92 * Generate an audit message from the contents of @buf, which is owned by 90 * Generate an audit message from the contents of @buf, which is owned by
93 * @tsk with @loginuid. @buf->mutex must be locked. 91 * the current task. @buf->mutex must be locked.
94 */ 92 */
95static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid, 93static void tty_audit_buf_push(struct tty_audit_buf *buf)
96 unsigned int sessionid,
97 struct tty_audit_buf *buf)
98{ 94{
99 if (buf->valid == 0) 95 if (buf->valid == 0)
100 return; 96 return;
@@ -102,25 +98,11 @@ static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid,
102 buf->valid = 0; 98 buf->valid = 0;
103 return; 99 return;
104 } 100 }
105 tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor, 101 tty_audit_log("tty", buf->major, buf->minor, buf->data, buf->valid);
106 buf->data, buf->valid);
107 buf->valid = 0; 102 buf->valid = 0;
108} 103}
109 104
110/** 105/**
111 * tty_audit_buf_push_current - Push buffered data out
112 *
113 * Generate an audit message from the contents of @buf, which is owned by
114 * the current task. @buf->mutex must be locked.
115 */
116static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
117{
118 kuid_t auid = audit_get_loginuid(current);
119 unsigned int sessionid = audit_get_sessionid(current);
120 tty_audit_buf_push(current, auid, sessionid, buf);
121}
122
123/**
124 * tty_audit_exit - Handle a task exit 106 * tty_audit_exit - Handle a task exit
125 * 107 *
126 * Make sure all buffered data is written out and deallocate the buffer. 108 * Make sure all buffered data is written out and deallocate the buffer.
@@ -130,15 +112,13 @@ void tty_audit_exit(void)
130{ 112{
131 struct tty_audit_buf *buf; 113 struct tty_audit_buf *buf;
132 114
133 spin_lock_irq(&current->sighand->siglock);
134 buf = current->signal->tty_audit_buf; 115 buf = current->signal->tty_audit_buf;
135 current->signal->tty_audit_buf = NULL; 116 current->signal->tty_audit_buf = NULL;
136 spin_unlock_irq(&current->sighand->siglock);
137 if (!buf) 117 if (!buf)
138 return; 118 return;
139 119
140 mutex_lock(&buf->mutex); 120 mutex_lock(&buf->mutex);
141 tty_audit_buf_push_current(buf); 121 tty_audit_buf_push(buf);
142 mutex_unlock(&buf->mutex); 122 mutex_unlock(&buf->mutex);
143 123
144 tty_audit_buf_put(buf); 124 tty_audit_buf_put(buf);
@@ -151,9 +131,8 @@ void tty_audit_exit(void)
151 */ 131 */
152void tty_audit_fork(struct signal_struct *sig) 132void tty_audit_fork(struct signal_struct *sig)
153{ 133{
154 spin_lock_irq(&current->sighand->siglock);
155 sig->audit_tty = current->signal->audit_tty; 134 sig->audit_tty = current->signal->audit_tty;
156 spin_unlock_irq(&current->sighand->siglock); 135 sig->audit_tty_log_passwd = current->signal->audit_tty_log_passwd;
157} 136}
158 137
159/** 138/**
@@ -163,20 +142,21 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
163{ 142{
164 struct tty_audit_buf *buf; 143 struct tty_audit_buf *buf;
165 int major, minor, should_audit; 144 int major, minor, should_audit;
145 unsigned long flags;
166 146
167 spin_lock_irq(&current->sighand->siglock); 147 spin_lock_irqsave(&current->sighand->siglock, flags);
168 should_audit = current->signal->audit_tty; 148 should_audit = current->signal->audit_tty;
169 buf = current->signal->tty_audit_buf; 149 buf = current->signal->tty_audit_buf;
170 if (buf) 150 if (buf)
171 atomic_inc(&buf->count); 151 atomic_inc(&buf->count);
172 spin_unlock_irq(&current->sighand->siglock); 152 spin_unlock_irqrestore(&current->sighand->siglock, flags);
173 153
174 major = tty->driver->major; 154 major = tty->driver->major;
175 minor = tty->driver->minor_start + tty->index; 155 minor = tty->driver->minor_start + tty->index;
176 if (buf) { 156 if (buf) {
177 mutex_lock(&buf->mutex); 157 mutex_lock(&buf->mutex);
178 if (buf->major == major && buf->minor == minor) 158 if (buf->major == major && buf->minor == minor)
179 tty_audit_buf_push_current(buf); 159 tty_audit_buf_push(buf);
180 mutex_unlock(&buf->mutex); 160 mutex_unlock(&buf->mutex);
181 tty_audit_buf_put(buf); 161 tty_audit_buf_put(buf);
182 } 162 }
@@ -187,24 +167,20 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
187 167
188 auid = audit_get_loginuid(current); 168 auid = audit_get_loginuid(current);
189 sessionid = audit_get_sessionid(current); 169 sessionid = audit_get_sessionid(current);
190 tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major, 170 tty_audit_log("ioctl=TIOCSTI", major, minor, &ch, 1);
191 minor, &ch, 1);
192 } 171 }
193} 172}
194 173
195/** 174/**
196 * tty_audit_push_task - Flush task's pending audit data 175 * tty_audit_push_current - Flush current's pending audit data
197 * @tsk: task pointer
198 * @loginuid: sender login uid
199 * @sessionid: sender session id
200 * 176 *
201 * Called with a ref on @tsk held. Try to lock sighand and get a 177 * Try to lock sighand and get a reference to the tty audit buffer if available.
202 * reference to the tty audit buffer if available.
203 * Flush the buffer or return an appropriate error code. 178 * Flush the buffer or return an appropriate error code.
204 */ 179 */
205int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid) 180int tty_audit_push_current(void)
206{ 181{
207 struct tty_audit_buf *buf = ERR_PTR(-EPERM); 182 struct tty_audit_buf *buf = ERR_PTR(-EPERM);
183 struct task_struct *tsk = current;
208 unsigned long flags; 184 unsigned long flags;
209 185
210 if (!lock_task_sighand(tsk, &flags)) 186 if (!lock_task_sighand(tsk, &flags))
@@ -225,7 +201,7 @@ int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
225 return PTR_ERR(buf); 201 return PTR_ERR(buf);
226 202
227 mutex_lock(&buf->mutex); 203 mutex_lock(&buf->mutex);
228 tty_audit_buf_push(tsk, loginuid, sessionid, buf); 204 tty_audit_buf_push(buf);
229 mutex_unlock(&buf->mutex); 205 mutex_unlock(&buf->mutex);
230 206
231 tty_audit_buf_put(buf); 207 tty_audit_buf_put(buf);
@@ -243,10 +219,11 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
243 unsigned icanon) 219 unsigned icanon)
244{ 220{
245 struct tty_audit_buf *buf, *buf2; 221 struct tty_audit_buf *buf, *buf2;
222 unsigned long flags;
246 223
247 buf = NULL; 224 buf = NULL;
248 buf2 = NULL; 225 buf2 = NULL;
249 spin_lock_irq(&current->sighand->siglock); 226 spin_lock_irqsave(&current->sighand->siglock, flags);
250 if (likely(!current->signal->audit_tty)) 227 if (likely(!current->signal->audit_tty))
251 goto out; 228 goto out;
252 buf = current->signal->tty_audit_buf; 229 buf = current->signal->tty_audit_buf;
@@ -254,7 +231,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
254 atomic_inc(&buf->count); 231 atomic_inc(&buf->count);
255 goto out; 232 goto out;
256 } 233 }
257 spin_unlock_irq(&current->sighand->siglock); 234 spin_unlock_irqrestore(&current->sighand->siglock, flags);
258 235
259 buf2 = tty_audit_buf_alloc(tty->driver->major, 236 buf2 = tty_audit_buf_alloc(tty->driver->major,
260 tty->driver->minor_start + tty->index, 237 tty->driver->minor_start + tty->index,
@@ -264,7 +241,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
264 return NULL; 241 return NULL;
265 } 242 }
266 243
267 spin_lock_irq(&current->sighand->siglock); 244 spin_lock_irqsave(&current->sighand->siglock, flags);
268 if (!current->signal->audit_tty) 245 if (!current->signal->audit_tty)
269 goto out; 246 goto out;
270 buf = current->signal->tty_audit_buf; 247 buf = current->signal->tty_audit_buf;
@@ -276,7 +253,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
276 atomic_inc(&buf->count); 253 atomic_inc(&buf->count);
277 /* Fall through */ 254 /* Fall through */
278 out: 255 out:
279 spin_unlock_irq(&current->sighand->siglock); 256 spin_unlock_irqrestore(&current->sighand->siglock, flags);
280 if (buf2) 257 if (buf2)
281 tty_audit_buf_free(buf2); 258 tty_audit_buf_free(buf2);
282 return buf; 259 return buf;
@@ -292,10 +269,18 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
292{ 269{
293 struct tty_audit_buf *buf; 270 struct tty_audit_buf *buf;
294 int major, minor; 271 int major, minor;
272 int audit_log_tty_passwd;
273 unsigned long flags;
295 274
296 if (unlikely(size == 0)) 275 if (unlikely(size == 0))
297 return; 276 return;
298 277
278 spin_lock_irqsave(&current->sighand->siglock, flags);
279 audit_log_tty_passwd = current->signal->audit_tty_log_passwd;
280 spin_unlock_irqrestore(&current->sighand->siglock, flags);
281 if (!audit_log_tty_passwd && icanon && !L_ECHO(tty))
282 return;
283
299 if (tty->driver->type == TTY_DRIVER_TYPE_PTY 284 if (tty->driver->type == TTY_DRIVER_TYPE_PTY
300 && tty->driver->subtype == PTY_TYPE_MASTER) 285 && tty->driver->subtype == PTY_TYPE_MASTER)
301 return; 286 return;
@@ -309,7 +294,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
309 minor = tty->driver->minor_start + tty->index; 294 minor = tty->driver->minor_start + tty->index;
310 if (buf->major != major || buf->minor != minor 295 if (buf->major != major || buf->minor != minor
311 || buf->icanon != icanon) { 296 || buf->icanon != icanon) {
312 tty_audit_buf_push_current(buf); 297 tty_audit_buf_push(buf);
313 buf->major = major; 298 buf->major = major;
314 buf->minor = minor; 299 buf->minor = minor;
315 buf->icanon = icanon; 300 buf->icanon = icanon;
@@ -325,7 +310,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
325 data += run; 310 data += run;
326 size -= run; 311 size -= run;
327 if (buf->valid == N_TTY_BUF_SIZE) 312 if (buf->valid == N_TTY_BUF_SIZE)
328 tty_audit_buf_push_current(buf); 313 tty_audit_buf_push(buf);
329 } while (size != 0); 314 } while (size != 0);
330 mutex_unlock(&buf->mutex); 315 mutex_unlock(&buf->mutex);
331 tty_audit_buf_put(buf); 316 tty_audit_buf_put(buf);
@@ -339,16 +324,17 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
339void tty_audit_push(struct tty_struct *tty) 324void tty_audit_push(struct tty_struct *tty)
340{ 325{
341 struct tty_audit_buf *buf; 326 struct tty_audit_buf *buf;
327 unsigned long flags;
342 328
343 spin_lock_irq(&current->sighand->siglock); 329 spin_lock_irqsave(&current->sighand->siglock, flags);
344 if (likely(!current->signal->audit_tty)) { 330 if (likely(!current->signal->audit_tty)) {
345 spin_unlock_irq(&current->sighand->siglock); 331 spin_unlock_irqrestore(&current->sighand->siglock, flags);
346 return; 332 return;
347 } 333 }
348 buf = current->signal->tty_audit_buf; 334 buf = current->signal->tty_audit_buf;
349 if (buf) 335 if (buf)
350 atomic_inc(&buf->count); 336 atomic_inc(&buf->count);
351 spin_unlock_irq(&current->sighand->siglock); 337 spin_unlock_irqrestore(&current->sighand->siglock, flags);
352 338
353 if (buf) { 339 if (buf) {
354 int major, minor; 340 int major, minor;
@@ -357,7 +343,7 @@ void tty_audit_push(struct tty_struct *tty)
357 minor = tty->driver->minor_start + tty->index; 343 minor = tty->driver->minor_start + tty->index;
358 mutex_lock(&buf->mutex); 344 mutex_lock(&buf->mutex);
359 if (buf->major == major && buf->minor == minor) 345 if (buf->major == major && buf->minor == minor)
360 tty_audit_buf_push_current(buf); 346 tty_audit_buf_push(buf);
361 mutex_unlock(&buf->mutex); 347 mutex_unlock(&buf->mutex);
362 tty_audit_buf_put(buf); 348 tty_audit_buf_put(buf);
363 } 349 }