@@ -95,8 +95,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
9595 helper = rcu_dereference (help -> helper );
9696 if (helper == NULL )
9797 goto err ;
98- if (strlen (helper -> name ) >= sizeof (dest -> data ))
99- goto err ;
10098 strncpy ((char * )dest -> data , helper -> name , sizeof (dest -> data ));
10199 return ;
102100#ifdef CONFIG_NF_CONNTRACK_LABELS
@@ -109,9 +107,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
109107 return ;
110108 }
111109
112- BUILD_BUG_ON (NF_CT_LABELS_MAX_SIZE > sizeof (dest -> data ));
113110 size = labels -> words * sizeof (long );
114-
115111 memcpy (dest -> data , labels -> bits , size );
116112 if (size < sizeof (dest -> data ))
117113 memset (((char * ) dest -> data ) + size , 0 ,
@@ -228,35 +224,72 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
228224 const struct nlattr * const tb [])
229225{
230226 struct nft_ct * priv = nft_expr_priv (expr );
227+ unsigned int len ;
231228 int err ;
232229
233230 priv -> key = ntohl (nla_get_be32 (tb [NFTA_CT_KEY ]));
234231 switch (priv -> key ) {
235- case NFT_CT_STATE :
236232 case NFT_CT_DIRECTION :
233+ if (tb [NFTA_CT_DIRECTION ] != NULL )
234+ return - EINVAL ;
235+ len = sizeof (u8 );
236+ break ;
237+ case NFT_CT_STATE :
237238 case NFT_CT_STATUS :
238239#ifdef CONFIG_NF_CONNTRACK_MARK
239240 case NFT_CT_MARK :
240241#endif
241242#ifdef CONFIG_NF_CONNTRACK_SECMARK
242243 case NFT_CT_SECMARK :
243244#endif
245+ case NFT_CT_EXPIRATION :
246+ if (tb [NFTA_CT_DIRECTION ] != NULL )
247+ return - EINVAL ;
248+ len = sizeof (u32 );
249+ break ;
244250#ifdef CONFIG_NF_CONNTRACK_LABELS
245251 case NFT_CT_LABELS :
252+ if (tb [NFTA_CT_DIRECTION ] != NULL )
253+ return - EINVAL ;
254+ len = NF_CT_LABELS_MAX_SIZE ;
255+ break ;
246256#endif
247- case NFT_CT_EXPIRATION :
248257 case NFT_CT_HELPER :
249258 if (tb [NFTA_CT_DIRECTION ] != NULL )
250259 return - EINVAL ;
260+ len = NF_CT_HELPER_NAME_LEN ;
251261 break ;
262+
252263 case NFT_CT_L3PROTOCOL :
253264 case NFT_CT_PROTOCOL :
265+ if (tb [NFTA_CT_DIRECTION ] == NULL )
266+ return - EINVAL ;
267+ len = sizeof (u8 );
268+ break ;
254269 case NFT_CT_SRC :
255270 case NFT_CT_DST :
271+ if (tb [NFTA_CT_DIRECTION ] == NULL )
272+ return - EINVAL ;
273+
274+ switch (ctx -> afi -> family ) {
275+ case NFPROTO_IPV4 :
276+ len = FIELD_SIZEOF (struct nf_conntrack_tuple ,
277+ src .u3 .ip );
278+ break ;
279+ case NFPROTO_IPV6 :
280+ case NFPROTO_INET :
281+ len = FIELD_SIZEOF (struct nf_conntrack_tuple ,
282+ src .u3 .ip6 );
283+ break ;
284+ default :
285+ return - EAFNOSUPPORT ;
286+ }
287+ break ;
256288 case NFT_CT_PROTO_SRC :
257289 case NFT_CT_PROTO_DST :
258290 if (tb [NFTA_CT_DIRECTION ] == NULL )
259291 return - EINVAL ;
292+ len = FIELD_SIZEOF (struct nf_conntrack_tuple , src .u .all );
260293 break ;
261294 default :
262295 return - EOPNOTSUPP ;
@@ -278,7 +311,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
278311 if (err < 0 )
279312 return err ;
280313
281- err = nft_validate_data_load (ctx , priv -> dreg , NULL , NFT_DATA_VALUE );
314+ err = nft_validate_data_load (ctx , priv -> dreg , NULL ,
315+ NFT_DATA_VALUE , len );
282316 if (err < 0 )
283317 return err ;
284318
0 commit comments