@@ -997,7 +997,6 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
997997 struct nft_table * table ;
998998 struct nft_ctx ctx ;
999999 u32 flags = 0 ;
1000- u16 udlen = 0 ;
10011000 int err ;
10021001
10031002 lockdep_assert_held (& net -> nft .commit_mutex );
@@ -1034,13 +1033,11 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
10341033 goto err_strdup ;
10351034
10361035 if (nla [NFTA_TABLE_USERDATA ]) {
1037- udlen = nla_len (nla [NFTA_TABLE_USERDATA ]);
1038- table -> udata = kzalloc (udlen , GFP_KERNEL );
1036+ table -> udata = nla_memdup (nla [NFTA_TABLE_USERDATA ], GFP_KERNEL );
10391037 if (table -> udata == NULL )
10401038 goto err_table_udata ;
10411039
1042- nla_memcpy (table -> udata , nla [NFTA_TABLE_USERDATA ], udlen );
1043- table -> udlen = udlen ;
1040+ table -> udlen = nla_len (nla [NFTA_TABLE_USERDATA ]);
10441041 }
10451042
10461043 err = rhltable_init (& table -> chains_ht , & nft_chain_ht_params );
@@ -1222,6 +1219,7 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx)
12221219
12231220 rhltable_destroy (& ctx -> table -> chains_ht );
12241221 kfree (ctx -> table -> name );
1222+ kfree (ctx -> table -> udata );
12251223 kfree (ctx -> table );
12261224}
12271225
@@ -1317,6 +1315,8 @@ static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
13171315 [NFTA_CHAIN_COUNTERS ] = { .type = NLA_NESTED },
13181316 [NFTA_CHAIN_FLAGS ] = { .type = NLA_U32 },
13191317 [NFTA_CHAIN_ID ] = { .type = NLA_U32 },
1318+ [NFTA_CHAIN_USERDATA ] = { .type = NLA_BINARY ,
1319+ .len = NFT_USERDATA_MAXLEN },
13201320};
13211321
13221322static const struct nla_policy nft_hook_policy [NFTA_HOOK_MAX + 1 ] = {
@@ -1458,6 +1458,10 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
14581458 if (nla_put_be32 (skb , NFTA_CHAIN_USE , htonl (chain -> use )))
14591459 goto nla_put_failure ;
14601460
1461+ if (chain -> udata &&
1462+ nla_put (skb , NFTA_CHAIN_USERDATA , chain -> udlen , chain -> udata ))
1463+ goto nla_put_failure ;
1464+
14611465 nlmsg_end (skb , nlh );
14621466 return 0 ;
14631467
@@ -1694,9 +1698,11 @@ void nf_tables_chain_destroy(struct nft_ctx *ctx)
16941698 free_percpu (rcu_dereference_raw (basechain -> stats ));
16951699 }
16961700 kfree (chain -> name );
1701+ kfree (chain -> udata );
16971702 kfree (basechain );
16981703 } else {
16991704 kfree (chain -> name );
1705+ kfree (chain -> udata );
17001706 kfree (chain );
17011707 }
17021708}
@@ -2050,7 +2056,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
20502056 } else {
20512057 if (!(flags & NFT_CHAIN_BINDING )) {
20522058 err = - EINVAL ;
2053- goto err1 ;
2059+ goto err_destroy_chain ;
20542060 }
20552061
20562062 snprintf (name , sizeof (name ), "__chain%llu" , ++ chain_id );
@@ -2059,13 +2065,22 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
20592065
20602066 if (!chain -> name ) {
20612067 err = - ENOMEM ;
2062- goto err1 ;
2068+ goto err_destroy_chain ;
2069+ }
2070+
2071+ if (nla [NFTA_CHAIN_USERDATA ]) {
2072+ chain -> udata = nla_memdup (nla [NFTA_CHAIN_USERDATA ], GFP_KERNEL );
2073+ if (chain -> udata == NULL ) {
2074+ err = - ENOMEM ;
2075+ goto err_destroy_chain ;
2076+ }
2077+ chain -> udlen = nla_len (nla [NFTA_CHAIN_USERDATA ]);
20632078 }
20642079
20652080 rules = nf_tables_chain_alloc_rules (chain , 0 );
20662081 if (!rules ) {
20672082 err = - ENOMEM ;
2068- goto err1 ;
2083+ goto err_destroy_chain ;
20692084 }
20702085
20712086 * rules = NULL ;
@@ -2074,12 +2089,12 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
20742089
20752090 err = nf_tables_register_hook (net , table , chain );
20762091 if (err < 0 )
2077- goto err1 ;
2092+ goto err_destroy_chain ;
20782093
20792094 trans = nft_trans_chain_add (ctx , NFT_MSG_NEWCHAIN );
20802095 if (IS_ERR (trans )) {
20812096 err = PTR_ERR (trans );
2082- goto err2 ;
2097+ goto err_unregister_hook ;
20832098 }
20842099
20852100 nft_trans_chain_policy (trans ) = NFT_CHAIN_POLICY_UNSET ;
@@ -2089,15 +2104,15 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
20892104 err = nft_chain_add (table , chain );
20902105 if (err < 0 ) {
20912106 nft_trans_destroy (trans );
2092- goto err2 ;
2107+ goto err_unregister_hook ;
20932108 }
20942109
20952110 table -> use ++ ;
20962111
20972112 return 0 ;
2098- err2 :
2113+ err_unregister_hook :
20992114 nf_tables_unregister_hook (net , table , chain );
2100- err1 :
2115+ err_destroy_chain :
21012116 nf_tables_chain_destroy (ctx );
21022117
21032118 return err ;
@@ -5906,7 +5921,6 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
59065921 struct nft_object * obj ;
59075922 struct nft_ctx ctx ;
59085923 u32 objtype ;
5909- u16 udlen ;
59105924 int err ;
59115925
59125926 if (!nla [NFTA_OBJ_TYPE ] ||
@@ -5963,13 +5977,11 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
59635977 }
59645978
59655979 if (nla [NFTA_OBJ_USERDATA ]) {
5966- udlen = nla_len (nla [NFTA_OBJ_USERDATA ]);
5967- obj -> udata = kzalloc (udlen , GFP_KERNEL );
5980+ obj -> udata = nla_memdup (nla [NFTA_OBJ_USERDATA ], GFP_KERNEL );
59685981 if (obj -> udata == NULL )
59695982 goto err_userdata ;
59705983
5971- nla_memcpy (obj -> udata , nla [NFTA_OBJ_USERDATA ], udlen );
5972- obj -> udlen = udlen ;
5984+ obj -> udlen = nla_len (nla [NFTA_OBJ_USERDATA ]);
59735985 }
59745986
59755987 err = nft_trans_obj_add (& ctx , NFT_MSG_NEWOBJ , obj );
@@ -6238,6 +6250,7 @@ static void nft_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
62386250
62396251 module_put (obj -> ops -> type -> owner );
62406252 kfree (obj -> key .name );
6253+ kfree (obj -> udata );
62416254 kfree (obj );
62426255}
62436256
0 commit comments