mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
netfilter: qtaguid: fix proc/.../stats uid filtered output
"cat /proc/net/xt_qtaguid/stats" for a non-priviledged UID would output multiple twice its own stats. The fix tweaks the way lines are counted. Non-root: idx iface acct_tag_hex uid_tag_int cnt_set ... 2 wlan0 0x0 10022 0 ... 3 wlan0 0x0 10022 1 ... 4 wlan0 0x3010000000000000 10022 0 ... 5 wlan0 0x3010000000000000 10022 1 ... Root: idx iface acct_tag_hex uid_tag_int cnt_set 2 wlan0 0x0 0 0 ... 3 wlan0 0x0 0 1 ... 4 wlan0 0x0 1000 0 ... ... 12 wlan0 0x0 10022 0 ... 13 wlan0 0x0 10022 1 ... ... 18 wlan0 0x3010000000000000 10022 0 ... 19 wlan0 0x3010000000000000 10022 1 ... Change-Id: I3cae1f4fee616bc897831350374656b0c718c45b Signed-off-by: JP Abgrall <jpa@google.com>
This commit is contained in:
@@ -1788,6 +1788,7 @@ struct proc_print_info {
|
||||
struct iface_stat *iface_entry;
|
||||
struct tag_stat *ts_entry;
|
||||
int item_index;
|
||||
int items_to_skip;
|
||||
int char_count;
|
||||
};
|
||||
|
||||
@@ -1795,7 +1796,10 @@ static int pp_stats_line(struct proc_print_info *ppi, int cnt_set)
|
||||
{
|
||||
int len;
|
||||
struct data_counters *cnts;
|
||||
|
||||
if (!ppi->item_index) {
|
||||
if (ppi->item_index++ < ppi->items_to_skip)
|
||||
return 0;
|
||||
len = snprintf(ppi->outp, ppi->char_count,
|
||||
"idx iface acct_tag_hex uid_tag_int cnt_set "
|
||||
"rx_bytes rx_packets "
|
||||
@@ -1809,6 +1813,7 @@ static int pp_stats_line(struct proc_print_info *ppi, int cnt_set)
|
||||
} else {
|
||||
tag_t tag = ppi->ts_entry->tn.tag;
|
||||
uid_t stat_uid = get_uid_from_tag(tag);
|
||||
|
||||
if (!can_read_other_uid_stats(stat_uid)) {
|
||||
CT_DEBUG("qtaguid: stats line: "
|
||||
"%s 0x%llx %u: "
|
||||
@@ -1818,6 +1823,8 @@ static int pp_stats_line(struct proc_print_info *ppi, int cnt_set)
|
||||
current->pid, current_fsuid());
|
||||
return 0;
|
||||
}
|
||||
if (ppi->item_index++ < ppi->items_to_skip)
|
||||
return 0;
|
||||
cnts = &ppi->ts_entry->counters;
|
||||
len = snprintf(
|
||||
ppi->outp, ppi->char_count,
|
||||
@@ -1891,11 +1898,13 @@ static int qtaguid_stats_proc_read(char *page, char **num_items_returned,
|
||||
ppi.item_index = 0;
|
||||
ppi.char_count = char_count;
|
||||
ppi.num_items_returned = num_items_returned;
|
||||
ppi.items_to_skip = items_to_skip;
|
||||
|
||||
if (unlikely(module_passive)) {
|
||||
len = pp_stats_line(&ppi, 0);
|
||||
/* The header should always be shorter than the buffer. */
|
||||
WARN_ON(len >= ppi.char_count);
|
||||
(*num_items_returned)++;
|
||||
*eof = 1;
|
||||
return len;
|
||||
}
|
||||
@@ -1907,16 +1916,17 @@ static int qtaguid_stats_proc_read(char *page, char **num_items_returned,
|
||||
if (*eof)
|
||||
return 0;
|
||||
|
||||
if (!items_to_skip) {
|
||||
/* The idx is there to help debug when things go belly up. */
|
||||
len = pp_stats_line(&ppi, 0);
|
||||
/* Don't advance the outp unless the whole line was printed */
|
||||
if (len >= ppi.char_count) {
|
||||
*ppi.outp = '\0';
|
||||
return ppi.outp - page;
|
||||
}
|
||||
/* The idx is there to help debug when things go belly up. */
|
||||
len = pp_stats_line(&ppi, 0);
|
||||
/* Don't advance the outp unless the whole line was printed */
|
||||
if (len >= ppi.char_count) {
|
||||
*ppi.outp = '\0';
|
||||
return ppi.outp - page;
|
||||
}
|
||||
if (len) {
|
||||
ppi.outp += len;
|
||||
ppi.char_count -= len;
|
||||
(*num_items_returned)++;
|
||||
}
|
||||
|
||||
spin_lock_bh(&iface_stat_list_lock);
|
||||
@@ -1927,8 +1937,6 @@ static int qtaguid_stats_proc_read(char *page, char **num_items_returned,
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
ppi.ts_entry = rb_entry(node, struct tag_stat, tn.node);
|
||||
if (ppi.item_index++ < items_to_skip)
|
||||
continue;
|
||||
if (!pp_sets(&ppi)) {
|
||||
spin_unlock_bh(
|
||||
&ppi.iface_entry->tag_stat_list_lock);
|
||||
|
||||
Reference in New Issue
Block a user