@@ -216,7 +216,6 @@ static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
216216 0 ,
217217};
218218
219- #define opts iptables_globals.opts
220219#define prog_name iptables_globals.program_name
221220#define prog_vers iptables_globals.program_version
222221/* A few hardcoded protocols for 'all' and in case the user has no
@@ -1439,10 +1438,27 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
14391438 demand-load a protocol. */
14401439 opterr = 0 ;
14411440
1442- opts = xt_params -> orig_opts ;
1441+ /* Create a malloc'd copy of orig_opts */
1442+ if (iptables_globals .opts == NULL ) {
1443+ size_t num_opts = 0 ;
1444+ struct option * orig_opts = iptables_globals .orig_opts ;
1445+
1446+ /* Count the number of options (including the NULL terminator) */
1447+ while (orig_opts [num_opts ].name != NULL ) {
1448+ num_opts ++ ;
1449+ }
1450+ num_opts ++ ; /* Include the NULL terminator */
1451+
1452+ /* Allocate memory and copy the options */
1453+ iptables_globals .opts = malloc (num_opts * sizeof (struct option ));
1454+ if (iptables_globals .opts == NULL ) {
1455+ xtables_error (OTHER_PROBLEM , "malloc failed for options array" );
1456+ }
1457+ memcpy (iptables_globals .opts , iptables_globals .orig_opts , num_opts * sizeof (struct option ));
1458+ }
14431459 while ((cs .c = getopt_long (argc , argv ,
14441460 "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:g:46" ,
1445- opts , NULL )) != -1 ) {
1461+ iptables_globals . opts ?: iptables_globals . orig_opts , NULL )) != -1 ) {
14461462 switch (cs .c ) {
14471463 /*
14481464 * Command selection
@@ -2017,5 +2033,11 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
20172033 free (dmasks );
20182034 xtables_free_opts (1 );
20192035
2036+ /* Free the malloc'd copy of opts if it was allocated */
2037+ if (iptables_globals .opts != iptables_globals .orig_opts ) {
2038+ free (iptables_globals .opts );
2039+ iptables_globals .opts = NULL ;
2040+ }
2041+
20202042 return ret ;
20212043}
0 commit comments