It appears that SLIP does not handle error codes from the TTY layer. This will result in a malfunction because the remaining length of data will be corrupted by the negative error code values from the TTY layer.
Therefore, add error code checks in sl_encaps() and sl_encaps_wakeup() to prevent the corruption of the sent data length. Note that SLIP is connectionless so on TTY error indicate that all data was sent. It seems SLIP does not return error codes to the network layer. Signed-off-by: Dean Jenkins <dean_jenk...@mentor.com> --- drivers/net/slip/slip.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index a34d6bf..bed819f 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -374,7 +374,7 @@ static void sl_bump(struct slip *sl) static void sl_encaps(struct slip *sl, unsigned char *icp, int len) { unsigned char *p; - int actual, count; + int actual, count, err; if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */ printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name); @@ -404,7 +404,16 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) * 14 Oct 1994 Dmitry Gorodchanin. */ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); - actual = sl->tty->ops->write(sl->tty, sl->xbuff, count); + err = sl->tty->ops->write(sl->tty, sl->xbuff, count); + + if (err < 0) { + /* error case, say all was sent as connectionless */ + actual = count; + } else { + /* good case, err contains the number sent */ + actual = err; + } + #ifdef SL_CHECK_TRANSMIT sl->dev->trans_start = jiffies; #endif @@ -422,7 +431,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) */ static void slip_write_wakeup(struct tty_struct *tty) { - int actual; + int actual, err; struct slip *sl = tty->disc_data; /* First make sure we're connected. */ @@ -438,7 +447,16 @@ static void slip_write_wakeup(struct tty_struct *tty) return; } - actual = tty->ops->write(tty, sl->xhead, sl->xleft); + err = tty->ops->write(tty, sl->xhead, sl->xleft); + + if (err < 0) { + /* error case, say all was sent as connectionless */ + actual = sl->xleft; + } else { + /* good case, err contains the number sent */ + actual = err; + } + sl->xleft -= actual; sl->xhead += actual; } -- 1.8.1.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/