Skip to content

Commit 50c2f14

Browse files
committed
...
1 parent aa2603e commit 50c2f14

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

ipthelper/xshared.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ int command_default(struct iptables_command_state *cs,
248248
m->x6_options,
249249
&m->option_offset);
250250
else
251-
gl->opts = xtables_merge_options(gl->orig_opts,
251+
gl->opts = xs_merge_options(gl->orig_opts,
252252
gl->opts,
253253
m->extra_opts,
254254
&m->option_offset);
@@ -659,7 +659,7 @@ void command_match(struct iptables_command_state *cs)
659659
opts = xtables_options_xfrm(xt_params->orig_opts, opts,
660660
m->x6_options, &m->option_offset);
661661
} else if (m->extra_opts != NULL) {
662-
opts = xtables_merge_options(xt_params->orig_opts, opts,
662+
opts = xs_merge_options(xt_params->orig_opts, opts,
663663
m->extra_opts, &m->option_offset);
664664

665665
} else
@@ -731,7 +731,7 @@ void command_jump(struct iptables_command_state *cs)
731731
cs->target->x6_options,
732732
&cs->target->option_offset);
733733
} else if (cs->target->extra_opts != NULL)
734-
opts = xtables_merge_options(xt_params->orig_opts, opts,
734+
opts = xs_merge_options(xt_params->orig_opts, opts,
735735
cs->target->extra_opts,
736736
&cs->target->option_offset);
737737
else

ipthelper/xshared.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,5 +179,9 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
179179
void command_match(struct iptables_command_state *cs);
180180
const char *xt_parse_target(const char *targetname);
181181
void command_jump(struct iptables_command_state *cs);
182+
struct option *xs_merge_options(struct option *orig_opts,
183+
struct option *oldopts,
184+
const struct option *newopts,
185+
unsigned int *option_offset);
182186

183187
#endif /* IPTABLES_XSHARED_H */

ipthelper/xtoptions.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,76 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
120120
memcpy(mp, oldopts, sizeof(*mp) * num_old);
121121
mp += num_old;
122122
}
123-
xtables_free_opts(0);
123+
if (xt_params->opts != NULL && xt_params->opts != xt_params->orig_opts)
124+
xtables_free_opts(0);
124125

125126
/* Clear trailing entry */
126127
memset(mp, 0, sizeof(*mp));
127128
return merge;
128129
}
129130

131+
struct option *
132+
xs_merge_options(struct option *orig_opts, struct option *oldopts,
133+
const struct option *newopts, unsigned int *option_offset)
134+
{
135+
unsigned int num_orig = 0, num_old = 0, num_new = 0, i;
136+
struct option *merge;
137+
struct option *mp;
138+
struct option *old_base = oldopts;
139+
140+
if (newopts == NULL || newopts->name == NULL)
141+
return oldopts;
142+
143+
if (orig_opts != NULL)
144+
for (; orig_opts[num_orig].name != NULL; ++num_orig)
145+
;
146+
147+
if (oldopts != NULL)
148+
for (; oldopts[num_old].name != NULL; ++num_old)
149+
;
150+
151+
for (; newopts[num_new].name != NULL; ++num_new)
152+
;
153+
154+
if (oldopts != NULL && num_old >= num_orig) {
155+
oldopts += num_orig;
156+
num_old -= num_orig;
157+
} else {
158+
oldopts = NULL;
159+
num_old = 0;
160+
}
161+
162+
merge = malloc(sizeof(*merge) * (num_orig + num_new + num_old + 1));
163+
if (merge == NULL)
164+
return NULL;
165+
166+
if (num_orig != 0)
167+
memcpy(merge, orig_opts, sizeof(*merge) * num_orig);
168+
mp = merge + num_orig;
169+
170+
xt_params->option_offset += XT_OPTION_OFFSET_SCALE;
171+
*option_offset = xt_params->option_offset;
172+
173+
for (i = 0; i < num_new; ++i, ++mp) {
174+
mp->name = newopts[i].name;
175+
mp->has_arg = newopts[i].has_arg;
176+
mp->flag = newopts[i].flag;
177+
mp->val = newopts[i].val + *option_offset;
178+
}
179+
180+
if (oldopts != NULL && num_old != 0) {
181+
memcpy(mp, oldopts, sizeof(*mp) * num_old);
182+
mp += num_old;
183+
}
184+
185+
memset(mp, 0, sizeof(*mp));
186+
187+
if (old_base != NULL && old_base != orig_opts && old_base != xt_params->orig_opts)
188+
free(old_base);
189+
190+
return merge;
191+
}
192+
130193
/**
131194
* Give the upper limit for a certain type.
132195
*/

0 commit comments

Comments
 (0)