Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fce471e3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'iucv-fixes'



Julian Wiedmann says:

====================
net/iucv: fixes 2018-09-05

please apply three straight-forward fixes for iucv. One that prevents
leaking the skb on malformed inbound packets, one to fix the error
handling on transmit error, and one to get rid of a compile warning.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ee28bb56 b7f41565
Loading
Loading
Loading
Loading
+25 −13
Original line number Diff line number Diff line
@@ -351,20 +351,28 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
		memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));

	skb->dev = iucv->hs_dev;
	if (!skb->dev)
		return -ENODEV;
	if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev))
		return -ENETDOWN;
	if (!skb->dev) {
		err = -ENODEV;
		goto err_free;
	}
	if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev)) {
		err = -ENETDOWN;
		goto err_free;
	}
	if (skb->len > skb->dev->mtu) {
		if (sock->sk_type == SOCK_SEQPACKET)
			return -EMSGSIZE;
		else
		if (sock->sk_type == SOCK_SEQPACKET) {
			err = -EMSGSIZE;
			goto err_free;
		}
		skb_trim(skb, skb->dev->mtu);
	}
	skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
	nskb = skb_clone(skb, GFP_ATOMIC);
	if (!nskb)
		return -ENOMEM;
	if (!nskb) {
		err = -ENOMEM;
		goto err_free;
	}

	skb_queue_tail(&iucv->send_skb_q, nskb);
	err = dev_queue_xmit(skb);
	if (net_xmit_eval(err)) {
@@ -375,6 +383,10 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
		WARN_ON(atomic_read(&iucv->msg_recv) < 0);
	}
	return net_xmit_eval(err);

err_free:
	kfree_skb(skb);
	return err;
}

static struct sock *__iucv_get_sock_by_name(char *nm)
@@ -1167,7 +1179,7 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
		err = afiucv_hs_send(&txmsg, sk, skb, 0);
		if (err) {
			atomic_dec(&iucv->msg_sent);
			goto fail;
			goto out;
		}
	} else { /* Classic VM IUCV transport */
		skb_queue_tail(&iucv->send_skb_q, skb);
@@ -2155,8 +2167,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
	struct sock *sk;
	struct iucv_sock *iucv;
	struct af_iucv_trans_hdr *trans_hdr;
	int err = NET_RX_SUCCESS;
	char nullstring[8];
	int err = 0;

	if (skb->len < (ETH_HLEN + sizeof(struct af_iucv_trans_hdr))) {
		WARN_ONCE(1, "AF_IUCV too short skb, len=%d, min=%d",
@@ -2254,7 +2266,7 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
		err = afiucv_hs_callback_rx(sk, skb);
		break;
	default:
		;
		kfree_skb(skb);
	}

	return err;
+1 −1
Original line number Diff line number Diff line
@@ -1874,7 +1874,7 @@ static void iucv_pm_complete(struct device *dev)
 * Returns 0 if there are still iucv pathes defined
 *	   1 if there are no iucv pathes defined
 */
int iucv_path_table_empty(void)
static int iucv_path_table_empty(void)
{
	int i;