Broken RTM_SETLINK message

Marcel Holtmann marcel
Mon Aug 11 22:08:25 PDT 2014


Hi,

so I have been looking at netlink traces a bit and it seems that wpa_supplicant is sending a badly formatted RTM_SETLINK message.

    2d 00 00 00 13 00 01 00 01 00 00 00 00 00 00 00  -...............
    00 00 00 00 07 00 00 00 00 00 00 00 00 00 00 00  ................
    05 00 11 00 01 00 00 00 05 00 10 00 05           .............   

The problem is that it does not pad the message and this causes problems when parsing it. It does seem that the kernel accepts it, but I still think this not a valid message.

	if (linkmode != -1) {
		rta = aliasing_hide_typecast(
			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
			struct rtattr);
		rta->rta_type = IFLA_LINKMODE;
		rta->rta_len = RTA_LENGTH(sizeof(char));
		*((char *) RTA_DATA(rta)) = linkmode;
		req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
			RTA_LENGTH(sizeof(char));
	}
	if (operstate != -1) {
		rta = aliasing_hide_typecast(
			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
			struct rtattr);
		rta->rta_type = IFLA_OPERSTATE;
		rta->rta_len = RTA_LENGTH(sizeof(char));
		*((char *) RTA_DATA(rta)) = operstate;
		req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
			RTA_LENGTH(sizeof(char));
	}

The problem seems to be that req.hdr.nlmsg_len calculation is done using RTA_LENGTH. That one however only aligns struct rtattr. It does not align the payload. While this is correct for the rta->rta_len assignment, it think it is wrong for req.hdr.nlmsg_len. That should use RTA_SPACE instead.

		req.hdr.nlmsg_len += RTA_SPACE(sizeof(char));

The NLMSG_ALIGN(req.hdr.nlmsg_len) looks like double alignment to me and should not be needed since RTA_SPACE will actually take care of it. I think it is just there because of the wrongly used RTA_LENGTH.

Any thoughts on this?

Regards

Marcel




More information about the Hostap mailing list