@@ -1213,6 +1213,18 @@ static int do_add_counters(struct net *net, const void __user *user,
12131213}
12141214
12151215#ifdef CONFIG_COMPAT
1216+ struct compat_arpt_replace {
1217+ char name [XT_TABLE_MAXNAMELEN ];
1218+ u32 valid_hooks ;
1219+ u32 num_entries ;
1220+ u32 size ;
1221+ u32 hook_entry [NF_ARP_NUMHOOKS ];
1222+ u32 underflow [NF_ARP_NUMHOOKS ];
1223+ u32 num_counters ;
1224+ compat_uptr_t counters ;
1225+ struct compat_arpt_entry entries [0 ];
1226+ };
1227+
12161228static inline void compat_release_entry (struct compat_arpt_entry * e )
12171229{
12181230 struct xt_entry_target * t ;
@@ -1228,8 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
12281240 const unsigned char * base ,
12291241 const unsigned char * limit ,
12301242 const unsigned int * hook_entries ,
1231- const unsigned int * underflows ,
1232- const char * name )
1243+ const unsigned int * underflows )
12331244{
12341245 struct xt_entry_target * t ;
12351246 struct xt_target * target ;
@@ -1300,7 +1311,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
13001311
13011312static int
13021313compat_copy_entry_from_user (struct compat_arpt_entry * e , void * * dstptr ,
1303- unsigned int * size , const char * name ,
1314+ unsigned int * size ,
13041315 struct xt_table_info * newinfo , unsigned char * base )
13051316{
13061317 struct xt_entry_target * t ;
@@ -1333,14 +1344,9 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
13331344 return ret ;
13341345}
13351346
1336- static int translate_compat_table (const char * name ,
1337- unsigned int valid_hooks ,
1338- struct xt_table_info * * pinfo ,
1347+ static int translate_compat_table (struct xt_table_info * * pinfo ,
13391348 void * * pentry0 ,
1340- unsigned int total_size ,
1341- unsigned int number ,
1342- unsigned int * hook_entries ,
1343- unsigned int * underflows )
1349+ const struct compat_arpt_replace * compatr )
13441350{
13451351 unsigned int i , j ;
13461352 struct xt_table_info * newinfo , * info ;
@@ -1352,8 +1358,8 @@ static int translate_compat_table(const char *name,
13521358
13531359 info = * pinfo ;
13541360 entry0 = * pentry0 ;
1355- size = total_size ;
1356- info -> number = number ;
1361+ size = compatr -> size ;
1362+ info -> number = compatr -> num_entries ;
13571363
13581364 /* Init all hooks to impossible value. */
13591365 for (i = 0 ; i < NF_ARP_NUMHOOKS ; i ++ ) {
@@ -1364,40 +1370,39 @@ static int translate_compat_table(const char *name,
13641370 duprintf ("translate_compat_table: size %u\n" , info -> size );
13651371 j = 0 ;
13661372 xt_compat_lock (NFPROTO_ARP );
1367- xt_compat_init_offsets (NFPROTO_ARP , number );
1373+ xt_compat_init_offsets (NFPROTO_ARP , compatr -> num_entries );
13681374 /* Walk through entries, checking offsets. */
1369- xt_entry_foreach (iter0 , entry0 , total_size ) {
1375+ xt_entry_foreach (iter0 , entry0 , compatr -> size ) {
13701376 ret = check_compat_entry_size_and_hooks (iter0 , info , & size ,
13711377 entry0 ,
1372- entry0 + total_size ,
1373- hook_entries ,
1374- underflows ,
1375- name );
1378+ entry0 + compatr -> size ,
1379+ compatr -> hook_entry ,
1380+ compatr -> underflow );
13761381 if (ret != 0 )
13771382 goto out_unlock ;
13781383 ++ j ;
13791384 }
13801385
13811386 ret = - EINVAL ;
1382- if (j != number ) {
1387+ if (j != compatr -> num_entries ) {
13831388 duprintf ("translate_compat_table: %u not %u entries\n" ,
1384- j , number );
1389+ j , compatr -> num_entries );
13851390 goto out_unlock ;
13861391 }
13871392
13881393 /* Check hooks all assigned */
13891394 for (i = 0 ; i < NF_ARP_NUMHOOKS ; i ++ ) {
13901395 /* Only hooks which are valid */
1391- if (!(valid_hooks & (1 << i )))
1396+ if (!(compatr -> valid_hooks & (1 << i )))
13921397 continue ;
13931398 if (info -> hook_entry [i ] == 0xFFFFFFFF ) {
13941399 duprintf ("Invalid hook entry %u %u\n" ,
1395- i , hook_entries [i ]);
1400+ i , info -> hook_entry [i ]);
13961401 goto out_unlock ;
13971402 }
13981403 if (info -> underflow [i ] == 0xFFFFFFFF ) {
13991404 duprintf ("Invalid underflow %u %u\n" ,
1400- i , underflows [i ]);
1405+ i , info -> underflow [i ]);
14011406 goto out_unlock ;
14021407 }
14031408 }
@@ -1407,17 +1412,17 @@ static int translate_compat_table(const char *name,
14071412 if (!newinfo )
14081413 goto out_unlock ;
14091414
1410- newinfo -> number = number ;
1415+ newinfo -> number = compatr -> num_entries ;
14111416 for (i = 0 ; i < NF_ARP_NUMHOOKS ; i ++ ) {
14121417 newinfo -> hook_entry [i ] = info -> hook_entry [i ];
14131418 newinfo -> underflow [i ] = info -> underflow [i ];
14141419 }
14151420 entry1 = newinfo -> entries ;
14161421 pos = entry1 ;
1417- size = total_size ;
1418- xt_entry_foreach (iter0 , entry0 , total_size ) {
1422+ size = compatr -> size ;
1423+ xt_entry_foreach (iter0 , entry0 , compatr -> size ) {
14191424 ret = compat_copy_entry_from_user (iter0 , & pos , & size ,
1420- name , newinfo , entry1 );
1425+ newinfo , entry1 );
14211426 if (ret != 0 )
14221427 break ;
14231428 }
@@ -1427,7 +1432,7 @@ static int translate_compat_table(const char *name,
14271432 goto free_newinfo ;
14281433
14291434 ret = - ELOOP ;
1430- if (!mark_source_chains (newinfo , valid_hooks , entry1 ))
1435+ if (!mark_source_chains (newinfo , compatr -> valid_hooks , entry1 ))
14311436 goto free_newinfo ;
14321437
14331438 i = 0 ;
@@ -1438,7 +1443,7 @@ static int translate_compat_table(const char *name,
14381443 break ;
14391444 }
14401445
1441- ret = check_target (iter1 , name );
1446+ ret = check_target (iter1 , compatr -> name );
14421447 if (ret != 0 ) {
14431448 xt_percpu_counter_free (iter1 -> counters .pcnt );
14441449 break ;
@@ -1480,7 +1485,7 @@ static int translate_compat_table(const char *name,
14801485free_newinfo :
14811486 xt_free_table_info (newinfo );
14821487out :
1483- xt_entry_foreach (iter0 , entry0 , total_size ) {
1488+ xt_entry_foreach (iter0 , entry0 , compatr -> size ) {
14841489 if (j -- == 0 )
14851490 break ;
14861491 compat_release_entry (iter0 );
@@ -1492,18 +1497,6 @@ static int translate_compat_table(const char *name,
14921497 goto out ;
14931498}
14941499
1495- struct compat_arpt_replace {
1496- char name [XT_TABLE_MAXNAMELEN ];
1497- u32 valid_hooks ;
1498- u32 num_entries ;
1499- u32 size ;
1500- u32 hook_entry [NF_ARP_NUMHOOKS ];
1501- u32 underflow [NF_ARP_NUMHOOKS ];
1502- u32 num_counters ;
1503- compat_uptr_t counters ;
1504- struct compat_arpt_entry entries [0 ];
1505- };
1506-
15071500static int compat_do_replace (struct net * net , void __user * user ,
15081501 unsigned int len )
15091502{
@@ -1536,10 +1529,7 @@ static int compat_do_replace(struct net *net, void __user *user,
15361529 goto free_newinfo ;
15371530 }
15381531
1539- ret = translate_compat_table (tmp .name , tmp .valid_hooks ,
1540- & newinfo , & loc_cpu_entry , tmp .size ,
1541- tmp .num_entries , tmp .hook_entry ,
1542- tmp .underflow );
1532+ ret = translate_compat_table (& newinfo , & loc_cpu_entry , & tmp );
15431533 if (ret != 0 )
15441534 goto free_newinfo ;
15451535
0 commit comments