net/rds: Fix info leak in rds6_inc_info_copy()

The rds6_inc_info_copy() function has a couple struct members which
are leaking stack information.  The ->tos field should hold actual
information and the ->flags field needs to be zeroed out.

Fixes: 3eb450367d08 ("rds: add type of service(tos) infrastructure")
Fixes: b7ff8b1036f0 ("rds: Extend RDS API for IPv6 support")
Reported-by: 黄ID蝴蝶 <butterflyhuangxx@gmail.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
static bool rds_recvmsg_zcookie(struct rds_sock *rs, struct msghdr *msg)
{
	struct rds_msg_zcopy_queue *q = &rs->rs_zcookie_queue;
	struct rds_msg_zcopy_info *info = NULL;
	struct rds_zcopy_cookies *done;
	unsigned long flags;

	if (!msg->msg_control)
		return false;

	if (!sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY) ||
	    msg->msg_controllen < CMSG_SPACE(sizeof(*done)))
		return false;

	spin_lock_irqsave(&q->lock, flags);
	if (!list_empty(&q->zcookie_head)) {
		info = list_entry(q->zcookie_head.next,
				  struct rds_msg_zcopy_info, rs_zcookie_next);
		list_del(&info->rs_zcookie_next);
	}
	spin_unlock_irqrestore(&q->lock, flags);
	if (!info)
		return false;
	done = &info->zcookies;
	if (put_cmsg(msg, SOL_RDS, RDS_CMSG_ZCOPY_COMPLETION, sizeof(*done),
		     done)) {
		spin_lock_irqsave(&q->lock, flags);
		list_add(&info->rs_zcookie_next, &q->zcookie_head);
		spin_unlock_irqrestore(&q->lock, flags);
		return false;
	}
	kfree(info);
	return true;
}

static bool rds_recvmsg_zcookie(struct rds_sock *rs, struct msghdr *msg)
{
	struct rds_msg_zcopy_queue *q = &rs->rs_zcookie_queue;
	struct rds_msg_zcopy_info *info = NULL;
	struct rds_zcopy_cookies *done;
	unsigned long flags;

	if (!msg->msg_control)
		return false;

	if (!sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY) ||
	    msg->msg_controllen < CMSG_SPACE(sizeof(*done)))
		return false;

	spin_lock_irqsave(&q->lock, flags);
	if (!list_empty(&q->zcookie_head)) {
		info = list_entry(q->zcookie_head.next,
				  struct rds_msg_zcopy_info, rs_zcookie_next);
		list_del(&info->rs_zcookie_next);
	}
	spin_unlock_irqrestore(&q->lock, flags);
	if (!info)
		return false;
	done = &info->zcookies;
	if (put_cmsg(msg, SOL_RDS, RDS_CMSG_ZCOPY_COMPLETION, sizeof(*done),
		     done)) {
		spin_lock_irqsave(&q->lock, flags);
		list_add(&info->rs_zcookie_next, &q->zcookie_head);
		spin_unlock_irqrestore(&q->lock, flags);
		return false;
	}
	kfree(info);
	return true;
}
