Thread (4 messages) flat view 4 messages, 2 authors, 2021-09-17

Re: [PATCH net v4] net: netfilter: Fix port selection of FTP for NF_NAT_RANGE_PROTO_SPECIFIED

From: Cole Dishington <hidden>
Date: 2021-09-16 20:30:52
Also in: lkml, netfilter-devel

On Thu, 2021-09-16 at 13:26 +0200, Florian Westphal wrote:
Cole Dishington [off-list ref] wrote:
quoted
+	/* Avoid applying nat->range to the reply direction */
+	if (!exp->dir || !nat->range_info.min_proto.all || !nat-
quoted
range_info.max_proto.all) {
+		min = ntohs(exp->saved_proto.tcp.port);
+		range_size = 65535 - min + 1;
+	} else {
+		min = ntohs(nat->range_info.min_proto.all);
+		range_size = ntohs(nat->range_info.max_proto.all) - min
+ 1;
+	}
+
 	/* Try to get same port: if not, try to change it. */
-	for (port = ntohs(exp->saved_proto.tcp.port); port != 0;
port++) {
-		int ret;
+	first_port = ntohs(exp->saved_proto.tcp.port);
+	if (min > first_port || first_port > (min + range_size - 1))
+		first_port = min;
 
+	for (i = 0, port = first_port; i < range_size; i++, port =
(port - first_port + i) % range_size) {
This looks complicated.  As far as I understand, this could instead
be
written like this (not even compile tested):

	/* Avoid applying nat->range to the reply direction */
	if (!exp->dir || !nat->range_info.min_proto.all || !nat-
quoted
range_info.max_proto.all) {
		min = 1;
		max = 65535;
		range_size = 65535;
	} else {
		min = ntohs(nat->range_info.min_proto.all);
		max = ntohs(nat->range_info.max_proto.all);
		range_size = max - min + 1;
	}
The original code defined the range as [ntohs(exp->saved_proto.tcp.port), 65535]. The above would
cause a change in behaviour, should we try to avoid it?
  	/* Try to get same port: if not, try to change it. */
	port = ntohs(exp->saved_proto.tcp.port);

	if (port < min || port > max)
		port = min;

	for (i = 0; i < range_size; i++) {
  		exp->tuple.dst.u.tcp.port = htons(port);
  		ret = nf_ct_expect_related(exp, 0);
		if (ret != -EBUSY)
 			break;
		port++;
		if (port > max)
			port = min;
  	}

	if (ret != 0) {
	...

AFAICS this is the same, we loop at most range_size times,
in case range_size is 64k, we will loop through all (hmmm,
not good actually, but better make that a different change)
else through given min - max range.

If orig port was in-range, we try it first, then increment.
If port exceeds upper bound, cycle back to min.

What do you think?
Looks good, just the one question above.

Thanks for your time reviewing!
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help