Commit message: [NETLINK]: Missing padding fields in dumped structures

Plug holes with padding fields and initialized them to zero.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2005-4881
CWE: CWE-200
Vulnerability description: The netlink subsystem in the Linux kernel 2.4.x before 2.4.37.6 and 2.6.x before 2.6.13-rc1 does not initialize certain padding fields in structures, which might allow local users to obtain sensitive information from kernel memory via unspecified vectors, related to the (1) tc_fill_qdisc, (2) tcf_fill_node, (3) neightbl_fill_info, (4) neightbl_fill_param_info, (5) neigh_fill_info, (6) rtnetlink_fill_ifinfo, (7) rtnetlink_fill_iwinfo, (8) vif_delete, (9) ipmr_destroy_unres, (10) ipmr_cache_alloc_unres, (11) ipmr_cache_resolve, (12) inet6_fill_ifinfo, (13) tca_get_fill, (14) tca_action_flush, (15) tcf_add_notify, (16) tc_dump_action, (17) cbq_dump_police, (18) __nlmsg_put, (19) __rta_fill, (20) __rta_reserve, (21) inet6_fill_prefix, (22) rsvp_dump, and (23) cbq_dump_ovl functions.

Project: linux-2.6

static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
{
	unsigned char	 *b = skb->tail;
	struct tc_cbq_ovl opt;

	opt.strategy = cl->ovl_strategy;
	opt.priority2 = cl->priority2+1;
	opt.penalty = (cl->penalty*1000)/HZ;
	RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
	return skb->len;

rtattr_failure:
	skb_trim(skb, b - skb->data);
	return -1;
}

Project: linux-2.6

static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
		     struct sk_buff *skb, struct tcmsg *t)
{
	struct rsvp_filter *f = (struct rsvp_filter*)fh;
	struct rsvp_session *s;
	unsigned char	 *b = skb->tail;
	struct rtattr *rta;
	struct tc_rsvp_pinfo pinfo;

	if (f == NULL)
		return skb->len;
	s = f->sess;

	t->tcm_handle = f->handle;


	rta = (struct rtattr*)b;
	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);

	RTA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst);
	pinfo.dpi = s->dpi;
	pinfo.spi = f->spi;
	pinfo.protocol = s->protocol;
	pinfo.tunnelid = s->tunnelid;
	pinfo.tunnelhdr = f->tunnelhdr;
	RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
	if (f->res.classid)
		RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
	if (((f->handle>>8)&0xFF) != 16)
		RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);

	if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
		goto rtattr_failure;

	rta->rta_len = skb->tail - b;

	if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
		goto rtattr_failure;
	return skb->len;

rtattr_failure:
	skb_trim(skb, b - skb->data);
	return -1;
}

Project: linux-2.6

static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
			struct prefix_info *pinfo, u32 pid, u32 seq, 
			int event, unsigned int flags)
{
	struct prefixmsg	*pmsg;
	struct nlmsghdr 	*nlh;
	unsigned char		*b = skb->tail;
	struct prefix_cacheinfo	ci;

	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
	pmsg = NLMSG_DATA(nlh);
	pmsg->prefix_family = AF_INET6;
	pmsg->prefix_ifindex = idev->dev->ifindex;
	pmsg->prefix_len = pinfo->prefix_len;
	pmsg->prefix_type = pinfo->type;
	
	pmsg->prefix_flags = 0;
	if (pinfo->onlink)
		pmsg->prefix_flags |= IF_PREFIX_ONLINK;
	if (pinfo->autoconf)
		pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;

	RTA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix);

	ci.preferred_time = ntohl(pinfo->prefered);
	ci.valid_time = ntohl(pinfo->valid);
	RTA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci);

	nlh->nlmsg_len = skb->tail - b;
	return skb->len;

nlmsg_failure:
rtattr_failure:
	skb_trim(skb, b - skb->data);
	return -1;
}