2016-07-06 15:49:22 +00:00
/*
* Copyright ( c ) 2016 Fabien Siron < fabien . siron @ epita . fr >
2016-07-08 16:01:49 +00:00
* Copyright ( c ) 2016 Dmitry V . Levin < ldv @ altlinux . org >
2018-04-05 01:40:00 +00:00
* Copyright ( c ) 2016 - 2018 The strace developers .
2016-07-06 15:49:22 +00:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
2017-06-22 00:24:22 +08:00
# include "netlink.h"
2017-07-19 17:17:37 +08:00
# include "nlattr.h"
2017-06-04 14:53:22 +00:00
# include <linux/audit.h>
2017-06-04 16:43:48 +00:00
# include <linux/rtnetlink.h>
2017-06-04 16:57:21 +00:00
# include <linux/xfrm.h>
2017-07-19 17:17:35 +08:00
# include "xlat/netlink_ack_flags.h"
2017-09-21 09:25:38 +08:00
# include "xlat/netlink_delete_flags.h"
2016-07-06 15:49:22 +00:00
# include "xlat/netlink_flags.h"
2017-06-08 09:02:22 +08:00
# include "xlat/netlink_get_flags.h"
# include "xlat/netlink_new_flags.h"
2017-06-04 17:03:44 +00:00
# include "xlat/netlink_protocols.h"
2016-07-06 15:49:22 +00:00
# include "xlat/netlink_types.h"
netlink: decode NETLINK_NETFILTER netlink message types
* netlink.c: Include "xlat/nf_acct_msg_types.h",
"xlat/nf_cthelper_msg_types.h", "xlat/nf_ctnetlink_exp_msg_types.h",
"xlat/nf_ctnetlink_msg_types.h", "xlat/nf_cttimeout_msg_types.h",
"xlat/nf_ipset_msg_types.h", "xlat/nf_nft_compat_msg_types.h",
"xlat/nf_nftables_msg_types.h", "xlat/nf_osf_msg_types.h",
"xlat/nf_queue_msg_types.h", and "xlat/nf_ulog_msg_types.h".
(nf_nlmsg_types): New array.
(decode_nlmsg_type_netfilter): Use it.
* NEWS: Mention this.
* xlat/nf_acct_msg_types.in: New file.
* xlat/nf_cthelper_msg_types.in: Likewise.
* xlat/nf_ctnetlink_exp_msg_types.in: Likewise.
* xlat/nf_ctnetlink_msg_types.in: Likewise.
* xlat/nf_cttimeout_msg_types.in: Likewise.
* xlat/nf_ipset_msg_types.in: Likewise.
* xlat/nf_nft_compat_msg_types.in: Likewise.
* xlat/nf_nftables_msg_types.in: Likewise.
* xlat/nf_osf_msg_types.in: Likewise.
* xlat/nf_queue_msg_types.in: Likewise.
* xlat/nf_ulog_msg_types.in: Likewise.
* tests/netlink_netfilter.c (test_nlmsg_type): Update expected output.
2017-09-09 17:42:41 +08:00
# include "xlat/nf_acct_msg_types.h"
# include "xlat/nf_cthelper_msg_types.h"
# include "xlat/nf_ctnetlink_exp_msg_types.h"
# include "xlat/nf_ctnetlink_msg_types.h"
# include "xlat/nf_cttimeout_msg_types.h"
# include "xlat/nf_ipset_msg_types.h"
# include "xlat/nf_nft_compat_msg_types.h"
# include "xlat/nf_nftables_msg_types.h"
# include "xlat/nf_osf_msg_types.h"
# include "xlat/nf_queue_msg_types.h"
# include "xlat/nf_ulog_msg_types.h"
2017-06-04 14:53:22 +00:00
# include "xlat/nl_audit_types.h"
2017-06-09 17:47:49 +08:00
# include "xlat/nl_crypto_types.h"
2017-06-04 18:14:50 +00:00
# include "xlat/nl_netfilter_subsys_ids.h"
2017-06-04 16:48:10 +00:00
# include "xlat/nl_selinux_types.h"
2017-06-03 23:19:49 +00:00
# include "xlat/nl_sock_diag_types.h"
2017-06-04 16:57:21 +00:00
# include "xlat/nl_xfrm_types.h"
2017-07-19 17:17:37 +08:00
# include "xlat/nlmsgerr_attrs.h"
2016-07-06 15:49:22 +00:00
2016-07-08 16:01:49 +00:00
/*
* Fetch a struct nlmsghdr from the given address .
*/
static bool
2016-12-20 23:16:25 +00:00
fetch_nlmsghdr ( struct tcb * const tcp , struct nlmsghdr * const nlmsghdr ,
2018-05-29 09:58:10 +00:00
const kernel_ulong_t addr , const kernel_ulong_t len ,
const bool in_array )
2016-07-06 15:49:22 +00:00
{
2016-07-08 16:01:49 +00:00
if ( len < sizeof ( struct nlmsghdr ) ) {
2017-07-07 09:44:09 +08:00
printstr_ex ( tcp , addr , len , QUOTE_FORCE_HEX ) ;
2016-07-08 16:01:49 +00:00
return false ;
2016-07-06 15:49:22 +00:00
}
2018-05-29 09:58:10 +00:00
if ( tfetch_obj ( tcp , addr , nlmsghdr ) )
return true ;
2016-07-08 16:01:49 +00:00
2018-05-29 09:58:10 +00:00
if ( in_array ) {
tprints ( " ... " ) ;
printaddr_comment ( addr ) ;
} else {
printaddr ( addr ) ;
}
return false ;
2016-07-08 16:01:49 +00:00
}
2017-06-03 23:19:49 +00:00
static int
get_fd_nl_family ( struct tcb * const tcp , const int fd )
{
const unsigned long inode = getfdinode ( tcp , fd ) ;
if ( ! inode )
2017-08-08 22:37:37 +08:00
return - 1 ;
2017-06-03 23:19:49 +00:00
netlink: avoid parsing data that has been just retrieved
get_fd_nl_family did a weird thing: it parsed netlink socket address in
order to get netlink proto, but the address itself is constructed based
on the netlink proto number in the first place. Avoid doing so by
stashing information about netlink protocol right after nul byte of the
sockaddress and providing it on request.
* socketutils.c (cache_entry): Add has_data field.
(cache_inode_details): Add data argument, store it in has_data field.
(get_sockdata_by_inode_cached): New function.
(inet_parse_response, unix_parse_response, packet_parse_response):
Pass false in data argument of cache_inode_details call.
(netlink_parse_response): Append ndiag_protocol value to details string,
pass true to cache_inode_details call.
(unix_get, inet_get, packet_get): Add data argument, return NULL
if called with data == true.
(netlink_get): Add data argument, call get_sockdata_by_inode_cached
instead of get_sockaddr_by_inode_cached if called with data == true.
(protocols): Add data arguments to the type definition of the get field.
(get_sockaddr_by_inode_uncached): Add data argument, pass
it to protocols->get.
(print_sockaddr_by_inode_uncached): Call get_sockaddr_by_inode_uncached
with data == false.
(get_sockaddr_by_inode): Call get_sockaddr_by_inode_uncached with
data == false;
(get_sockdata_by_inode): New function.
* defs.h (get_sockdata_by_inode): New declaration.
* netlink.c (get_fd_nl_family): Use get_sockdata_by_inode.
2018-08-31 05:48:19 +02:00
const char * const data = get_sockdata_by_inode ( tcp , fd , inode ) ;
if ( ! data )
2017-08-08 22:37:37 +08:00
return - 1 ;
2017-06-03 23:19:49 +00:00
netlink: avoid parsing data that has been just retrieved
get_fd_nl_family did a weird thing: it parsed netlink socket address in
order to get netlink proto, but the address itself is constructed based
on the netlink proto number in the first place. Avoid doing so by
stashing information about netlink protocol right after nul byte of the
sockaddress and providing it on request.
* socketutils.c (cache_entry): Add has_data field.
(cache_inode_details): Add data argument, store it in has_data field.
(get_sockdata_by_inode_cached): New function.
(inet_parse_response, unix_parse_response, packet_parse_response):
Pass false in data argument of cache_inode_details call.
(netlink_parse_response): Append ndiag_protocol value to details string,
pass true to cache_inode_details call.
(unix_get, inet_get, packet_get): Add data argument, return NULL
if called with data == true.
(netlink_get): Add data argument, call get_sockdata_by_inode_cached
instead of get_sockaddr_by_inode_cached if called with data == true.
(protocols): Add data arguments to the type definition of the get field.
(get_sockaddr_by_inode_uncached): Add data argument, pass
it to protocols->get.
(print_sockaddr_by_inode_uncached): Call get_sockaddr_by_inode_uncached
with data == false.
(get_sockaddr_by_inode): Call get_sockaddr_by_inode_uncached with
data == false;
(get_sockdata_by_inode): New function.
* defs.h (get_sockdata_by_inode): New declaration.
* netlink.c (get_fd_nl_family): Use get_sockdata_by_inode.
2018-08-31 05:48:19 +02:00
return data [ 0 ] ;
2017-06-03 23:19:49 +00:00
}
2017-06-14 23:32:45 +00:00
static void
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decode_nlmsg_type_default ( struct tcb * tcp , const struct xlat * const xlat ,
2017-06-14 23:32:45 +00:00
const uint16_t type ,
const char * const dflt )
{
printxval ( xlat , type , dflt ) ;
}
2017-06-13 17:26:44 +09:00
static void
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decode_nlmsg_type_generic ( struct tcb * tcp , const struct xlat * const xlat ,
2017-06-13 17:26:44 +09:00
const uint16_t type ,
const char * const dflt )
{
2018-09-24 05:06:41 +02:00
/* As genl family numbers are allocated dynamically */
2018-09-24 20:16:32 +02:00
print_xlat_ex ( type , genl_get_family_name ( tcp , type ) ,
XLAT_STYLE_VERBOSE ) ;
2017-06-13 17:26:44 +09:00
}
netlink: decode NETLINK_NETFILTER netlink message types
* netlink.c: Include "xlat/nf_acct_msg_types.h",
"xlat/nf_cthelper_msg_types.h", "xlat/nf_ctnetlink_exp_msg_types.h",
"xlat/nf_ctnetlink_msg_types.h", "xlat/nf_cttimeout_msg_types.h",
"xlat/nf_ipset_msg_types.h", "xlat/nf_nft_compat_msg_types.h",
"xlat/nf_nftables_msg_types.h", "xlat/nf_osf_msg_types.h",
"xlat/nf_queue_msg_types.h", and "xlat/nf_ulog_msg_types.h".
(nf_nlmsg_types): New array.
(decode_nlmsg_type_netfilter): Use it.
* NEWS: Mention this.
* xlat/nf_acct_msg_types.in: New file.
* xlat/nf_cthelper_msg_types.in: Likewise.
* xlat/nf_ctnetlink_exp_msg_types.in: Likewise.
* xlat/nf_ctnetlink_msg_types.in: Likewise.
* xlat/nf_cttimeout_msg_types.in: Likewise.
* xlat/nf_ipset_msg_types.in: Likewise.
* xlat/nf_nft_compat_msg_types.in: Likewise.
* xlat/nf_nftables_msg_types.in: Likewise.
* xlat/nf_osf_msg_types.in: Likewise.
* xlat/nf_queue_msg_types.in: Likewise.
* xlat/nf_ulog_msg_types.in: Likewise.
* tests/netlink_netfilter.c (test_nlmsg_type): Update expected output.
2017-09-09 17:42:41 +08:00
static const struct {
const struct xlat * const xlat ;
const char * const dflt ;
} nf_nlmsg_types [ ] = {
[ NFNL_SUBSYS_CTNETLINK ] = {
nf_ctnetlink_msg_types ,
" IPCTNL_MSG_CT_??? "
} ,
[ NFNL_SUBSYS_CTNETLINK_EXP ] = {
nf_ctnetlink_exp_msg_types ,
" IPCTNL_MSG_EXP_??? "
} ,
[ NFNL_SUBSYS_QUEUE ] = { nf_queue_msg_types , " NFQNL_MSG_??? " } ,
[ NFNL_SUBSYS_ULOG ] = { nf_ulog_msg_types , " NFULNL_MSG_??? " } ,
[ NFNL_SUBSYS_OSF ] = { nf_osf_msg_types , " OSF_MSG_??? " } ,
[ NFNL_SUBSYS_IPSET ] = { nf_ipset_msg_types , " IPSET_CMD_??? " } ,
[ NFNL_SUBSYS_ACCT ] = { nf_acct_msg_types , " NFNL_MSG_ACCT_??? " } ,
[ NFNL_SUBSYS_CTNETLINK_TIMEOUT ] = {
nf_cttimeout_msg_types ,
" IPCTNL_MSG_TIMEOUT_??? "
} ,
[ NFNL_SUBSYS_CTHELPER ] = {
nf_cthelper_msg_types ,
" NFNL_MSG_CTHELPER_??? "
} ,
[ NFNL_SUBSYS_NFTABLES ] = { nf_nftables_msg_types , " NFT_MSG_??? " } ,
[ NFNL_SUBSYS_NFT_COMPAT ] = {
nf_nft_compat_msg_types ,
" NFNL_MSG_COMPAT_??? "
}
} ;
2017-06-14 23:32:45 +00:00
static void
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decode_nlmsg_type_netfilter ( struct tcb * tcp , const struct xlat * const xlat ,
2017-06-14 23:32:45 +00:00
const uint16_t type ,
const char * const dflt )
{
/* Reserved control nfnetlink messages first. */
const char * const text = xlookup ( nl_netfilter_msg_types , type ) ;
if ( text ) {
2018-04-04 14:39:42 +02:00
print_xlat_ex ( type , text , XLAT_STYLE_DEFAULT ) ;
2017-06-14 23:32:45 +00:00
return ;
}
/*
* Other netfilter message types are split
* in two pieces : 8 bits subsystem and 8 bits type .
*/
const uint8_t subsys_id = ( uint8_t ) ( type > > 8 ) ;
const uint8_t msg_type = ( uint8_t ) type ;
printxval ( xlat , subsys_id , dflt ) ;
netlink: decode NETLINK_NETFILTER netlink message types
* netlink.c: Include "xlat/nf_acct_msg_types.h",
"xlat/nf_cthelper_msg_types.h", "xlat/nf_ctnetlink_exp_msg_types.h",
"xlat/nf_ctnetlink_msg_types.h", "xlat/nf_cttimeout_msg_types.h",
"xlat/nf_ipset_msg_types.h", "xlat/nf_nft_compat_msg_types.h",
"xlat/nf_nftables_msg_types.h", "xlat/nf_osf_msg_types.h",
"xlat/nf_queue_msg_types.h", and "xlat/nf_ulog_msg_types.h".
(nf_nlmsg_types): New array.
(decode_nlmsg_type_netfilter): Use it.
* NEWS: Mention this.
* xlat/nf_acct_msg_types.in: New file.
* xlat/nf_cthelper_msg_types.in: Likewise.
* xlat/nf_ctnetlink_exp_msg_types.in: Likewise.
* xlat/nf_ctnetlink_msg_types.in: Likewise.
* xlat/nf_cttimeout_msg_types.in: Likewise.
* xlat/nf_ipset_msg_types.in: Likewise.
* xlat/nf_nft_compat_msg_types.in: Likewise.
* xlat/nf_nftables_msg_types.in: Likewise.
* xlat/nf_osf_msg_types.in: Likewise.
* xlat/nf_queue_msg_types.in: Likewise.
* xlat/nf_ulog_msg_types.in: Likewise.
* tests/netlink_netfilter.c (test_nlmsg_type): Update expected output.
2017-09-09 17:42:41 +08:00
tprints ( " <<8| " ) ;
if ( subsys_id < ARRAY_SIZE ( nf_nlmsg_types ) )
printxval ( nf_nlmsg_types [ subsys_id ] . xlat ,
msg_type , nf_nlmsg_types [ subsys_id ] . dflt ) ;
else
tprintf ( " %#x " , msg_type ) ;
2017-06-14 23:32:45 +00:00
}
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
typedef void ( * nlmsg_types_decoder_t ) ( struct tcb * , const struct xlat * ,
2017-06-14 23:32:45 +00:00
uint16_t type ,
const char * dflt ) ;
2017-06-03 23:19:49 +00:00
static const struct {
2017-06-14 23:32:45 +00:00
const nlmsg_types_decoder_t decoder ;
2017-06-03 23:19:49 +00:00
const struct xlat * const xlat ;
const char * const dflt ;
} nlmsg_types [ ] = {
2017-06-14 23:32:45 +00:00
[ NETLINK_AUDIT ] = { NULL , nl_audit_types , " AUDIT_??? " } ,
2017-06-09 17:47:49 +08:00
[ NETLINK_CRYPTO ] = { NULL , nl_crypto_types , " CRYPTO_MSG_??? " } ,
2017-06-13 17:26:44 +09:00
[ NETLINK_GENERIC ] = {
decode_nlmsg_type_generic ,
NULL ,
" GENERIC_FAMILY_??? "
} ,
2017-06-14 23:32:45 +00:00
[ NETLINK_NETFILTER ] = {
decode_nlmsg_type_netfilter ,
nl_netfilter_subsys_ids ,
" NFNL_SUBSYS_??? "
} ,
[ NETLINK_ROUTE ] = { NULL , nl_route_types , " RTM_??? " } ,
[ NETLINK_SELINUX ] = { NULL , nl_selinux_types , " SELNL_MSG_??? " } ,
[ NETLINK_SOCK_DIAG ] = { NULL , nl_sock_diag_types , " SOCK_DIAG_??? " } ,
[ NETLINK_XFRM ] = { NULL , nl_xfrm_types , " XFRM_MSG_??? " }
2017-06-03 23:19:49 +00:00
} ;
/*
* As all valid netlink families are positive integers , use unsigned int
2017-08-08 22:37:37 +08:00
* for family here to filter out - 1.
2017-06-03 23:19:49 +00:00
*/
static void
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decode_nlmsg_type ( struct tcb * tcp , const uint16_t type ,
const unsigned int family )
2017-06-03 23:19:49 +00:00
{
2017-06-14 23:32:45 +00:00
nlmsg_types_decoder_t decoder = decode_nlmsg_type_default ;
const struct xlat * xlat = netlink_types ;
const char * dflt = " NLMSG_??? " ;
2017-08-08 22:37:37 +08:00
/*
* type < NLMSG_MIN_TYPE are reserved control messages
* that need no family - specific decoding .
*/
if ( type > = NLMSG_MIN_TYPE & & family < ARRAY_SIZE ( nlmsg_types ) ) {
2017-06-14 23:32:45 +00:00
if ( nlmsg_types [ family ] . decoder )
decoder = nlmsg_types [ family ] . decoder ;
if ( nlmsg_types [ family ] . xlat )
xlat = nlmsg_types [ family ] . xlat ;
if ( nlmsg_types [ family ] . dflt )
dflt = nlmsg_types [ family ] . dflt ;
2017-06-03 23:19:49 +00:00
}
2017-06-14 23:32:45 +00:00
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decoder ( tcp , xlat , type , dflt ) ;
2017-06-03 23:19:49 +00:00
}
2017-09-09 23:43:20 +08:00
static const struct xlat *
decode_nlmsg_flags_crypto ( const uint16_t type )
{
switch ( type ) {
case CRYPTO_MSG_NEWALG :
return netlink_new_flags ;
2017-09-21 09:25:38 +08:00
case CRYPTO_MSG_DELALG :
case CRYPTO_MSG_DELRNG :
return netlink_delete_flags ;
2017-09-09 23:43:20 +08:00
case CRYPTO_MSG_GETALG :
return netlink_get_flags ;
}
return NULL ;
}
2017-09-18 20:13:14 +08:00
static const struct xlat *
decode_nlmsg_flags_netfilter ( const uint16_t type )
{
const uint8_t subsys_id = ( uint8_t ) ( type > > 8 ) ;
const uint8_t msg_type = ( uint8_t ) type ;
switch ( subsys_id ) {
case NFNL_SUBSYS_CTNETLINK :
switch ( msg_type ) {
case IPCTNL_MSG_CT_NEW :
return netlink_new_flags ;
case IPCTNL_MSG_CT_GET :
case IPCTNL_MSG_CT_GET_CTRZERO :
case IPCTNL_MSG_CT_GET_STATS_CPU :
case IPCTNL_MSG_CT_GET_STATS :
case IPCTNL_MSG_CT_GET_DYING :
case IPCTNL_MSG_CT_GET_UNCONFIRMED :
return netlink_get_flags ;
case IPCTNL_MSG_CT_DELETE :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_CTNETLINK_EXP :
switch ( msg_type ) {
case IPCTNL_MSG_EXP_NEW :
return netlink_new_flags ;
case IPCTNL_MSG_EXP_GET :
case IPCTNL_MSG_EXP_GET_STATS_CPU :
return netlink_get_flags ;
case IPCTNL_MSG_EXP_DELETE :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_ACCT :
switch ( msg_type ) {
case NFNL_MSG_ACCT_NEW :
return netlink_new_flags ;
case NFNL_MSG_ACCT_GET :
case NFNL_MSG_ACCT_GET_CTRZERO :
return netlink_get_flags ;
case NFNL_MSG_ACCT_DEL :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_CTNETLINK_TIMEOUT :
switch ( msg_type ) {
case IPCTNL_MSG_TIMEOUT_NEW :
return netlink_new_flags ;
case IPCTNL_MSG_TIMEOUT_GET :
return netlink_get_flags ;
case IPCTNL_MSG_TIMEOUT_DELETE :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_CTHELPER :
switch ( msg_type ) {
case NFNL_MSG_CTHELPER_NEW :
return netlink_new_flags ;
case NFNL_MSG_CTHELPER_GET :
return netlink_get_flags ;
case NFNL_MSG_CTHELPER_DEL :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_NFTABLES :
switch ( msg_type ) {
case NFT_MSG_NEWTABLE :
case NFT_MSG_NEWCHAIN :
case NFT_MSG_NEWRULE :
case NFT_MSG_NEWSET :
case NFT_MSG_NEWSETELEM :
case NFT_MSG_NEWGEN :
case NFT_MSG_NEWOBJ :
return netlink_new_flags ;
case NFT_MSG_GETTABLE :
case NFT_MSG_GETCHAIN :
case NFT_MSG_GETRULE :
case NFT_MSG_GETSET :
case NFT_MSG_GETSETELEM :
case NFT_MSG_GETGEN :
case NFT_MSG_GETOBJ :
case NFT_MSG_GETOBJ_RESET :
return netlink_get_flags ;
case NFT_MSG_DELTABLE :
case NFT_MSG_DELCHAIN :
case NFT_MSG_DELRULE :
case NFT_MSG_DELSET :
case NFT_MSG_DELSETELEM :
case NFT_MSG_DELOBJ :
return netlink_delete_flags ;
}
break ;
case NFNL_SUBSYS_NFT_COMPAT :
switch ( msg_type ) {
case NFNL_MSG_COMPAT_GET :
return netlink_get_flags ;
}
break ;
}
return NULL ;
}
2017-09-09 23:43:20 +08:00
static const struct xlat *
decode_nlmsg_flags_route ( const uint16_t type )
{
2017-09-21 09:25:38 +08:00
/* RTM_DELACTION uses NLM_F_ROOT flags */
2017-09-09 23:43:20 +08:00
if ( type = = RTM_DELACTION )
return netlink_get_flags ;
switch ( type & 3 ) {
case 0 :
return netlink_new_flags ;
2017-09-21 09:25:38 +08:00
case 1 :
return netlink_delete_flags ;
2017-09-09 23:43:20 +08:00
case 2 :
return netlink_get_flags ;
}
return NULL ;
}
static const struct xlat *
decode_nlmsg_flags_sock_diag ( const uint16_t type )
{
return netlink_get_flags ;
}
static const struct xlat *
decode_nlmsg_flags_xfrm ( const uint16_t type )
{
switch ( type ) {
case XFRM_MSG_NEWSA :
case XFRM_MSG_NEWPOLICY :
case XFRM_MSG_NEWAE :
case XFRM_MSG_NEWSADINFO :
case XFRM_MSG_NEWSPDINFO :
return netlink_new_flags ;
2017-09-21 09:25:38 +08:00
case XFRM_MSG_DELSA :
case XFRM_MSG_DELPOLICY :
return netlink_delete_flags ;
2017-09-09 23:43:20 +08:00
case XFRM_MSG_GETSA :
case XFRM_MSG_GETPOLICY :
case XFRM_MSG_GETAE :
case XFRM_MSG_GETSADINFO :
case XFRM_MSG_GETSPDINFO :
return netlink_get_flags ;
}
return NULL ;
}
typedef const struct xlat * ( * nlmsg_flags_decoder_t ) ( const uint16_t type ) ;
static const nlmsg_flags_decoder_t nlmsg_flags [ ] = {
[ NETLINK_CRYPTO ] = decode_nlmsg_flags_crypto ,
2017-09-18 20:13:14 +08:00
[ NETLINK_NETFILTER ] = decode_nlmsg_flags_netfilter ,
2017-09-09 23:43:20 +08:00
[ NETLINK_ROUTE ] = decode_nlmsg_flags_route ,
[ NETLINK_SOCK_DIAG ] = decode_nlmsg_flags_sock_diag ,
[ NETLINK_XFRM ] = decode_nlmsg_flags_xfrm
} ;
/*
* As all valid netlink families are positive integers , use unsigned int
* for family here to filter out - 1.
*/
2017-06-08 09:02:22 +08:00
static void
2017-09-09 23:43:20 +08:00
decode_nlmsg_flags ( const uint16_t flags , const uint16_t type ,
const unsigned int family )
2017-06-08 09:02:22 +08:00
{
2017-06-08 22:15:58 +00:00
const struct xlat * table = NULL ;
2017-06-08 09:02:22 +08:00
2017-07-19 17:17:35 +08:00
if ( type < NLMSG_MIN_TYPE ) {
if ( type = = NLMSG_ERROR )
table = netlink_ack_flags ;
2017-09-09 23:43:20 +08:00
} else if ( family < ARRAY_SIZE ( nlmsg_flags ) & & nlmsg_flags [ family ] )
table = nlmsg_flags [ family ] ( type ) ;
2017-06-08 09:02:22 +08:00
2018-08-26 01:11:37 +02:00
printflags_ex ( flags , " NLM_F_??? " , XLAT_STYLE_DEFAULT ,
Introduce xlat verbosity styles
* defs.h (printxvals_ex): Rename from printxvals, add style argument.
(enum xlat_style): New enumeration.
(printxvals): New macro, a wrapper for printxvals_ex.
(printxval_searchn_ex): Rename from printxval_searchn, add style
argument.
(printxval_searchn): New macro, a wrapper for printxval_searchn_ex.
(printxval_search_ex): New macro, a wrapper for printxval_searchn_ex.
(sprintxval_ex): Rename from sprintxval, add style argument.
(sprintxval): New macro, a wrapper for sprintxval_ex.
(printflags_ex): Add style argument.
(sprintflags_ex): Rename from sprintflags, add style argument.
(sprintflags): New macro, a wrapper for sprintflags_ex.
(printflags64): Pass XLAT_STYLE_ABBREV as a style in printflags_ex call.
* netlink.c (decode_nlmsg_flags): Pass XLAT_STYLE_ABBREV as a style in
printflags_ex call.
* xlat.c (printxvals_ex): Rename from printxvals, add style argument,
handle it.
(sprintxval_ex): Rename from sprintxval, add style argument, handle it.
(printxval_searchn_ex): Rename from printxval_searchn, add style
argument, handle it.
(sprintflags_ex): Rename from sprintflags, add style argument,
handle it.
(printflags_ex): Add style argument, handle it.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
References: https://github.com/strace/strace/issues/27
2018-03-10 04:48:33 +01:00
netlink_flags , table , NULL ) ;
2017-06-08 09:02:22 +08:00
}
2017-08-08 22:37:37 +08:00
static void
2016-07-11 12:54:59 +00:00
print_nlmsghdr ( struct tcb * tcp ,
const int fd ,
2017-08-08 22:37:37 +08:00
const int family ,
2016-07-11 12:54:59 +00:00
const struct nlmsghdr * const nlmsghdr )
2016-07-08 16:01:49 +00:00
{
/* print the whole structure regardless of its nlmsg_len */
tprintf ( " {len=%u, type= " , nlmsghdr - > nlmsg_len ) ;
2016-07-06 15:49:22 +00:00
Add tcp arguments to netlink calls
Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to
pass tcp there.
* defs.h (genl_families_xlat): Add tcp argument.
* netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic,
decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise.
(decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call.
(print_nlmsghdr): Pass tcp to the decode_nlmsg_type call.
* socketutils.c (send_query, receive_responses): Add tcp argument.
(inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument.
Pass tcp to the send_query call.
(unix_get): Add tcp argument. Pass tcp to the unix_send_query and
receive_responses calls.
(inet_get): Add tcp argument. Pass tcp to the inet_send_query and
receive_responses calls.
(tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass
tcp to the inet_get call.
(netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and
receive_responses calls.
(protocols): Add tcp argument to the get field.
(get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the protocols[].get calls.
(print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to
the get_sockaddr_by_inode_uncached call.
(get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached
call.
(print_sockaddr_by_inode): Pass tcp to the
print_sockaddr_by_inode_uncached call.
(genl_send_dump_families): Add tcp argument. Pass tcp to the send_query
call.
(genl_families_xlat): Add tcp argument. Pass tcp to the
genl_send_dump_families and receive_responses calls.
2017-12-26 00:14:14 +01:00
decode_nlmsg_type ( tcp , nlmsghdr - > nlmsg_type , family ) ;
2016-07-06 15:49:22 +00:00
tprints ( " , flags= " ) ;
2017-06-08 09:02:22 +08:00
decode_nlmsg_flags ( nlmsghdr - > nlmsg_flags ,
2017-08-08 22:37:37 +08:00
nlmsghdr - > nlmsg_type , family ) ;
2016-07-08 16:01:49 +00:00
tprintf ( " , seq=%u, pid=%u} " , nlmsghdr - > nlmsg_seq ,
nlmsghdr - > nlmsg_pid ) ;
}
2016-07-06 15:49:22 +00:00
2017-07-19 17:17:37 +08:00
static bool
2017-08-07 20:44:55 +08:00
print_cookie ( struct tcb * const tcp , void * const elem_buf ,
const size_t elem_size , void * const opaque_data )
2017-07-19 17:17:37 +08:00
{
tprintf ( " % " PRIu8 , * ( uint8_t * ) elem_buf ) ;
return true ;
}
static bool
decode_nlmsgerr_attr_cookie ( struct tcb * const tcp ,
const kernel_ulong_t addr ,
Adjust prototypes of netlink parsing functions
Change the type of "len" argument that is based
on struct nlmsghdr.nlmsg_len from kernel_ulong_t to unsigned int.
* defs.h (netlink_decoder_t, DECL_NETLINK): Change "len" argument type
from kernel_ulong_t to unsigned int.
* netlink.c (decode_nlmsgerr_attr_cookie, decode_nlmsgerr,
decode_payload): Likewise.
* netlink_selinux.c (decode_netlink_selinux): Likewise.
* netlink_sock_diag.c (decode_family, decode_unix_diag_req,
decode_meminfo, decode_unix_diag_vfs, decode_unix_diag_inode,
decode_unix_diag_rqlen, decode_unix_diag_msg, decode_netlink_diag_req,
print_group, decode_netlink_diag_ring, decode_netlink_diag_flags,
decode_netlink_diag_msg, decode_packet_diag_req,
decode_packet_diag_info, decode_packet_diag_mclist,
decode_packet_diag_ring, decode_packet_diag_filter,
decode_packet_diag_msg, decode_inet_addr, decode_inet_diag_hostcond,
decode_inet_diag_markcond, decode_bytecode_data, decode_inet_diag_bc_op,
decode_inet_diag_req_compat, decode_inet_diag_req_v2,
decode_inet_diag_req, decode_inet_diag_meminfo, decode_tcpvegas_info,
decode_tcp_dctcp_info, decode_tcp_bbr_info, decode_inet_diag_msg,
decode_smc_diag_req, decode_smc_diag_conninfo, decode_smc_diag_lgrinfo,
decode_smc_diag_msg, netlink_diag_decoder_t, decode_netlink_sock_diag):
Likewise.
* nlattr.c (fetch_nlattr, decode_nlattr_with_data, decode_nlattr,
decode_nla_str, decode_nla_strn, DECODE_NLA_INTEGER): Likewise.
* nlattr.h (nla_decoder_t, DECL_NLA, decode_nlattr): Likewise.
2017-07-19 10:07:34 +00:00
const unsigned int len ,
2017-07-19 17:17:37 +08:00
const void * const opaque_data )
{
uint8_t cookie ;
const size_t nmemb = len / sizeof ( cookie ) ;
print_array ( tcp , addr , nmemb , & cookie , sizeof ( cookie ) ,
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 01:15:19 +00:00
tfetch_mem , print_cookie , 0 ) ;
2017-07-19 17:17:37 +08:00
return true ;
}
static const nla_decoder_t nlmsgerr_nla_decoders [ ] = {
[ NLMSGERR_ATTR_MSG ] = decode_nla_str ,
[ NLMSGERR_ATTR_OFFS ] = decode_nla_u32 ,
[ NLMSGERR_ATTR_COOKIE ] = decode_nlmsgerr_attr_cookie
} ;
2017-04-17 04:37:41 +00:00
static void
decode_nlmsghdr_with_payload ( struct tcb * const tcp ,
2016-07-11 12:54:59 +00:00
const int fd ,
2017-08-08 22:37:37 +08:00
const int family ,
2017-04-17 04:37:41 +00:00
const struct nlmsghdr * const nlmsghdr ,
const kernel_ulong_t addr ,
const kernel_ulong_t len ) ;
static void
decode_nlmsgerr ( struct tcb * const tcp ,
2016-07-11 12:54:59 +00:00
const int fd ,
2017-06-03 22:56:32 +00:00
const int family ,
2016-07-11 12:54:59 +00:00
kernel_ulong_t addr ,
Adjust prototypes of netlink parsing functions
Change the type of "len" argument that is based
on struct nlmsghdr.nlmsg_len from kernel_ulong_t to unsigned int.
* defs.h (netlink_decoder_t, DECL_NETLINK): Change "len" argument type
from kernel_ulong_t to unsigned int.
* netlink.c (decode_nlmsgerr_attr_cookie, decode_nlmsgerr,
decode_payload): Likewise.
* netlink_selinux.c (decode_netlink_selinux): Likewise.
* netlink_sock_diag.c (decode_family, decode_unix_diag_req,
decode_meminfo, decode_unix_diag_vfs, decode_unix_diag_inode,
decode_unix_diag_rqlen, decode_unix_diag_msg, decode_netlink_diag_req,
print_group, decode_netlink_diag_ring, decode_netlink_diag_flags,
decode_netlink_diag_msg, decode_packet_diag_req,
decode_packet_diag_info, decode_packet_diag_mclist,
decode_packet_diag_ring, decode_packet_diag_filter,
decode_packet_diag_msg, decode_inet_addr, decode_inet_diag_hostcond,
decode_inet_diag_markcond, decode_bytecode_data, decode_inet_diag_bc_op,
decode_inet_diag_req_compat, decode_inet_diag_req_v2,
decode_inet_diag_req, decode_inet_diag_meminfo, decode_tcpvegas_info,
decode_tcp_dctcp_info, decode_tcp_bbr_info, decode_inet_diag_msg,
decode_smc_diag_req, decode_smc_diag_conninfo, decode_smc_diag_lgrinfo,
decode_smc_diag_msg, netlink_diag_decoder_t, decode_netlink_sock_diag):
Likewise.
* nlattr.c (fetch_nlattr, decode_nlattr_with_data, decode_nlattr,
decode_nla_str, decode_nla_strn, DECODE_NLA_INTEGER): Likewise.
* nlattr.h (nla_decoder_t, DECL_NLA, decode_nlattr): Likewise.
2017-07-19 10:07:34 +00:00
unsigned int len ,
2017-07-19 17:17:36 +08:00
const bool capped )
2017-04-17 04:37:41 +00:00
{
struct nlmsgerr err ;
2017-06-02 22:22:22 +00:00
if ( len < sizeof ( err . error ) ) {
2017-07-07 09:10:17 +08:00
printstr_ex ( tcp , addr , len , QUOTE_FORCE_HEX ) ;
2017-06-02 22:22:22 +00:00
return ;
}
2017-04-17 04:37:41 +00:00
if ( umove_or_printaddr ( tcp , addr , & err . error ) )
return ;
tprints ( " {error= " ) ;
2018-09-27 07:42:50 +02:00
print_err ( err . error , true ) ;
2017-04-17 04:37:41 +00:00
addr + = offsetof ( struct nlmsgerr , msg ) ;
len - = offsetof ( struct nlmsgerr , msg ) ;
if ( len ) {
tprints ( " , msg= " ) ;
2018-05-29 09:58:10 +00:00
if ( fetch_nlmsghdr ( tcp , & err . msg , addr , len , false ) ) {
2017-07-19 17:17:36 +08:00
unsigned int payload =
capped ? sizeof ( err . msg ) : err . msg . nlmsg_len ;
if ( payload > len )
payload = len ;
2017-06-03 22:56:32 +00:00
decode_nlmsghdr_with_payload ( tcp , fd , family ,
2017-07-19 17:17:36 +08:00
& err . msg , addr , payload ) ;
2017-07-19 17:17:37 +08:00
if ( len > payload ) {
tprints ( " , " ) ;
decode_nlattr ( tcp , addr + payload ,
len - payload , nlmsgerr_attrs ,
" NLMSGERR_ATTR_??? " ,
nlmsgerr_nla_decoders ,
ARRAY_SIZE ( nlmsgerr_nla_decoders ) ,
NULL ) ;
}
2017-04-17 04:37:41 +00:00
}
}
tprints ( " } " ) ;
}
2017-06-09 23:06:42 +00:00
static const netlink_decoder_t netlink_decoders [ ] = {
2017-07-20 15:55:22 +08:00
# ifdef HAVE_LINUX_CRYPTOUSER_H
[ NETLINK_CRYPTO ] = decode_netlink_crypto ,
2018-03-08 22:53:44 +08:00
# endif
# ifdef HAVE_LINUX_NETFILTER_NFNETLINK_H
[ NETLINK_NETFILTER ] = decode_netlink_netfilter ,
2017-07-20 15:55:22 +08:00
# endif
2017-06-16 20:49:15 +08:00
[ NETLINK_ROUTE ] = decode_netlink_route ,
2017-07-14 13:16:36 +08:00
[ NETLINK_SELINUX ] = decode_netlink_selinux ,
2017-06-09 23:06:42 +00:00
[ NETLINK_SOCK_DIAG ] = decode_netlink_sock_diag
} ;
2017-04-17 04:37:41 +00:00
static void
decode_payload ( struct tcb * const tcp ,
2016-07-11 12:54:59 +00:00
const int fd ,
2017-06-03 22:56:32 +00:00
const int family ,
2017-04-17 04:37:41 +00:00
const struct nlmsghdr * const nlmsghdr ,
const kernel_ulong_t addr ,
Adjust prototypes of netlink parsing functions
Change the type of "len" argument that is based
on struct nlmsghdr.nlmsg_len from kernel_ulong_t to unsigned int.
* defs.h (netlink_decoder_t, DECL_NETLINK): Change "len" argument type
from kernel_ulong_t to unsigned int.
* netlink.c (decode_nlmsgerr_attr_cookie, decode_nlmsgerr,
decode_payload): Likewise.
* netlink_selinux.c (decode_netlink_selinux): Likewise.
* netlink_sock_diag.c (decode_family, decode_unix_diag_req,
decode_meminfo, decode_unix_diag_vfs, decode_unix_diag_inode,
decode_unix_diag_rqlen, decode_unix_diag_msg, decode_netlink_diag_req,
print_group, decode_netlink_diag_ring, decode_netlink_diag_flags,
decode_netlink_diag_msg, decode_packet_diag_req,
decode_packet_diag_info, decode_packet_diag_mclist,
decode_packet_diag_ring, decode_packet_diag_filter,
decode_packet_diag_msg, decode_inet_addr, decode_inet_diag_hostcond,
decode_inet_diag_markcond, decode_bytecode_data, decode_inet_diag_bc_op,
decode_inet_diag_req_compat, decode_inet_diag_req_v2,
decode_inet_diag_req, decode_inet_diag_meminfo, decode_tcpvegas_info,
decode_tcp_dctcp_info, decode_tcp_bbr_info, decode_inet_diag_msg,
decode_smc_diag_req, decode_smc_diag_conninfo, decode_smc_diag_lgrinfo,
decode_smc_diag_msg, netlink_diag_decoder_t, decode_netlink_sock_diag):
Likewise.
* nlattr.c (fetch_nlattr, decode_nlattr_with_data, decode_nlattr,
decode_nla_str, decode_nla_strn, DECODE_NLA_INTEGER): Likewise.
* nlattr.h (nla_decoder_t, DECL_NLA, decode_nlattr): Likewise.
2017-07-19 10:07:34 +00:00
const unsigned int len )
2017-04-17 04:37:41 +00:00
{
2017-06-02 22:22:22 +00:00
if ( nlmsghdr - > nlmsg_type = = NLMSG_ERROR ) {
2017-07-19 17:17:36 +08:00
decode_nlmsgerr ( tcp , fd , family , addr , len ,
nlmsghdr - > nlmsg_flags & NLM_F_CAPPED ) ;
2017-06-02 22:22:22 +00:00
return ;
2017-06-09 23:06:42 +00:00
}
2017-08-08 22:37:37 +08:00
/*
* While most of NLMSG_DONE messages indeed have payloads
* containing just a single integer , there are few exceptions ,
* so pass payloads of NLMSG_DONE messages to family - specific
* netlink payload decoders .
*
* Other types of reserved control messages need no family - specific
* netlink payload decoding .
*/
if ( ( nlmsghdr - > nlmsg_type > = NLMSG_MIN_TYPE
| | nlmsghdr - > nlmsg_type = = NLMSG_DONE )
& & ( unsigned int ) family < ARRAY_SIZE ( netlink_decoders )
2017-06-09 23:06:42 +00:00
& & netlink_decoders [ family ]
& & netlink_decoders [ family ] ( tcp , nlmsghdr , addr , len ) ) {
return ;
}
if ( nlmsghdr - > nlmsg_type = = NLMSG_DONE & & len = = sizeof ( int ) ) {
2017-05-05 18:21:17 +08:00
int num ;
if ( ! umove_or_printaddr ( tcp , addr , & num ) )
tprintf ( " %d " , num ) ;
return ;
2017-04-17 04:37:41 +00:00
}
2017-06-02 22:22:22 +00:00
2017-07-07 09:34:59 +08:00
printstr_ex ( tcp , addr , len , QUOTE_FORCE_HEX ) ;
2017-04-17 04:37:41 +00:00
}
2016-07-08 16:01:49 +00:00
static void
2016-12-20 23:16:25 +00:00
decode_nlmsghdr_with_payload ( struct tcb * const tcp ,
2016-07-11 12:54:59 +00:00
const int fd ,
2017-08-08 22:37:37 +08:00
const int family ,
2016-07-08 16:01:49 +00:00
const struct nlmsghdr * const nlmsghdr ,
2016-12-26 10:26:03 +00:00
const kernel_ulong_t addr ,
const kernel_ulong_t len )
2016-07-08 16:01:49 +00:00
{
2018-05-07 08:15:19 +02:00
const unsigned int nlmsg_len = MIN ( nlmsghdr - > nlmsg_len , len ) ;
2017-06-18 21:43:39 +00:00
if ( nlmsg_len > NLMSG_HDRLEN )
tprints ( " { " ) ;
2016-07-08 16:01:49 +00:00
2017-08-08 22:37:37 +08:00
print_nlmsghdr ( tcp , fd , family , nlmsghdr ) ;
2016-07-06 15:49:22 +00:00
2017-04-17 04:37:29 +00:00
if ( nlmsg_len > NLMSG_HDRLEN ) {
2016-07-06 15:49:22 +00:00
tprints ( " , " ) ;
2017-06-03 22:56:32 +00:00
decode_payload ( tcp , fd , family , nlmsghdr , addr + NLMSG_HDRLEN ,
nlmsg_len - NLMSG_HDRLEN ) ;
2017-06-18 21:43:39 +00:00
tprints ( " } " ) ;
2016-07-06 15:49:22 +00:00
}
}
2016-07-08 16:01:49 +00:00
void
2016-07-11 12:54:59 +00:00
decode_netlink ( struct tcb * const tcp ,
const int fd ,
kernel_ulong_t addr ,
kernel_ulong_t len )
2016-07-08 16:01:49 +00:00
{
2017-08-08 22:37:37 +08:00
const int family = get_fd_nl_family ( tcp , fd ) ;
2017-08-08 22:39:21 +08:00
if ( family = = NETLINK_KOBJECT_UEVENT ) {
2018-03-03 16:41:43 +05:30
decode_netlink_kobject_uevent ( tcp , addr , len ) ;
2017-08-08 22:39:21 +08:00
return ;
}
2016-07-08 16:01:49 +00:00
struct nlmsghdr nlmsghdr ;
2018-05-07 08:26:29 +02:00
bool is_array = false ;
2016-07-08 16:01:49 +00:00
unsigned int elt ;
2018-05-29 09:58:10 +00:00
for ( elt = 0 ; fetch_nlmsghdr ( tcp , & nlmsghdr , addr , len , is_array ) ;
elt + + ) {
2016-07-08 16:01:49 +00:00
if ( abbrev ( tcp ) & & elt = = max_strlen ) {
tprints ( " ... " ) ;
break ;
}
2016-12-25 01:31:49 +00:00
unsigned int nlmsg_len = NLMSG_ALIGN ( nlmsghdr . nlmsg_len ) ;
2016-12-26 10:26:03 +00:00
kernel_ulong_t next_addr = 0 ;
kernel_ulong_t next_len = 0 ;
2016-07-08 16:01:49 +00:00
2017-04-17 04:37:29 +00:00
if ( nlmsghdr . nlmsg_len > = NLMSG_HDRLEN ) {
2016-07-08 16:01:49 +00:00
next_len = ( len > = nlmsg_len ) ? len - nlmsg_len : 0 ;
if ( next_len & & addr + nlmsg_len > addr )
next_addr = addr + nlmsg_len ;
}
2018-05-07 08:26:29 +02:00
if ( ! is_array & & next_addr ) {
2016-07-08 16:01:49 +00:00
tprints ( " [ " ) ;
2018-05-07 08:26:29 +02:00
is_array = true ;
2016-07-08 16:01:49 +00:00
}
2017-08-08 22:37:37 +08:00
decode_nlmsghdr_with_payload ( tcp , fd , family ,
2017-06-03 22:56:32 +00:00
& nlmsghdr , addr , len ) ;
2016-07-08 16:01:49 +00:00
if ( ! next_addr )
break ;
tprints ( " , " ) ;
addr = next_addr ;
len = next_len ;
}
2018-05-07 08:26:29 +02:00
if ( is_array ) {
2016-07-08 16:01:49 +00:00
tprints ( " ] " ) ;
}
}