nbdd0121 / nfq-rs

Rust library for dealing with NetFilter queue
Apache License 2.0
31 stars 12 forks source link

First call of queue.recv() #2

Closed rfael closed 4 years ago

rfael commented 4 years ago

I tried to use your library for mipsel-unknown-linux-musl target in some project, and I noticed a problem. Every time when I run my program, and it does first call of recv() method on Queue struct object it results with error: Error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" } Every next call is valid.

That error is returned in 760 line of ./src/lib.rs file.

 if unsafe { (*nlh).nlmsg_flags } & NLM_F_DUMP_INTR as u16 != 0 {
                    return Err(std::io::Error::from_raw_os_error(EINTR));
                }

I checked what syscalls can return a error with strace, and i figured out this invalid syscall:

recvfrom(3, {{len=56, type=NLMSG_ERROR, flags=0, seq=0, pid=19762}, {error=-EOPNOTSUPP, msg={{len=36, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x08\x00\x05\x00\x00\x00\x00\x02\x08\x00\x04\x00\x00\x00\x00\x02"}}}, 4224, MSG_TRUNC, NULL, NULL) = 56

A valid syscall should looks like that (I get its when I run my app on x86 target):

recvfrom(3,  {{len=284, type=NFNL_SUBSYS_QUEUE<<8|NFQNL_MSG_PACKET, flags=0, seq=0, pid=0}, "\x02\x00\x02\x31\x0b\x00\x01\x00\x00\x00\x00\x01\x08\x00\x03\x00\x08\x00\x06\x00\x00\x00\x00\x03\x94\x00\x0b\x80\x3c\x00\x01\x80"...}, 4224, MSG_TRUNC, NULL, NULL) = 284
write(1, "Accepted: saddr: 192.168.12.242 "..., 63Accepted: saddr: 192.168.12.242 daddr: 212.77.98.9 proto: Icmp
) = 63

That error occurs only on MIPS target, x86 was ok

nbdd0121 commented 4 years ago

It looks that the error message is a response to previous configuration. Your strace says type 0x302 is ??? where it should be NFNL_SUBSYS_QUEUE<<8|NFQNL_MSG_CONFIG. It hints that the kernel might not support nfqueue. What kernel version are you using?

Edit: Can you provide a more detailed strace? I would also like to see the previous syscalls that does the setup.

rfael commented 4 years ago

I am using this with OpenWRT and its Linux version is 4.14.95.

queue.revc() strace:

set_thread_area(0x77f98ec0)             = 0
set_tid_address(0x77f91e28)             = 25167
open("/etc/ld-musl-mipsel-sf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=78095, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0p(\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 147456, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x77eca000
mmap2(0x77eed000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x13000) = 0x77eed000
close(3)                                = 0
mprotect(0x5564e000, 12288, PROT_READ)  = 0
set_thread_area(0x55658578)             = 0
set_tid_address(0x556514e0)             = 25167
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[RT_68 RT_73 RT_74 RT_75 RT_76 RT_79 RT_80 RT_81 RT_82 RT_83 RT_84 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=NULL}, {sa_handler=SIG_DFL, sa_mask=[RT_67 RT_68 RT_71 RT_72 RT_73 RT_74 RT_75 RT_79 RT_81 RT_82 RT_84 RT_85 RT_87 RT_89 RT_91 RT_93 RT_95], sa_flags=0}, 16) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 16) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x555f7edc, sa_mask=[RT_73 RT_74 RT_75 RT_76 RT_79 RT_80 RT_81 RT_82 RT_83 RT_84 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=NULL}, NULL, 16) = 0
rt_sigaction(SIGBUS, {sa_handler=0x555f7edc, sa_mask=[RT_73 RT_74 RT_75 RT_76 RT_79 RT_80 RT_81 RT_82 RT_83 RT_84 RT_86 RT_87 RT_88 RT_89 RT_90 RT_91 RT_93 RT_94 RT_95], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=NULL}, NULL, 16) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77f8d000
sigaltstack({ss_sp=0x77f8d000, ss_flags=0, ss_size=8192}, NULL) = 0
socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER) = 3
brk(NULL)                               = 0x5565b000
brk(0x5566e000)                         = 0x5566e000
bind(3, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
setsockopt(3, SOL_NETLINK, NETLINK_NO_ENOBUFS, [1], 4) = 0
sendto(3, {{len=28, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x08\x00\x01\x00\x01\x00\x00\x00"}, 28, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 28
sendto(3, {{len=32, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x09\x00\x02\x00\x00\x00\xff\xff\x02\x00\x00\x00"}, 32, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 32
brk(0x55680000)                         = 0x55680000
sendto(3, {{len=36, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x08\x00\x05\x00\x00\x00\x00\x02\x08\x00\x04\x00\x00\x00\x00\x02"}, 36, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 36
sendto(3, {{len=32, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x09\x00\x02\x00\x00\x00\x00\x80\x02\x00\x00\x00"}, 32, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 32
getrandom("\x37\x9e\x38\x33\xc5\xc6\x1b\x7d\x04\x02\xf5\x05\xa7\x8c\x00\x5f", 16, GRND_NONBLOCK) = 16
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 16) = 0
mmap2(NULL, 2105344, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77cc8000
mprotect(0x77cc9000, 2101248, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x77ec9cb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID|0x400000, parent_tidptr=0x77ec9ce0, tls=0x77ed0d78, child_tidptr=0x77ec9ce0) = 25177
          = 13
recvfrom(3, {{len=48, type=NLMSG_ERROR, flags=0, seq=0, pid=25167}, {error=-EINVAL, msg={{len=28, type=0x302 /* NLMSG_??? */, flags=NLM_F_REQUEST, seq=0, pid=0}, "\x00\x00\x02\x31\x08\x00\x01\x00\x01\x00\x00\x00"}}}, 4224, MSG_TRUNC, NULL, NULL) = 48
close(3)                                = 0
write(2, "Error: ", 7Error: )                  = 7
write(2, "Os", 2Os)                       = 2
write(2, " { ", 3 { )                      = 3
write(2, "code", 4code)                     = 4
write(2, ": ", 2: )                       = 2
write(2, "22", 222)                       = 2
write(2, ", ", 2, )                       = 2
write(2, "kind", 4kind)                     = 4
write(2, ": ", 2: )                       = 2
write(2, "InvalidInput", 12InvalidInput)            = 12
write(2, ", ", 2, )                       = 2
write(2, "message", 7message)                  = 7
write(2, ": ", 2: )                       = 2
write(2, "\"", 1")                       = 1
write(2, "Invalid argument", 16Invalid argument)        = 16
write(2, "\"", 1")                       = 1
write(2, " }", 2 })                       = 2
write(2, "\n", 1
)                       = 1
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x77f8d000, 8192)                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

And lsmod on device where i run that:

# lsmod | grep nf
auth_rpcgss            37461  2 nfsd,rpcsec_gss_krb5
dns_resolver            3866  1 nfsv4
grace                   1569  2 nfsd,lockd
lockd                  53727  2 nfsd,nfs
nf_conntrack           69921 22 ipt_MASQUERADE,xt_state,xt_nat,xt_helper,xt_conntrack,xt_connmark,xt_connlimit,xt_connbytes,xt_REDIRECT,xt_CT,nf_nat_masquerade_ipv4,nf_conntrack_ipv4,nf_nat_ipv4,nf_nat_ftp,nf_flow_table,nf_conntrack_rtcache,nf_conntrack_netlink,nf_conntrack_ftp,nf_nat_masquerade_ipv6,nf_conntrack_ipv6,nf_nat_ipv6,nf_nat
nf_conntrack_ftp        5472  1 nf_nat_ftp
nf_conntrack_ipv4       5136 81 
nf_conntrack_ipv6       5440  8 
nf_conntrack_netlink   22000  0 
nf_conntrack_rtcache    2800  0 
nf_defrag_ipv4          1142  1 nf_conntrack_ipv4
nf_defrag_ipv6          4958  1 nf_conntrack_ipv6
nf_flow_table          13596  2 xt_FLOWOFFLOAD,nf_flow_table_hw
nf_flow_table_hw        2336  1 
nf_log_common           2735  2 nf_log_ipv4,nf_log_ipv6
nf_log_ipv4             3504  0 
nf_log_ipv6             4144  0 
nf_nat                 14170  7 xt_nat,nf_nat_redirect,nf_nat_masquerade_ipv4,nf_nat_ipv4,nf_nat_ftp,nf_nat_masquerade_ipv6,nf_nat_ipv6
nf_nat_ftp              1328  0 
nf_nat_ipv4             3505  1 iptable_nat
nf_nat_ipv6             4051  1 ip6table_nat
nf_nat_masquerade_ipv4    1628  1 ipt_MASQUERADE
nf_nat_masquerade_ipv6    1788  1 ip6t_MASQUERADE
nf_nat_redirect         1435  1 xt_REDIRECT
nf_reject_ipv4          2179  1 ipt_REJECT
nf_reject_ipv6          2536  1 ip6t_REJECT
nfnetlink               4663  2 nf_conntrack_netlink,ip_set
nfs                   124008  1 nfsv4
nfsd                  220147 11 
nfsv4                 131835  0 
sunrpc                166401 12 nfsv4,nfsd,nfs,rpcsec_gss_krb5,auth_rpcgss,lockd

Do you need some more information?

nbdd0121 commented 4 years ago

nfnetlink_queue seems to be missing.

nbdd0121 commented 4 years ago

16a8c2c improves the error reporting. The error would probably now be reported when you use bind rather than recv.

rfael commented 4 years ago

You were right about _nfnetlinkqueue. I fixed that and I used newest version of library. Now I am getting Error: Os { code: 122, kind: Other, message: "Not supported" } in my code

let mut queue = Queue::open()?;
queue.bind(QUEUE_ID)?;
queue.set_recv_conntrack(QUEUE_ID, true)?;

on the queue.set_recv_conntrack(QUEUE_ID, true) line. What could be the reason of that? I have loaded modules for conntrack and _nfnetlinkqueue, maybe I am missing something else?

lsmod:

# lsmod | grep nf
auth_rpcgss            37461  2 nfsd,rpcsec_gss_krb5
dns_resolver            3866  1 nfsv4
grace                   1569  2 nfsd,lockd
lockd                  53727  2 nfsd,nfs
nf_conntrack           69921 22 ipt_MASQUERADE,xt_state,xt_nat,xt_helper,xt_conntrack,xt_connmark,xt_connlimit,xt_connbytes,xt_REDIRECT,xt_CT,nf_nat_masquerade_ipv4,nf_conntrack_ipv4,nf_nat_ipv4,nf_nat_ftp,nf_flow_table,nf_conntrack_rtcache,nf_conntrack_netlink,nf_conntrack_ftp,nf_nat_masquerade_ipv6,nf_conntrack_ipv6,nf_nat_ipv6,nf_nat
nf_conntrack_ftp        5472  1 nf_nat_ftp
nf_conntrack_ipv4       5136 84 
nf_conntrack_ipv6       5440  8 
nf_conntrack_netlink   22000  0 
nf_conntrack_rtcache    2800  0 
nf_defrag_ipv4          1142  1 nf_conntrack_ipv4
nf_defrag_ipv6          4958  1 nf_conntrack_ipv6
nf_flow_table          13596  2 xt_FLOWOFFLOAD,nf_flow_table_hw
nf_flow_table_hw        2336  1 
nf_log_common           2735  2 nf_log_ipv4,nf_log_ipv6
nf_log_ipv4             3504  0 
nf_log_ipv6             4144  0 
nf_nat                 14170  7 xt_nat,nf_nat_redirect,nf_nat_masquerade_ipv4,nf_nat_ipv4,nf_nat_ftp,nf_nat_masquerade_ipv6,nf_nat_ipv6
nf_nat_ftp              1328  0 
nf_nat_ipv4             3505  1 iptable_nat
nf_nat_ipv6             4051  1 ip6table_nat
nf_nat_masquerade_ipv4    1628  1 ipt_MASQUERADE
nf_nat_masquerade_ipv6    1788  1 ip6t_MASQUERADE
nf_nat_redirect         1435  1 xt_REDIRECT
nf_reject_ipv4          2179  1 ipt_REJECT
nf_reject_ipv6          2536  1 ip6t_REJECT
nfnetlink               4663  3 nfnetlink_queue,nf_conntrack_netlink,ip_set
nfnetlink_queue         9776  0 
nfs                   124008  1 nfsv4
nfsd                  220147 11 
nfsv4                 131835  0 
sunrpc                166401 12 nfsv4,nfsd,nfs,rpcsec_gss_krb5,auth_rpcgss,lockd
nbdd0121 commented 4 years ago

Check if your nf_conntrack_netlink is compiled with CONFIG_NETFILTER_NETLINK_GLUE_CT set.

rfael commented 4 years ago

Thanks for your help, setting 'CONFIG_NETFILTER_NETLINK_GLUE_CT' solved the problem, now everything work fine.