OSDN Git Service

netfilter: nf_tables: do not allow to delete table with owner by handle
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 22 Jun 2021 10:10:49 +0000 (12:10 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 22 Jun 2021 10:15:05 +0000 (12:15 +0200)
nft_table_lookup_byhandle() also needs to validate the netlink PortID
owner when deleting a table by handle.

Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c

index 1d62b1a..fcb15b8 100644 (file)
@@ -583,7 +583,7 @@ static struct nft_table *nft_table_lookup(const struct net *net,
 
 static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
                                                   const struct nlattr *nla,
-                                                  u8 genmask)
+                                                  u8 genmask, u32 nlpid)
 {
        struct nftables_pernet *nft_net;
        struct nft_table *table;
@@ -591,8 +591,13 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
        nft_net = nft_pernet(net);
        list_for_each_entry(table, &nft_net->tables, list) {
                if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
-                   nft_active_genmask(table, genmask))
+                   nft_active_genmask(table, genmask)) {
+                       if (nft_table_has_owner(table) &&
+                           nlpid && table->nlpid != nlpid)
+                               return ERR_PTR(-EPERM);
+
                        return table;
+               }
        }
 
        return ERR_PTR(-ENOENT);
@@ -1279,7 +1284,8 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info,
 
        if (nla[NFTA_TABLE_HANDLE]) {
                attr = nla[NFTA_TABLE_HANDLE];
-               table = nft_table_lookup_byhandle(net, attr, genmask);
+               table = nft_table_lookup_byhandle(net, attr, genmask,
+                                                 NETLINK_CB(skb).portid);
        } else {
                attr = nla[NFTA_TABLE_NAME];
                table = nft_table_lookup(net, attr, family, genmask,