6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) jirislaby@kernel.org
[ Upstream commit d97aa066678bd1e2951ee93db9690835dfe57ab6 ]
tty_write_room() returns an "unsigned int". So in case some insane driver (like my tty test driver) returns (legitimate) UINT_MAX from its tty_operations::write_room(), n_tty is confused on several places.
For example, in process_output_block(), the result of tty_write_room() is stored into (signed) "int". So this UINT_MAX suddenly becomes -1. And that is extended to ssize_t and returned from process_output_block(). This causes a write() to such a node to receive -EPERM (which is -1).
Fix that by using proper "unsigned int" and proper "== 0" test. And return 0 constant directly in that "if", so that it is immediately clear what is returned ("space" equals to 0 at that point).
Similarly for process_output() and __process_echoes().
Note this does not fix any in-tree driver as of now.
If you want "Fixes: something", it would be commit 03b3b1a2405c ("tty: make tty_operations::write_room return uint"). I intentionally do not mark this patch by a real tag below.
Signed-off-by: Jiri Slaby (SUSE) jirislaby@kernel.org Link: https://lore.kernel.org/r/20250317070046.24386-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_tty.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index e05341b85c599..788035f0c1ab2 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -491,7 +491,8 @@ static int do_output_char(u8 c, struct tty_struct *tty, int space) static int process_output(u8 c, struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; - int space, retval; + unsigned int space; + int retval;
mutex_lock(&ldata->output_lock);
@@ -527,16 +528,16 @@ static ssize_t process_output_block(struct tty_struct *tty, const u8 *buf, unsigned int nr) { struct n_tty_data *ldata = tty->disc_data; - int space; - int i; + unsigned int space; + int i; const u8 *cp;
mutex_lock(&ldata->output_lock);
space = tty_write_room(tty); - if (space <= 0) { + if (space == 0) { mutex_unlock(&ldata->output_lock); - return space; + return 0; } if (nr > space) nr = space; @@ -701,7 +702,7 @@ static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail, static size_t __process_echoes(struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; - int space, old_space; + unsigned int space, old_space; size_t tail; u8 c;