From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: cocci@inria.fr
Cc: keescook@chromium.org
Subject: [cocci] "reachable by inconsistent control-flow paths"
Date: Sun, 9 Oct 2022 09:03:36 -0600 [thread overview]
Message-ID: <Y0LiyBxZ0pU+NOPR@zx2c4.com> (raw)
Hi,
I've got a fairly simple rule that works on easy contrived examples:
@@
identifier get_random_u32 =~ "get_random_int|prandom_u32|get_random_u32";
typedef u16;
identifier v;
@@
u16 v;
... when exists
- v = get_random_u32();
+ v = get_random_u16();
However, when I try to apply it to a real function, afixed below, I get
the error:
rule starting on line 1: node 172: off = ... ;[1,2,67,68,70] in nf_nat_l4proto_unique_tuple reachable by inconsistent control-flow paths
I tried using the option "--allow-inconsistent-paths", and it works, but
that also seems potentially scary. I figure if it's not on by default,
it must be for a good reason. Any idea what's up here?
Thanks,
Jason
---------------------------------------------------------------------
static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
const struct nf_nat_range2 *range,
enum nf_nat_manip_type maniptype,
const struct nf_conn *ct)
{
unsigned int range_size, min, max, i, attempts;
__be16 *keyptr;
u16 off;
static const unsigned int max_attempts = 128;
switch (tuple->dst.protonum) {
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
/* id is same for either direction... */
keyptr = &tuple->src.u.icmp.id;
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
min = 0;
range_size = 65536;
} else {
min = ntohs(range->min_proto.icmp.id);
range_size = ntohs(range->max_proto.icmp.id) -
ntohs(range->min_proto.icmp.id) + 1;
}
goto find_free_id;
#if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE)
case IPPROTO_GRE:
/* If there is no master conntrack we are not PPTP,
do not change tuples */
if (!ct->master)
return;
if (maniptype == NF_NAT_MANIP_SRC)
keyptr = &tuple->src.u.gre.key;
else
keyptr = &tuple->dst.u.gre.key;
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
min = 1;
range_size = 65535;
} else {
min = ntohs(range->min_proto.gre.key);
range_size = ntohs(range->max_proto.gre.key) - min + 1;
}
goto find_free_id;
#endif
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
if (maniptype == NF_NAT_MANIP_SRC)
keyptr = &tuple->src.u.all;
else
keyptr = &tuple->dst.u.all;
break;
default:
return;
}
/* If no range specified... */
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
/* If it's dst rewrite, can't change port */
if (maniptype == NF_NAT_MANIP_DST)
return;
if (ntohs(*keyptr) < 1024) {
/* Loose convention: >> 512 is credential passing */
if (ntohs(*keyptr) < 512) {
min = 1;
range_size = 511 - min + 1;
} else {
min = 600;
range_size = 1023 - min + 1;
}
} else {
min = 1024;
range_size = 65535 - 1024 + 1;
}
} else {
min = ntohs(range->min_proto.all);
max = ntohs(range->max_proto.all);
if (unlikely(max < min))
swap(max, min);
range_size = max - min + 1;
}
find_free_id:
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
off = (ntohs(*keyptr) - ntohs(range->base_proto.all));
else
off = prandom_u32();
attempts = range_size;
if (attempts > max_attempts)
attempts = max_attempts;
/* We are in softirq; doing a search of the entire range risks
* soft lockup when all tuples are already used.
*
* If we can't find any free port from first offset, pick a new
* one and try again, with ever smaller search window.
*/
another_round:
for (i = 0; i < attempts; i++, off++) {
*keyptr = htons(min + off % range_size);
if (!nf_nat_used_tuple(tuple, ct))
return;
}
if (attempts >= range_size || attempts < 16)
return;
attempts /= 2;
off = prandom_u32();
goto another_round;
}
next reply other threads:[~2022-10-09 15:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-09 15:03 Jason A. Donenfeld [this message]
2022-10-09 15:15 ` [cocci] "reachable by inconsistent control-flow paths" Julia Lawall
2022-10-09 15:17 ` Jason A. Donenfeld
2022-10-09 15:22 ` Jason A. Donenfeld
2022-10-09 15:26 ` Jason A. Donenfeld
2022-10-09 15:30 ` Julia Lawall
2022-10-09 15:53 ` Jason A. Donenfeld
2022-10-09 17:00 ` [cocci] Replacement of random functions for Linux Markus Elfring
2022-10-10 16:18 ` Jason A. Donenfeld
2022-10-10 17:45 ` Markus Elfring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y0LiyBxZ0pU+NOPR@zx2c4.com \
--to=jason@zx2c4.com \
--cc=cocci@inria.fr \
--cc=keescook@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).