[PATCH 5/8] netlink: add a basic socket diag parser of AF_INET messages

Dmitry V. Levin ldv at altlinux.org
Tue Jun 13 20:31:50 UTC 2017


On Tue, Jun 13, 2017 at 10:13:22PM +0800, JingPiao Chen wrote:
> * defs.h (inet_protocols): New xlat prototype.
> * linux/inet_diag.h (inet_diag_req): New structure.
> (INET_DIAG_*): New enum.
> * netlink_sock_diag.c: Include <arpa/inet.h>, <linux/inet_diag.h>
> and "xlat/inet_diag_extended_flags.h".
> (print_inet_diag_sockid, decode_inet_diag_req_compat)
> (decode_inet_diag_req_v2, decode_inet_diag_req)
> (decode_inet_diag_msg): New functions.
> (diag_decoders): Add AF_INET.
> * xlat/inet_diag_extended_flags.in: New file.
> 
> Co-authored-by: Fabien Siron <fabien.siron at epita.fr>
> ---
>  defs.h                           |   1 +
>  linux/inet_diag.h                |  36 +++++++++++-
>  netlink_sock_diag.c              | 122 +++++++++++++++++++++++++++++++++++++++
>  xlat/inet_diag_extended_flags.in |  16 +++++
>  4 files changed, 174 insertions(+), 1 deletion(-)
>  create mode 100644 xlat/inet_diag_extended_flags.in
> 
> diff --git a/defs.h b/defs.h
> index f7d25f0..0b32b24 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -293,6 +293,7 @@ extern const struct xlat clocknames[];
>  extern const struct xlat dirent_types[];
>  extern const struct xlat ethernet_protocols[];
>  extern const struct xlat evdev_abs[];
> +extern const struct xlat inet_protocols[];
>  extern const struct xlat msg_flags[];
>  extern const struct xlat netlink_protocols[];
>  extern const struct xlat open_access_modes[];
> diff --git a/linux/inet_diag.h b/linux/inet_diag.h
> index 69012af..7302c87 100644
> --- a/linux/inet_diag.h
> +++ b/linux/inet_diag.h
> @@ -14,7 +14,17 @@ struct inet_diag_sockid {
>  	uint32_t idiag_cookie[2];
>  };
>  
> -/* Request structure */
> +/* Request structures */
> +struct inet_diag_req {
> +	uint8_t idiag_family;
> +	uint8_t idiag_src_len;
> +	uint8_t idiag_dst_len;
> +	uint8_t idiag_ext;
> +	struct inet_diag_sockid id;
> +	uint32_t idiag_states;
> +	uint32_t idiag_dbs;
> +};
> +
>  struct inet_diag_req_v2 {
>  	uint8_t sdiag_family;
>  	uint8_t sdiag_protocol;
> @@ -40,4 +50,28 @@ struct inet_diag_msg {
>  	uint32_t idiag_inode;
>  };
>  
> +/* Extensions */
> +enum {
> +	INET_DIAG_NONE,
> +	INET_DIAG_MEMINFO,
> +	INET_DIAG_INFO,
> +	INET_DIAG_VEGASINFO,
> +	INET_DIAG_CONG,
> +	INET_DIAG_TOS,
> +	INET_DIAG_TCLASS,
> +	INET_DIAG_SKMEMINFO,
> +	INET_DIAG_SHUTDOWN,
> +	INET_DIAG_DCTCPINFO,
> +	INET_DIAG_PROTOCOL,  /* response attribute only */
> +	INET_DIAG_SKV6ONLY,
> +	INET_DIAG_LOCALS,
> +	INET_DIAG_PEERS,
> +	INET_DIAG_PAD,
> +	INET_DIAG_MARK,
> +	INET_DIAG_BBRINFO,
> +	__INET_DIAG_MAX,
> +};
> +
> +#define INET_DIAG_MAX (__INET_DIAG_MAX - 1)

I don't think we need __INET_DIAG_MAX or INET_DIAG_MAX.

> +
>  #endif /* !STRACE_LINUX_INET_DIAG_H */
> diff --git a/netlink_sock_diag.c b/netlink_sock_diag.c
> index 3f153a8..7467d1a 100644
> --- a/netlink_sock_diag.c
> +++ b/netlink_sock_diag.c
> @@ -30,11 +30,15 @@
>  #include "defs.h"
>  
>  #include <sys/socket.h>
> +#include <arpa/inet.h>
> +#include <linux/inet_diag.h>
>  #include <linux/netlink.h>
>  #include <linux/netlink_diag.h>
>  #include <linux/packet_diag.h>
>  #include <linux/unix_diag.h>
>  
> +#include "xlat/inet_diag_extended_flags.h"
> +
>  #include "xlat/tcp_states.h"
>  #include "xlat/tcp_state_flags.h"
>  
> @@ -210,9 +214,127 @@ decode_packet_diag_msg(struct tcb *const tcp,
>  	return true;
>  }
>  
> +static void
> +print_inet_diag_sockid(const struct inet_diag_sockid *id, const uint8_t family)
> +{
> +	tprintf("{idiag_sport=htons(%u), idiag_dport=htons(%u)",
> +		ntohs(id->idiag_sport), ntohs(id->idiag_dport));
> +	int text_size = family == AF_INET ?
> +		INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
> +	char buf[text_size];
> +
> +	inet_ntop(family, id->idiag_src, buf, text_size);
> +	tprintf(", inet_pton(%s, \"%s\", idiag_src)",
> +		family == AF_INET ? "AF_INET" : "AF_INET6", buf);
> +
> +	inet_ntop(family, id->idiag_dst, buf, text_size);
> +	tprintf(", inet_pton(%s, \"%s\", idiag_dst)",
> +		family == AF_INET ? "AF_INET" : "AF_INET6", buf);

As "family" is untrusted input, we cannot assume it's either AF_INET or
AF_INET6.  In fact, inet_ntop currently supports AF_INET and AF_INET6
only, so I wouldn't bother invoking inet_ntop with any other address
family argument.


-- 
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/26995d8b/attachment.bin>


More information about the Strace-devel mailing list