diff options
Diffstat (limited to 'drivers/net/ppp/ppp_synctty.c')
| -rw-r--r-- | drivers/net/ppp/ppp_synctty.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 18283b7b94bc..9c4932198931 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -43,7 +43,7 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/refcount.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uaccess.h> #define PPP_VERSION "2.4.2" @@ -93,8 +93,8 @@ static int ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, static void ppp_sync_process(struct tasklet_struct *t); static int ppp_sync_push(struct syncppp *ap); static void ppp_sync_flush_output(struct syncppp *ap); -static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - const char *flags, int count); +static void ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags, + int count); static const struct ppp_channel_ops sync_ops = { .start_xmit = ppp_sync_send, @@ -255,8 +255,7 @@ static void ppp_sync_hangup(struct tty_struct *tty) * Pppd reads and writes packets via /dev/ppp instead. */ static ssize_t -ppp_sync_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t count, +ppp_sync_read(struct tty_struct *tty, struct file *file, u8 *buf, size_t count, void **cookie, unsigned long offset) { return -EAGAIN; @@ -267,8 +266,8 @@ ppp_sync_read(struct tty_struct *tty, struct file *file, * from the ppp generic stuff. */ static ssize_t -ppp_sync_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) +ppp_sync_write(struct tty_struct *tty, struct file *file, const u8 *buf, + size_t count) { return -EAGAIN; } @@ -321,17 +320,10 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) return err; } -/* No kernel lock - fine */ -static __poll_t -ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) -{ - return 0; -} - /* May sleep, don't call from interrupt level or with interrupts disabled */ static void -ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, - const char *cflags, int count) +ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags, + size_t count) { struct syncppp *ap = sp_get(tty); unsigned long flags; @@ -371,7 +363,6 @@ static struct tty_ldisc_ops ppp_sync_ldisc = { .read = ppp_sync_read, .write = ppp_sync_write, .ioctl = ppp_synctty_ioctl, - .poll = ppp_sync_poll, .receive_buf = ppp_sync_receive, .write_wakeup = ppp_sync_wakeup, }; @@ -462,6 +453,10 @@ ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) case PPPIOCSMRU: if (get_user(val, (int __user *) argp)) break; + if (val > U16_MAX) { + err = -EINVAL; + break; + } if (val < PPP_MRU) val = PPP_MRU; ap->mru = val; @@ -511,6 +506,11 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb) unsigned char *data; int islcp; + /* Ensure we can safely access protocol field and LCP code */ + if (!pskb_may_pull(skb, 3)) { + kfree_skb(skb); + return NULL; + } data = skb->data; proto = get_unaligned_be16(data); @@ -663,8 +663,7 @@ ppp_sync_flush_output(struct syncppp *ap) * frame is considered to be in error and is tossed. */ static void -ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - const char *flags, int count) +ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags, int count) { struct sk_buff *skb; unsigned char *p; @@ -697,7 +696,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf, /* strip address/control field if present */ p = skb->data; - if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { /* chop off address/control */ if (skb->len < 3) goto err; @@ -730,5 +729,6 @@ ppp_sync_cleanup(void) module_init(ppp_sync_init); module_exit(ppp_sync_cleanup); +MODULE_DESCRIPTION("PPP synchronous TTY channel module"); MODULE_LICENSE("GPL"); MODULE_ALIAS_LDISC(N_SYNC_PPP); |
