@@ -1438,7 +1438,24 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
14381438 demand-load a protocol. */
14391439 opterr = 0 ;
14401440
1441- iptables_globals .opts = iptables_globals .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+ }
14421459 while ((cs .c = getopt_long (argc , argv ,
14431460 "-: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" ,
14441461 iptables_globals .opts ?: iptables_globals .orig_opts , NULL )) != -1 ) {
@@ -2016,5 +2033,11 @@ int do_command6(int argc, char *argv[], char **table, void **handle)
20162033 free (dmasks );
20172034 xtables_free_opts (1 );
20182035
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+
20192042 return ret ;
20202043}
0 commit comments