Skip to content

Commit

Permalink
conntrack: Fix FTP seq_skew boundary adjustments.
Browse files Browse the repository at this point in the history
At the same time, splice out a function and also rely on the compiler
for overflow/underflow handling.

Found by inspection.

Fixes: bd5e81a ("Userspace Datapath: Add ALG infra and FTP.")
Signed-off-by: Darrell Ball <dlu998@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
darball1 authored and blp committed Jan 19, 2019
1 parent 043b81a commit ac9811f
Showing 1 changed file with 10 additions and 28 deletions.
38 changes: 10 additions & 28 deletions lib/conntrack.c
Expand Up @@ -3173,6 +3173,13 @@ repl_ftp_v6_addr(struct dp_packet *pkt, struct ct_addr v6_addr_rep,
return overall_delta;
}

/* Increment/decrement a TCP sequence number. */
static void
adj_seqnum(ovs_16aligned_be32 *val, int32_t inc)
{
put_16aligned_be32(val, htonl(ntohl(get_16aligned_be32(val)) + inc));
}

static void
handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
struct dp_packet *pkt, const struct conn *ec, long long now,
Expand Down Expand Up @@ -3247,34 +3254,9 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
struct tcp_header *th = dp_packet_l4(pkt);

if (nat && ec->seq_skew != 0) {
if (ctx->reply != ec->seq_skew_dir) {

uint32_t tcp_ack = ntohl(get_16aligned_be32(&th->tcp_ack));

if ((ec->seq_skew > 0) && (tcp_ack < ec->seq_skew)) {
/* Should not be possible; will be marked invalid. */
tcp_ack = 0;
} else if ((ec->seq_skew < 0) &&
(UINT32_MAX - tcp_ack < -ec->seq_skew)) {
tcp_ack = (-ec->seq_skew) - (UINT32_MAX - tcp_ack);
} else {
tcp_ack -= ec->seq_skew;
}
ovs_be32 new_tcp_ack = htonl(tcp_ack);
put_16aligned_be32(&th->tcp_ack, new_tcp_ack);
} else {
uint32_t tcp_seq = ntohl(get_16aligned_be32(&th->tcp_seq));
if ((ec->seq_skew > 0) && (UINT32_MAX - tcp_seq < ec->seq_skew)) {
tcp_seq = ec->seq_skew - (UINT32_MAX - tcp_seq);
} else if ((ec->seq_skew < 0) && (tcp_seq < -ec->seq_skew)) {
/* Should not be possible; will be marked invalid. */
tcp_seq = 0;
} else {
tcp_seq += ec->seq_skew;
}
ovs_be32 new_tcp_seq = htonl(tcp_seq);
put_16aligned_be32(&th->tcp_seq, new_tcp_seq);
}
ctx->reply != ec->seq_skew_dir ?
adj_seqnum(&th->tcp_ack, -ec->seq_skew) :
adj_seqnum(&th->tcp_seq, ec->seq_skew);
}

th->tcp_csum = 0;
Expand Down

0 comments on commit ac9811f

Please sign in to comment.