| From b97b3d9fb57860a60592859e332de7759fd54c2e Mon Sep 17 00:00:00 2001 |
| From: Greg KH <greg@kroah.com> |
| Date: Thu, 4 Oct 2018 11:06:14 -0700 |
| Subject: tty: wipe buffer if not echoing data |
| |
| From: Greg Kroah-Hartman <greg@kroah.com> |
| |
| commit b97b3d9fb57860a60592859e332de7759fd54c2e upstream. |
| |
| If we are not echoing the data to userspace or the console is in icanon |
| mode, then perhaps it is a "secret" so we should wipe it once we are |
| done with it. |
| |
| This mirrors the logic that the audit code has. |
| |
| Reported-by: aszlig <aszlig@nix.build> |
| Tested-by: Milan Broz <gmazyland@gmail.com> |
| Tested-by: Daniel Zatovic <daniel.zatovic@gmail.com> |
| Tested-by: aszlig <aszlig@nix.build> |
| Cc: Willy Tarreau <w@1wt.eu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/n_tty.c | 19 +++++++++++++++++-- |
| 1 file changed, 17 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/tty/n_tty.c |
| +++ b/drivers/tty/n_tty.c |
| @@ -165,15 +165,29 @@ static inline int tty_put_user(struct tt |
| return put_user(x, ptr); |
| } |
| |
| +/* If we are not echoing the data, perhaps this is a secret so erase it */ |
| +static inline void zero_buffer(struct tty_struct *tty, u8 *buffer, int size) |
| +{ |
| + bool icanon = !!L_ICANON(tty); |
| + bool no_echo = !L_ECHO(tty); |
| + |
| + if (icanon && no_echo) |
| + memset(buffer, 0x00, size); |
| +} |
| + |
| static inline int tty_copy_to_user(struct tty_struct *tty, |
| void __user *to, |
| - const void *from, |
| + void *from, |
| unsigned long n) |
| { |
| struct n_tty_data *ldata = tty->disc_data; |
| + int retval; |
| |
| tty_audit_add_data(tty, from, n, ldata->icanon); |
| - return copy_to_user(to, from, n); |
| + retval = copy_to_user(to, from, n); |
| + if (!retval) |
| + zero_buffer(tty, from, n); |
| + return retval; |
| } |
| |
| /** |
| @@ -2005,6 +2019,7 @@ static int copy_from_read_buf(struct tty |
| is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty); |
| tty_audit_add_data(tty, read_buf_addr(ldata, tail), n, |
| ldata->icanon); |
| + zero_buffer(tty, read_buf_addr(ldata, tail), n); |
| smp_store_release(&ldata->read_tail, ldata->read_tail + n); |
| /* Turn single EOF into zero-length read */ |
| if (L_EXTPROC(tty) && ldata->icanon && is_eof && |