]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/tty/tty_audit.c
2 * Creating audit events from TTY input.
4 * Copyright (C) 2007 Red Hat, Inc. All rights reserved. This copyrighted
5 * material is made available to anyone wishing to use, modify, copy, or
6 * redistribute it subject to the terms and conditions of the GNU General
9 * Authors: Miloslav Trmac <mitr@redhat.com>
12 #include <linux/audit.h>
13 #include <linux/slab.h>
14 #include <linux/tty.h>
16 struct tty_audit_buf
{
18 struct mutex mutex
; /* Protects all data below */
19 dev_t dev
; /* The TTY which the data is from */
22 unsigned char *data
; /* Allocated size N_TTY_BUF_SIZE */
25 static struct tty_audit_buf
*tty_audit_buf_alloc(void)
27 struct tty_audit_buf
*buf
;
29 buf
= kmalloc(sizeof(*buf
), GFP_KERNEL
);
32 buf
->data
= kmalloc(N_TTY_BUF_SIZE
, GFP_KERNEL
);
35 atomic_set(&buf
->count
, 1);
36 mutex_init(&buf
->mutex
);
37 buf
->dev
= MKDEV(0, 0);
48 static void tty_audit_buf_free(struct tty_audit_buf
*buf
)
50 WARN_ON(buf
->valid
!= 0);
55 static void tty_audit_buf_put(struct tty_audit_buf
*buf
)
57 if (atomic_dec_and_test(&buf
->count
))
58 tty_audit_buf_free(buf
);
61 static void tty_audit_log(const char *description
, dev_t dev
,
62 unsigned char *data
, size_t size
)
64 struct audit_buffer
*ab
;
65 struct task_struct
*tsk
= current
;
66 pid_t pid
= task_pid_nr(tsk
);
67 uid_t uid
= from_kuid(&init_user_ns
, task_uid(tsk
));
68 uid_t loginuid
= from_kuid(&init_user_ns
, audit_get_loginuid(tsk
));
69 unsigned int sessionid
= audit_get_sessionid(tsk
);
71 ab
= audit_log_start(NULL
, GFP_KERNEL
, AUDIT_TTY
);
73 char name
[sizeof(tsk
->comm
)];
75 audit_log_format(ab
, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
76 " minor=%d comm=", description
, pid
, uid
,
77 loginuid
, sessionid
, MAJOR(dev
), MINOR(dev
));
78 get_task_comm(name
, tsk
);
79 audit_log_untrustedstring(ab
, name
);
80 audit_log_format(ab
, " data=");
81 audit_log_n_hex(ab
, data
, size
);
87 * tty_audit_buf_push - Push buffered data out
89 * Generate an audit message from the contents of @buf, which is owned by
90 * the current task. @buf->mutex must be locked.
92 static void tty_audit_buf_push(struct tty_audit_buf
*buf
)
96 if (audit_enabled
== 0) {
100 tty_audit_log("tty", buf
->dev
, buf
->data
, buf
->valid
);
105 * tty_audit_exit - Handle a task exit
107 * Make sure all buffered data is written out and deallocate the buffer.
108 * Only needs to be called if current->signal->tty_audit_buf != %NULL.
110 void tty_audit_exit(void)
112 struct tty_audit_buf
*buf
;
114 buf
= current
->signal
->tty_audit_buf
;
115 current
->signal
->tty_audit_buf
= NULL
;
119 mutex_lock(&buf
->mutex
);
120 tty_audit_buf_push(buf
);
121 mutex_unlock(&buf
->mutex
);
123 tty_audit_buf_put(buf
);
127 * tty_audit_fork - Copy TTY audit state for a new task
129 * Set up TTY audit state in @sig from current. @sig needs no locking.
131 void tty_audit_fork(struct signal_struct
*sig
)
133 sig
->audit_tty
= current
->signal
->audit_tty
;
137 * tty_audit_tiocsti - Log TIOCSTI
139 void tty_audit_tiocsti(struct tty_struct
*tty
, char ch
)
141 struct tty_audit_buf
*buf
;
145 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
146 buf
= current
->signal
->tty_audit_buf
;
148 atomic_inc(&buf
->count
);
149 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
151 dev
= MKDEV(tty
->driver
->major
, tty
->driver
->minor_start
) + tty
->index
;
153 mutex_lock(&buf
->mutex
);
155 tty_audit_buf_push(buf
);
156 mutex_unlock(&buf
->mutex
);
157 tty_audit_buf_put(buf
);
160 if (audit_enabled
&& (current
->signal
->audit_tty
& AUDIT_TTY_ENABLE
)) {
162 unsigned int sessionid
;
164 auid
= audit_get_loginuid(current
);
165 sessionid
= audit_get_sessionid(current
);
166 tty_audit_log("ioctl=TIOCSTI", dev
, &ch
, 1);
171 * tty_audit_push - Flush current's pending audit data
173 * Returns 0 if success, -EPERM if tty audit is disabled
175 int tty_audit_push(void)
177 struct tty_audit_buf
*buf
;
180 if (~current
->signal
->audit_tty
& AUDIT_TTY_ENABLE
)
183 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
184 buf
= current
->signal
->tty_audit_buf
;
186 atomic_inc(&buf
->count
);
187 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
190 mutex_lock(&buf
->mutex
);
191 tty_audit_buf_push(buf
);
192 mutex_unlock(&buf
->mutex
);
194 tty_audit_buf_put(buf
);
200 * tty_audit_buf_get - Get an audit buffer.
202 * Get an audit buffer, allocate it if necessary. Return %NULL
203 * if TTY auditing is disabled or out of memory. Otherwise, return a new
204 * reference to the buffer.
206 static struct tty_audit_buf
*tty_audit_buf_get(void)
208 struct tty_audit_buf
*buf
, *buf2
;
213 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
214 buf
= current
->signal
->tty_audit_buf
;
216 atomic_inc(&buf
->count
);
219 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
221 buf2
= tty_audit_buf_alloc();
223 audit_log_lost("out of memory in TTY auditing");
227 if (~current
->signal
->audit_tty
& AUDIT_TTY_ENABLE
)
230 spin_lock_irqsave(¤t
->sighand
->siglock
, flags
);
231 buf
= current
->signal
->tty_audit_buf
;
233 current
->signal
->tty_audit_buf
= buf2
;
237 atomic_inc(&buf
->count
);
240 spin_unlock_irqrestore(¤t
->sighand
->siglock
, flags
);
242 tty_audit_buf_free(buf2
);
247 * tty_audit_add_data - Add data for TTY auditing.
249 * Audit @data of @size from @tty, if necessary.
251 void tty_audit_add_data(struct tty_struct
*tty
, const void *data
, size_t size
)
253 struct tty_audit_buf
*buf
;
254 unsigned int icanon
= !!L_ICANON(tty
);
255 unsigned int audit_tty
;
258 if (unlikely(size
== 0))
261 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
262 && tty
->driver
->subtype
== PTY_TYPE_MASTER
)
265 audit_tty
= READ_ONCE(current
->signal
->audit_tty
);
266 if (~audit_tty
& AUDIT_TTY_ENABLE
)
268 if ((~audit_tty
& AUDIT_TTY_LOG_PASSWD
) && icanon
&& !L_ECHO(tty
))
271 buf
= tty_audit_buf_get();
275 mutex_lock(&buf
->mutex
);
276 dev
= MKDEV(tty
->driver
->major
, tty
->driver
->minor_start
) + tty
->index
;
277 if (buf
->dev
!= dev
|| buf
->icanon
!= icanon
) {
278 tty_audit_buf_push(buf
);
280 buf
->icanon
= icanon
;
285 run
= N_TTY_BUF_SIZE
- buf
->valid
;
288 memcpy(buf
->data
+ buf
->valid
, data
, run
);
292 if (buf
->valid
== N_TTY_BUF_SIZE
)
293 tty_audit_buf_push(buf
);
295 mutex_unlock(&buf
->mutex
);
296 tty_audit_buf_put(buf
);