OSDN Git Service

ANDROID: netfilter: xt_qtaguid: add qtaguid matching module
authorJP Abgrall <jpa@google.com>
Mon, 20 Jun 2011 19:41:46 +0000 (12:41 -0700)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 12 Jun 2019 16:06:19 +0000 (00:06 +0800)
commit9ec9344a69c00f09a71ec855bfac5e7853919c9a
tree9d5090265f558900a6d25268334d622d3786baf8
parent2bd8593118d5e4d79c29cfd9ad9184a010b50227
ANDROID: netfilter: xt_qtaguid: add qtaguid matching module

This module allows tracking stats at the socket level for given UIDs.
It replaces xt_owner.
If the --uid-owner is not specified, it will just count stats based on
who the skb belongs to. This will even happen on incoming skbs as it
looks into the skb via xt_socket magic to see who owns it.
If an skb is lost, it will be assigned to uid=0.

To control what sockets of what UIDs are tagged by what, one uses:
  echo t $sock_fd $accounting_tag $the_billed_uid \
     > /proc/net/xt_qtaguid/ctrl
 So whenever an skb belongs to a sock_fd, it will be accounted against
   $the_billed_uid
  and matching stats will show up under the uid with the given
   $accounting_tag.

Because the number of allocations for the stats structs is not that big:
  ~500 apps * 32 per app
we'll just do it atomic. This avoids walking lists many times, and
the fancy worker thread handling. Slabs will grow when needed later.

It use netdevice and inetaddr notifications instead of hooks in the core dev
code to track when a device comes and goes. This removes the need for
exposed iface_stat.h.

Put procfs dirs in /proc/net/xt_qtaguid/
  ctrl
  stats
  iface_stat/<iface>/...
The uid stats are obtainable in ./stats.

Change-Id: I01af4fd91c8de651668d3decb76d9bdc1e343919
Signed-off-by: JP Abgrall <jpa@google.com>
[AmitP: Folded following android-4.9 commit changes into this patch
        e5d798684a71 ("ANDROID: netfilter: qtaguid: initialize a local var to keep compiler happy")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
ANDROID: netfilter: xt_qtaguid: fix ipv6 protocol lookup

When updating the stats for a given uid it would incorrectly assume
IPV4 and pick up the wrong protocol when IPV6.

Change-Id: Iea4a635012b4123bf7aa93809011b7b2040bb3d5
Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: start tracking iface rx/tx at low level

qtaguid tracks the device stats by monitoring when it goes up and down,
then it gets the dev_stats().
But devs don't correctly report stats (either they don't count headers
symmetrically between rx/tx, or they count internal control messages).

Now qtaguid counts the rx/tx bytes/packets during raw:prerouting and
mangle:postrouting (nat is not available in ipv6).

The results are in
  /proc/net/xt_qtaguid/iface_stat_fmt
which outputs a format line (bash expansion):
  ifname  total_skb_{rx,tx}_{bytes,packets}

Added event counters for pre/post handling.
Added extra ctrl_*() pid/uid debugging.

Change-Id: Id84345d544ad1dd5f63e3842cab229e71d339297
Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: report only uid tags to non-privileged processes

In the past, a process could only see its own stats (uid-based summary,
and details).
Now we allow any process to see other UIDs uid-based stats, but still
hide the detailed stats.

Change-Id: I7666961ed244ac1d9359c339b048799e5db9facc
Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: fix error exit that would keep a spinlock.

qtudev_open() could return with a uid_tag_data_tree_lock held
when an kzalloc(..., GFP_ATOMIC) would fail.
Very unlikely to get triggered AND survive the mayhem of running out of mem.

Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: Don't BUG_ON if create_if_tag_stat fails

If create_if_tag_stat fails to allocate memory (GFP_ATOMIC) the
following will happen:

qtaguid: iface_stat: tag stat alloc failed
...
kernel BUG at xt_qtaguid.c:1482!

Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
ANDROID: netfilter: xt_qtaguid: remove AID_* dependency for access control

qtaguid limits what can be done with /ctrl and /stats based on group
membership.
This changes removes AID_NET_BW_STATS and AID_NET_BW_ACCT, and picks
up the groups from the gid of the matching proc entry files.

Signed-off-by: JP Abgrall <jpa@google.com>
Change-Id: I42e477adde78a12ed5eb58fbc0b277cdaadb6f94

