diff options
Diffstat (limited to 'net/x25')
-rw-r--r-- | net/x25/af_x25.c | 41 | ||||
-rw-r--r-- | net/x25/x25_dev.c | 6 | ||||
-rw-r--r-- | net/x25/x25_link.c | 6 | ||||
-rw-r--r-- | net/x25/x25_out.c | 13 |
4 files changed, 35 insertions, 31 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index ebaaa7242..9af3a0e3d 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -20,6 +20,9 @@ * 2000-22-03 Daniela Squassoni Allowed disabling/enabling of * facilities negotiation and increased * the throughput upper limit. + * 2000-27-08 Arnaldo C. Melo s/suser/capable/ + micro cleanups + * 2000-04-09 Henner Eisen Set sock->state in x25_accept(). + * Fixed x25_output() related skb leakage. */ #include <linux/config.h> @@ -402,10 +405,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, if (put_user(len, optlen)) return -EFAULT; - if (copy_to_user(optval, &val, len)) - return -EFAULT; - - return 0; + return copy_to_user(optval, &val, len) ? -EFAULT : 0; } static int x25_listen(struct socket *sock, int backlog) @@ -723,6 +723,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) kfree_skb(skb); sk->ack_backlog--; newsock->sk = newsk; + newsock->state = SS_CONNECTED; return 0; } @@ -973,7 +974,11 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct if (msg->msg_flags & MSG_OOB) { skb_queue_tail(&sk->protinfo.x25->interrupt_out_queue, skb); } else { - x25_output(sk, skb); + err = x25_output(sk, skb); + if(err){ + len = err; + kfree_skb(skb); + } } x25_kick(sk); @@ -1067,9 +1072,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); if (amount < 0) amount = 0; - if (put_user(amount, (unsigned int *)arg)) - return -EFAULT; - return 0; + return put_user(amount, (unsigned int *)arg); } case TIOCINQ: { @@ -1078,18 +1081,14 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) /* These two are safe on a single CPU system as only user tasks fiddle here */ if ((skb = skb_peek(&sk->receive_queue)) != NULL) amount = skb->len; - if (put_user(amount, (unsigned int *)arg)) - return -EFAULT; - return 0; + return put_user(amount, (unsigned int *)arg); } case SIOCGSTAMP: if (sk != NULL) { if (sk->stamp.tv_sec == 0) return -ENOENT; - if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0; } return -EINVAL; @@ -1114,15 +1113,13 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return x25_subscr_ioctl(cmd, (void *)arg); case SIOCX25SSUBSCRIP: - if (!suser()) return -EPERM; + if (!capable(CAP_NET_ADMIN)) return -EPERM; return x25_subscr_ioctl(cmd, (void *)arg); case SIOCX25GFACILITIES: { struct x25_facilities facilities; facilities = sk->protinfo.x25->facilities; - if (copy_to_user((void *)arg, &facilities, sizeof(facilities))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &facilities, sizeof(facilities)) ? -EFAULT : 0; } case SIOCX25SFACILITIES: { @@ -1148,9 +1145,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25GCALLUSERDATA: { struct x25_calluserdata calluserdata; calluserdata = sk->protinfo.x25->calluserdata; - if (copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)) ? -EFAULT : 0; } case SIOCX25SCALLUSERDATA: { @@ -1166,9 +1161,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25GCAUSEDIAG: { struct x25_causediag causediag; causediag = sk->protinfo.x25->causediag; - if (copy_to_user((void *)arg, &causediag, sizeof(causediag))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0; } default: diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index 1808361a6..d986022fb 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -14,6 +14,7 @@ * * History * X.25 001 Jonathan Naylor Started coding. + * 2000-09-04 Henner Eisen Prevent freeing a dangling skb. */ #include <linux/config.h> @@ -78,12 +79,13 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh) return x25_rx_call_request(skb, neigh, lci); /* - * Its not a Call Request, nor is it a control frame, throw it awa + * Its not a Call Request, nor is it a control frame. + * Let caller throw it away. */ /* x25_transmit_clear_request(neigh, lci, 0x0D); */ - kfree_skb(skb); + printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype); return 0; } diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 34d065b83..d6b878371 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -17,6 +17,7 @@ * X.25 002 Jonathan Naylor New timer architecture. * mar/20/00 Daniela Squassoni Disabling/enabling of facilities * negotiation. + * 2000-09-04 Henner Eisen dev_hold() / dev_put() for x25_neigh. */ #include <linux/config.h> @@ -292,6 +293,7 @@ void x25_link_device_up(struct net_device *dev) init_timer(&x25_neigh->t20timer); + dev_hold(dev); x25_neigh->dev = dev; x25_neigh->state = X25_LINK_STATE_0; x25_neigh->extended = 0; @@ -349,8 +351,10 @@ void x25_link_device_down(struct net_device *dev) neigh = x25_neigh; x25_neigh = x25_neigh->next; - if (neigh->dev == dev) + if (neigh->dev == dev){ x25_remove_neigh(neigh); + dev_put(dev); + } } } diff --git a/net/x25/x25_out.c b/net/x25/x25_out.c index 24fdf4d47..077f2c0b4 100644 --- a/net/x25/x25_out.c +++ b/net/x25/x25_out.c @@ -15,6 +15,7 @@ * History * X.25 001 Jonathan Naylor Started coding. * X.25 002 Jonathan Naylor New timer architecture. + * 2000-09-04 Henner Eisen Prevented x25_output() skb leakage. */ #include <linux/config.h> @@ -56,7 +57,7 @@ static int x25_pacsize_to_bytes(unsigned int pacsize) /* * This is where all X.25 information frames pass; */ -void x25_output(struct sock *sk, struct sk_buff *skb) +int x25_output(struct sock *sk, struct sk_buff *skb) { struct sk_buff *skbn; unsigned char header[X25_EXT_MIN_LEN]; @@ -73,9 +74,12 @@ void x25_output(struct sock *sk, struct sk_buff *skb) frontlen = skb_headroom(skb); while (skb->len > 0) { - if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, 0, 0, &err)) == NULL) - return; - + if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, 0, 0, &err)) == NULL){ + int unsent = skb->len - header_len; + SOCK_DEBUG(sk, "x25_output: framgent allocation failed, err=%d, %d bytes unsent\n", err, unsent); + return err; + } + skb_reserve(skbn, frontlen); len = (max_len > skb->len) ? skb->len : max_len; @@ -102,6 +106,7 @@ void x25_output(struct sock *sk, struct sk_buff *skb) } else { skb_queue_tail(&sk->write_queue, skb); } + return 0; } /* |