@@ -151,6 +151,21 @@ static struct option original_opts[] = {
151151};
152152
153153extern struct xtables_globals iptables_globals ;
154+
155+ static struct option * clone_original_options (const struct option * orig )
156+ {
157+ size_t count = 0 ;
158+
159+ while (orig [count ].name != NULL )
160+ count ++ ;
161+ count ++ ;
162+
163+ struct option * copy = xtables_calloc (count , sizeof (* copy ));
164+ memcpy (copy , orig , count * sizeof (* copy ));
165+ copy [count - 1 ] = (struct option ){0 };
166+
167+ return copy ;
168+ }
154169
155170/* Table of legal combinations of commands and options. If any of the
156171 * given commands make an option legal, that option is legal (applies to
@@ -1423,6 +1438,8 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
14231438 /* re-set optind to 0 in case do_command6 gets called
14241439 * a second time */
14251440 optind = 0 ;
1441+ iptables_globals .option_offset = 0 ;
1442+ iptables_globals .orig_opts = original_opts ;
14261443
14271444 /* clear mflags in case do_command6 gets called a second time
14281445 * (we clear the global list of all matches for security)*/
@@ -1438,22 +1455,7 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
14381455 demand-load a protocol. */
14391456 opterr = 0 ;
14401457
1441- /* Create a malloc'd copy of orig_opts */
1442- size_t num_opts = 0 ;
1443- struct option * orig_opts = iptables_globals .orig_opts ;
1444-
1445- /* Count the number of options (including the NULL terminator) */
1446- while (orig_opts [num_opts ].name != NULL ) {
1447- num_opts ++ ;
1448- }
1449- num_opts ++ ; /* Include the NULL terminator */
1450-
1451- /* Allocate memory and copy the options */
1452- iptables_globals .opts = malloc (num_opts * sizeof (struct option ));
1453- if (iptables_globals .opts == NULL ) {
1454- xtables_error (OTHER_PROBLEM , "malloc failed for options array" );
1455- }
1456- memcpy (iptables_globals .opts , iptables_globals .orig_opts , num_opts * sizeof (struct option ));
1458+ iptables_globals .opts = clone_original_options (iptables_globals .orig_opts );
14571459
14581460 while ((cs .c = getopt_long (argc , argv ,
14591461 "-: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" ,
@@ -2032,11 +2034,5 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
20322034 free (dmasks );
20332035 xtables_free_opts (1 );
20342036
2035- /* Free the malloc'd copy of opts if it was allocated */
2036- if (iptables_globals .opts != iptables_globals .orig_opts ) {
2037- free (iptables_globals .opts );
2038- iptables_globals .opts = NULL ;
2039- }
2040-
20412037 return ret ;
20422038}
0 commit comments