ANDROID: netfilter: xt_qtaguid: extend iface stat to report protocols

In the past the iface_stat_fmt would only show global bytes/packets
for the skb-based numbers.
For stall detection in userspace, distinguishing tcp vs other protocols
makes it easier.
Now we report
  ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes
  total_skb_tx_packets {rx,tx}_{tcp,udp,ohter}_{bytes,packets}

Bug: 6818637
Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: Allow tracking loopback

In the past it would always ignore interfaces with loopback addresses.
Now we just treat them like any other.
This also helps with writing tests that check for the presence
of the qtaguid module.

Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: rate limit some of the printks

Some of the printks are in the packet handling path.
We now ratelimit the very unlikely errors to avoid
kmsg spamming.

Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: 3.10 fixes

Stop using obsolete procfs api.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
[AmitP: Folded following android-4.9 commit changes into this patch
        564729173b12 ("netfilter: xt_qtaguid: fix memory leak in seq_file handlers")
        85a2eb5b48fc ("ANDROID: netfilter: xt_qtaguid: 64-bit warning fixes")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
ANDROID: netfilter: xt_qtaguid: fix bad tcp_time_wait sock handling

Since (41063e9 ipv4: Early TCP socket demux), skb's can have an sk which
is not a struct sock but the smaller struct inet_timewait_sock without an
sk->sk_socket. Now we bypass sk_state == TCP_TIME_WAIT

Signed-off-by: JP Abgrall <jpa@google.com>
ANDROID: netfilter: xt_qtaguid: Fix boot panic

We need the change below because of mainline commit 351638e7de (net: pass
info struct via netdevice notifier). Otherwise we panic.

Change-Id: I7daf7513a733933fdcbaeebea7f8191f8b6a0432
Signed-off-by: John Stultz <john.stultz@linaro.org>
ANDROID: netfilter: xt_qtaguid/xt_socket: Build fixups

Fix up build kuid/kguid build issues in netfilter code.

Also re-add the xt_socket_get/put_sk interfaces needed by xt_qtaguid.

Change-Id: I7027fb840e109785bddffe8ea717b8d018b26d82
Signed-off-by: John Stultz <john.stultz@linaro.org>
[AmitP: Folded following android-4.9 commit changes into this patch
        da5ea99a74f2 ("ANDROID: netfilter: xt_qtaguid: fix seq_printf type mismatch warning")
        070eff8f023c ("ANDROID: netfilter: xt_qtaguid: fix broken uid/gid range check")]
        2879b6ec24ee ("ANDROID: xt_qtaguid: use sock_gen_put() instead of xt_socket_put_sk()")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
ANDROID: netfilter: xt_qtaguid: Use sk_callback_lock read locks before reading sk->sk_socket

It prevents a kernel panic when accessing sk->sk_socket fields due to NULLing sk->sk_socket when sock_orphan is called through
sk_common_release.

Change-Id: I4aa46b4e2d8600e4d4ef8dcdd363aa4e6e5f8433
Signed-off-by: Mohamad Ayyash <mkayyash@google.com>
(cherry picked from commit cdea0ebcb8bcfe57688f6cb692b49e550ebd9796)
Signed-off-by: John Stultz <john.stultz@linaro.org>
ANDROID: netfilter: xt_qtaguid: xt_socket: build fixes

Add missing header <linux/miscdevice.h> and use
xt_socket_lookup_slow_v* instead of xt_socket_get*_sk
in xt_qtaguid.c.

Fix xt_socket_lookup_slow_v* functions in xt_socket.c
and declare them in xt_socket.h

Change-Id: I55819b2d4ffa82a2be20995c87d28fb5cc77b5ba
Signed-off-by: John Stultz <john.stultz@linaro.org>
[AmitP: Upstream commit 8db4c5be88f6 ("netfilter: move socket lookup
        infrastructure to nf_socket_ipv{4,6}.c")] moved socket lookup
        to nf_socket_ipv{4,6}.c, hence use nf_sk_lookup_slow_v[4|6]()
        instead of obsolete xt_socket_lookup_slow_v[4|6]().

        Also folded following android-4.9 commit changes into this patch
        7de1bb86dc5a ("ANDROID: netfilter: xt_qtaguid/socket: build fixes for 4.4")
        5b5ab94817f9 ("ANDROID: netfilter: xt_qtaguid: seq_printf fixes")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
ANDROID: netfilter: xt_qtaguid: fix a race condition in if_tag_stat_update

Miss a lock protection in if_tag_stat_update while doing get_iface_entry. So if
one CPU is doing iface_stat_create while another CPU is doing if_tag_stat_update,
race will happened.

Change-Id: Ib8d98e542f4e385685499f5b7bb7354f08654a75
Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
ANDROID: netfilter: xt_qtaguid: Fix panic caused by synack processing

In upstream commit ca6fb06518836ef9b65dc0aac02ff97704d52a05
(tcp: attach SYNACK messages to request sockets instead of
listener)
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ca6fb0651883

The building of synack messages was changed, which made it so
the skb->sk points to a casted request_sock. This is problematic,
as there is no sk_socket in a request_sock. So when the qtaguid_mt
function tries to access the sk->sk_socket, it accesses uninitialized
memory.

After looking at how other netfilter implementations handle this,
I realized there was a skb_to_full_sk() helper added, which the
xt_qtaguid code isn't yet using.

This patch adds its use, and resovles panics seen when accessing
uninitialzed memory when processing synack packets.

Reported-by: YongQin Liu <yongquin.liu@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
ANDROID: netfilter: xt_qtaguid: Fix panic caused by processing non-full socket.

In an issue very similar to 4e461c777e3 (xt_qtaguid: Fix panic
caused by synack processing), we were seeing panics on occasion
in testing.

In this case, it was the same issue, but caused by a different
call path, as the sk being returned from qtaguid_find_sk() was
not a full socket. Resulting in the sk->sk_socket deref to fail.

This patch adds an extra check to ensure the sk being retuned
is a full socket, and if not it returns NULL.

Reported-by: Milosz Wasilewski <milosz.wasilewski@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
ANDROID: netfilter: xt_qtaguid: Don't show empty tag stats for unprivileged uids

BUG: 27577101
BUG: 27532522
Change-Id: Ibee3c5d224f139b9312a40acb203e87aa7060797
Signed-off-by: Mohamad Ayyash <mkayyash@google.com>
ANDROID: netfilter: xt_qtaguid: fix the deadlock when enable DDEBUG

When DDEBUG is enabled, the prdebug_full_state() function will try to
recursively aquire the spinlock of sock_tag_list and causing deadlock. A
check statement is added before it aquire the spinlock to differentiate
the behavior depend on the caller of the function.

Bug: 36559739
Test: Compile and run test under system/extra/test/iptables/
Change-Id: Ie3397fbaa207e14fe214d47aaf5e8ca1f4a712ee
Signed-off-by: Chenbo Feng <fengc@google.com>
(cherry picked from commit f0faedd6b468777f3bb5834f97100794d562c8b7)

ANDROID: netfilter: xt_qtaguid: don't check if embedded arrays are NULL

clang warns about four NULL pointer checks:

net/netfilter/xt_qtaguid.c:973:11: warning: address of array 'ifa->ifa_label' will always evaluate to 'true' [-Wpointer-bool-conversion]
net/netfilter/xt_qtaguid.c:974:13: warning: address of array 'ifa->ifa_label' will always evaluate to 'true' [-Wpointer-bool-conversion]
net/netfilter/xt_qtaguid.c:1212:31: warning: address of array 'el_dev->name' will always evaluate to 'true' [-Wpointer-bool-conversion]
net/netfilter/xt_qtaguid.c:1640:31: warning: address of array 'el_dev->name' will always evaluate to 'true' [-Wpointer-bool-conversion]

Both of these fields are embedded char[16] arrays rather than pointers,
so they can never be NULL.

Change-Id: I748ff6dd11569e5596a9d5cecdf9c334847e7307
Signed-off-by: Greg Hackmann <ghackmann@google.com>
ANDROID: netfilter: xt_qtaguid: Add untag hacks to inet_release function

To prevent protential risk of memory leak caused by closing socket with
out untag it from qtaguid module, the qtaguid module now do not hold any
socket file reference count. Instead, it will increase the sk_refcnt of
the sk struct to prevent a reuse of the socket pointer.  And when a socket
is released. It will delete the tag if the socket is previously tagged so
no more resources is held by xt_qtaguid moudle. A flag is added to the untag
process to prevent possible kernel crash caused by fail to delete
corresponding socket_tag_entry list.
Bug: 36374484
Test: compile and run test under system/extra/test/iptables,
      run cts -m CtsNetTestCases -t android.net.cts.SocketRefCntTest

Signed-off-by: Chenbo Feng <fengc@google.com>
Change-Id: Iea7c3bf0c59b9774a5114af905b2405f6bc9ee52

ANDROID: netfilter: xt_qtaguid: handle properly request sockets

To match rules related to uid/gid for syn recv packets
we need to get the full socket from request_sock struct.

Bug: 63917742
Change-Id: I03acb2251319fd800d0e36a6dde30fc1fbb7d1b0
Signed-off-by: Simon Dubray <simonx.dubray@intel.com>
ANDROID: netfilter: xt_qtaguid: fix handling for cases where tunnels are used.

* fix skb->dev vs par->in/out
When there is some forwarding going on, it introduces extra state
around devs associated with xt_action_param->in/out and sk_buff->dev.
E.g.
   par->in and par->out are both set, or
   skb->dev and par->out are both set (and different)
This would lead qtaguid to make the wrong assumption about the
direction and update the wrong device stats.
Now we rely more on par->in/out.

* Fix handling when qtaguid is used as "owner"
When qtaguid is used as an owner module, and sk_socket->file is
not there (happens when tunnels are involved), it would
incorrectly do a tag stats update.

* Correct debug messages.

Bug: 11687690
Change-Id: I2b1ff8bd7131969ce9e25f8291d83a6280b3ba7f
CRs-Fixed: 747810
Signed-off-by: JP Abgrall <jpa@google.com>
Git-commit: 2b71479d6f5fe8f33b335f713380f72037244395
Git-repo: https://www.codeaurora.org/cgit/quic/la/kernel/mediatek
[imaund@codeaurora.org: Resolved trivial context conflicts.]
Signed-off-by: Ian Maund <imaund@codeaurora.org>
[bflowers@codeaurora.org: Resolved merge conflicts]
Signed-off-by: Bryse Flowers <bflowers@codeaurora.org>
Signed-off-by: Chenbo Feng <fengc@google.com>
ANDROID: netfilter: xt_qtaguid: Use sk_uid to replace uid get from socket file

Retrieve socket uid from the sk_uid field added to struct sk instead of
read it from sk->socket->file. It prevent the packet been dropped when
the socket file doesn't exist.

Bug: 37524657
Signed-off-by: Chenbo Feng <fengc@google.com>
Change-Id: Ic58239c1f9aa7e0eb1d4d1c09d40b845fd4e8e57

ANDROID: netfilter: xt_qtaguid: Fix 4.14 compilation

struct xt_action_param was changed:
  in, out, family and hooknum were moved to
struct nf_hook_state *state
  in, out, pf and hook
Replace atomic_read() with refcount_read()

Change-Id: If463bf84db08fe382baa825ca7818cab2150b60d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
ANDROID: qtaguid: Fix the UAF probelm with tag_ref_tree

When multiple threads is trying to tag/delete the same socket at the
same time, there is a chance the tag_ref_entry of the target socket to
be null before the uid_tag_data entry is freed. It is caused by the
ctrl_cmd_tag function where it doesn't correctly grab the spinlocks
when tagging a socket.

Signed-off-by: Chenbo Feng <fengc@google.com>
Bug: 65853158
Change-Id: I5d89885918054cf835370a52bff2d693362ac5f0

ANDROID: xt_qtaguid: Remove unnecessary null checks to device's name

'name' will never be NULL since it isn't a plain pointer but an array
of char values.

../net/netfilter/xt_qtaguid.c:1195:27: warning: address of array
'(*el_dev)->name' will always evaluate to 'true'
[-Wpointer-bool-conversion]
        if (unlikely(!(*el_dev)->name)) {
                     ~~~~~~~~~~~~^~~~

Change-Id: If3b25f17829b43e8a639193fb9cd04ae45947200
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
(cherry picked from android-4.4 commit 207b579e3db6fd0cb6fe40ba3e929635ad748d89)
Signed-off-by: Chenbo Feng <fengc@google.com>
include/linux/android_aid.h
include/linux/netfilter/xt_qtaguid.h [new file with mode: 0644]
net/ipv4/af_inet.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/xt_qtaguid.c [new file with mode: 0644]
net/netfilter/xt_qtaguid_internal.h [new file with mode: 0644]
net/netfilter/xt_qtaguid_print.c [new file with mode: 0644]
net/netfilter/xt_qtaguid_print.h [new file with mode: 0644]