// SPDX-License-Identifier: GPL-2.0 /* * Creating audit events from TTY input. * * Copyright (C) 2007 Red Hat, Inc. All rights reserved. * * Authors: Miloslav Trmac <mitr@redhat.com>
*/
struct tty_audit_buf { struct mutex mutex; /* Protects all data below */
dev_t dev; /* The TTY which the data is from */ bool icanon;
size_t valid;
u8 *data; /* Allocated size TTY_AUDIT_BUF_SIZE */
};
/* * tty_audit_buf_push - Push buffered data out * * Generate an audit message from the contents of @buf, which is owned by * the current task. @buf->mutex must be locked.
*/ staticvoid tty_audit_buf_push(struct tty_audit_buf *buf)
{ if (buf->valid == 0) return; if (audit_enabled == AUDIT_OFF) {
buf->valid = 0; return;
}
tty_audit_log("tty", buf->dev, buf->data, buf->valid);
buf->valid = 0;
}
/** * tty_audit_exit - Handle a task exit * * Make sure all buffered data is written out and deallocate the buffer. * Only needs to be called if current->signal->tty_audit_buf != %NULL. * * The process is single-threaded at this point; no other threads share * current->signal.
*/ void tty_audit_exit(void)
{ struct tty_audit_buf *buf;
buf = xchg(¤t->signal->tty_audit_buf, ERR_PTR(-ESRCH)); if (!buf) return;
/* * tty_audit_fork - Copy TTY audit state for a new task * * Set up TTY audit state in @sig from current. @sig needs no locking.
*/ void tty_audit_fork(struct signal_struct *sig)
{
sig->audit_tty = current->signal->audit_tty;
}
/* * tty_audit_buf_get - Get an audit buffer. * * Get an audit buffer, allocate it if necessary. Return %NULL * if out of memory or ERR_PTR(-ESRCH) if tty_audit_exit() has already * occurred. Otherwise, return a new reference to the buffer.
*/ staticstruct tty_audit_buf *tty_audit_buf_get(void)
{ struct tty_audit_buf *buf;
buf = tty_audit_buf_ref(); if (buf) return buf;
buf = tty_audit_buf_alloc(); if (buf == NULL) {
audit_log_lost("out of memory in TTY auditing"); return NULL;
}
/* Race to use this buffer, free it if another wins */ if (cmpxchg(¤t->signal->tty_audit_buf, NULL, buf) != NULL)
tty_audit_buf_free(buf); return tty_audit_buf_ref();
}
/* * tty_audit_add_data - Add data for TTY auditing. * * Audit @data of @size from @tty, if necessary.
*/ void tty_audit_add_data(conststruct tty_struct *tty, constvoid *data,
size_t size)
{ struct tty_audit_buf *buf; unsignedint audit_tty; bool icanon = L_ICANON(tty);
dev_t dev;
audit_tty = READ_ONCE(current->signal->audit_tty); if (~audit_tty & AUDIT_TTY_ENABLE) return;
if (unlikely(size == 0)) return;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY
&& tty->driver->subtype == PTY_TYPE_MASTER) return;
if ((~audit_tty & AUDIT_TTY_LOG_PASSWD) && icanon && !L_ECHO(tty)) return;
buf = tty_audit_buf_get(); if (IS_ERR_OR_NULL(buf)) return;
mutex_lock(&buf->mutex);
dev = MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; if (buf->dev != dev || buf->icanon != icanon) {
tty_audit_buf_push(buf);
buf->dev = dev;
buf->icanon = icanon;
} do {
size_t run;
run = TTY_AUDIT_BUF_SIZE - buf->valid; if (run > size)
run = size;
memcpy(buf->data + buf->valid, data, run);
buf->valid += run;
data += run;
size -= run; if (buf->valid == TTY_AUDIT_BUF_SIZE)
tty_audit_buf_push(buf);
} while (size != 0);
mutex_unlock(&buf->mutex);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.