[PATCH 2/8] tests: check decoding of NETLINK_SOCK_DIAG AF_NETLINK messages

Dmitry V. Levin ldv at altlinux.org
Tue Jun 13 20:21:33 UTC 2017


On Tue, Jun 13, 2017 at 10:13:19PM +0800, JingPiao Chen wrote:
> * tests/netlink_sock_diag.c: Include <linux/netlink_diag.h>.
> (test_netlink_diag_req, test_netlink_diag_msg): New functions.
> (main): Use them.
> 
> Co-authored-by: Fabien Siron <fabien.siron at epita.fr>
> ---
>  tests/netlink_sock_diag.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 242 insertions(+)
> 
> diff --git a/tests/netlink_sock_diag.c b/tests/netlink_sock_diag.c
> index 63e7c3f..87a6d00 100644
> --- a/tests/netlink_sock_diag.c
> +++ b/tests/netlink_sock_diag.c
> @@ -35,6 +35,7 @@
>  #include <sys/socket.h>
>  #include <netinet/tcp.h>
>  #include <linux/netlink.h>
> +#include <linux/netlink_diag.h>
>  #include <linux/sock_diag.h>
>  #include <linux/unix_diag.h>
>  
> @@ -314,6 +315,245 @@ test_unix_diag_msg(const int fd)
>  	       sprintrc(rc));
>  }
>  
> +static void
> +test_netlink_diag_req(const int fd)
> +{
> +	struct nlmsghdr *nlh;
> +	struct netlink_diag_req *req;
> +	uint8_t *family;
> +	void *const nlh0 = tail_alloc(NLMSG_HDRLEN);
> +	long rc;
> +
> +	/* print family only */
> +	nlh = nlh0 - sizeof(*family);
> +	*nlh = (struct nlmsghdr) {
> +		.nlmsg_len = NLMSG_HDRLEN + sizeof(*family),
> +		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
> +		.nlmsg_flags = NLM_F_REQUEST,
> +	};
> +	family = NLMSG_DATA(nlh);
> +	*family = AF_NETLINK;
> +
> +	rc = sendto(fd, nlh, NLMSG_HDRLEN + sizeof(*family), MSG_DONTWAIT,
> +		    NULL, 0);
> +
> +	printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY"
> +	       ", flags=NLM_F_REQUEST, seq=0, pid=0}, {family=AF_NETLINK}}"
> +	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       sprintrc(rc));
> +
> +	/* print unknown family */
> +	*family = 0xff;
> +
> +	rc = sendto(fd, nlh, NLMSG_HDRLEN + sizeof(*family), MSG_DONTWAIT,
> +		    NULL, 0);
> +
> +	printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY"
> +	       ", flags=NLM_F_REQUEST, seq=0, pid=0}, {family=0xff /* AF_??? */}}"
> +	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       sprintrc(rc));
> +
> +	/* short read of family */
> +	memmove(nlh0, nlh, NLMSG_HDRLEN);
> +	nlh = nlh0;
> +
> +	rc = sendto(fd, nlh, NLMSG_HDRLEN + sizeof(*family), MSG_DONTWAIT,
> +		    NULL, 0);
> +
> +	printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY"
> +	       ", flags=NLM_F_REQUEST, seq=0, pid=0}, %p}"
> +	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       NLMSG_DATA(nlh),
> +	       NLMSG_HDRLEN + (unsigned int) sizeof(*family),
> +	       sprintrc(rc));
> +
> +	/* print family and string */
> +	nlh = nlh0 - (sizeof(*family) + 4);
> +	*nlh = (struct nlmsghdr) {
> +		.nlmsg_len = NLMSG_HDRLEN + sizeof(*family) + 4,
> +		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
> +		.nlmsg_flags = NLM_F_REQUEST,
> +	};
> +	family = NLMSG_DATA(nlh);
> +	*family = AF_NETLINK;
> +	memcpy(family + 1, "1234", 4);
> +
> +	rc = sendto(fd, nlh, NLMSG_HDRLEN + sizeof(*family) + 4, MSG_DONTWAIT,
> +		    NULL, 0);
> +
> +	printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY"
> +	       ", flags=NLM_F_REQUEST, seq=0, pid=0}"
> +	       ", {family=AF_NETLINK, \"1234\"}}"
> +	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, NLMSG_HDRLEN + (unsigned int) sizeof(*family) + 4,
> +	       NLMSG_HDRLEN + (unsigned int) sizeof(*family) + 4,
> +	       sprintrc(rc));
> +
> +	/* print netlink_diag_req */
> +	nlh = nlh0 - sizeof(*req);
> +	*nlh = (struct nlmsghdr) {
> +		.nlmsg_len = NLMSG_HDRLEN + sizeof(*req),
> +		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
> +		.nlmsg_flags = NLM_F_REQUEST,
> +	};
> +	req = NLMSG_DATA(nlh);
> +	*req = (struct netlink_diag_req) {
> +		.sdiag_family = AF_NETLINK,
> +		.sdiag_protocol = NDIAG_PROTO_ALL,
> +		.ndiag_show = NDIAG_SHOW_MEMINFO,
> +	};
> +
> +
> +	rc = sendto(fd, nlh, nlh->nlmsg_len, MSG_DONTWAIT, NULL, 0);
> +
> +	printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY"
> +	       ", flags=NLM_F_REQUEST, seq=0, pid=0}"
> +	       ", {sdiag_family=AF_NETLINK, sdiag_protocol=NDIAG_PROTO_ALL"
> +	       ", ndiag_ino=0, ndiag_show=NDIAG_SHOW_MEMINFO"
> +	       ", ndiag_cookie=[0, 0]}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, nlh->nlmsg_len, nlh->nlmsg_len, sprintrc(rc));

I think we should try to check decoding of all fields of struct
netlink_diag_req.  Let's initialize all numeric fields to some non-zero
magic numbers with most significant bit set.  This applies to other
diag_req/diag_msg structs, too.

> +
> +	/* short read of netlink_diag_req */
> +	nlh = nlh0 - sizeof(*family);
> +	memmove(nlh, nlh0 - sizeof(*req), NLMSG_HDRLEN + sizeof(*family));

I'd prefer if this short read was just 1 byte shorter than required.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170613/267d9169/attachment.bin>


More information about the Strace-devel mailing list