^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Creating audit events from TTY input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors: Miloslav Trmac <mitr@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct tty_audit_buf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct mutex mutex; /* Protects all data below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) dev_t dev; /* The TTY which the data is from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned icanon:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) size_t valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) unsigned char *data; /* Allocated size N_TTY_BUF_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static struct tty_audit_buf *tty_audit_buf_ref(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) buf = current->signal->tty_audit_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) WARN_ON(buf == ERR_PTR(-ESRCH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static struct tty_audit_buf *tty_audit_buf_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) buf = kmalloc(sizeof(*buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!buf->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) goto err_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mutex_init(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) buf->dev = MKDEV(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) buf->icanon = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) buf->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) err_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void tty_audit_buf_free(struct tty_audit_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) WARN_ON(buf->valid != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) kfree(buf->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void tty_audit_log(const char *description, dev_t dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned char *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct audit_buffer *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) pid_t pid = task_pid_nr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) uid_t uid = from_kuid(&init_user_ns, task_uid(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int sessionid = audit_get_sessionid(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_TTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) char name[sizeof(current->comm)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) " minor=%d comm=", description, pid, uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) loginuid, sessionid, MAJOR(dev), MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) get_task_comm(name, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) audit_log_untrustedstring(ab, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) audit_log_format(ab, " data=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) audit_log_n_hex(ab, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) audit_log_end(ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * tty_audit_buf_push - Push buffered data out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Generate an audit message from the contents of @buf, which is owned by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * the current task. @buf->mutex must be locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void tty_audit_buf_push(struct tty_audit_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (buf->valid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (audit_enabled == AUDIT_OFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) buf->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) tty_audit_log("tty", buf->dev, buf->data, buf->valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) buf->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * tty_audit_exit - Handle a task exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Make sure all buffered data is written out and deallocate the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Only needs to be called if current->signal->tty_audit_buf != %NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * The process is single-threaded at this point; no other threads share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * current->signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) void tty_audit_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) buf = xchg(¤t->signal->tty_audit_buf, ERR_PTR(-ESRCH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) tty_audit_buf_push(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) tty_audit_buf_free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * tty_audit_fork - Copy TTY audit state for a new task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Set up TTY audit state in @sig from current. @sig needs no locking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void tty_audit_fork(struct signal_struct *sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) sig->audit_tty = current->signal->audit_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * tty_audit_tiocsti - Log TIOCSTI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) void tty_audit_tiocsti(struct tty_struct *tty, char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev_t dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev = MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (tty_audit_push())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (audit_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) tty_audit_log("ioctl=TIOCSTI", dev, &ch, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * tty_audit_push - Flush current's pending audit data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Returns 0 if success, -EPERM if tty audit is disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int tty_audit_push(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (~current->signal->audit_tty & AUDIT_TTY_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) buf = tty_audit_buf_ref();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!IS_ERR_OR_NULL(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mutex_lock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) tty_audit_buf_push(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) mutex_unlock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * tty_audit_buf_get - Get an audit buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Get an audit buffer, allocate it if necessary. Return %NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * if out of memory or ERR_PTR(-ESRCH) if tty_audit_exit() has already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * occurred. Otherwise, return a new reference to the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static struct tty_audit_buf *tty_audit_buf_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) buf = tty_audit_buf_ref();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) buf = tty_audit_buf_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) audit_log_lost("out of memory in TTY auditing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Race to use this buffer, free it if another wins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (cmpxchg(¤t->signal->tty_audit_buf, NULL, buf) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) tty_audit_buf_free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return tty_audit_buf_ref();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * tty_audit_add_data - Add data for TTY auditing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Audit @data of @size from @tty, if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct tty_audit_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int icanon = !!L_ICANON(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned int audit_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dev_t dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) audit_tty = READ_ONCE(current->signal->audit_tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (~audit_tty & AUDIT_TTY_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (unlikely(size == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (tty->driver->type == TTY_DRIVER_TYPE_PTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) && tty->driver->subtype == PTY_TYPE_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if ((~audit_tty & AUDIT_TTY_LOG_PASSWD) && icanon && !L_ECHO(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) buf = tty_audit_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (IS_ERR_OR_NULL(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mutex_lock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev = MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (buf->dev != dev || buf->icanon != icanon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tty_audit_buf_push(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) buf->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) buf->icanon = icanon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) size_t run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) run = N_TTY_BUF_SIZE - buf->valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (run > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) run = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) memcpy(buf->data + buf->valid, data, run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) buf->valid += run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) data += run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) size -= run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (buf->valid == N_TTY_BUF_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) tty_audit_buf_push(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } while (size != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mutex_unlock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }