Page MenuHomeFreeBSD

inpcb: relax recently added assertion
Needs ReviewPublic

Authored by glebius on Thu, Aug 27, 4:16 PM.
Tags
None
Referenced Files
F169265691: D59225.id.diff
Tue, Sep 1, 2:28 AM
F169252699: D59225.diff
Tue, Sep 1, 1:46 AM
Unknown Object (File)
Mon, Aug 31, 10:13 AM
Unknown Object (File)
Mon, Aug 31, 6:13 AM
Unknown Object (File)
Sun, Aug 30, 3:47 AM
Unknown Object (File)
Sun, Aug 30, 3:30 AM
Unknown Object (File)
Sun, Aug 30, 12:06 AM
Unknown Object (File)
Sat, Aug 29, 11:27 PM
Subscribers

Details

Reviewers
pouria
jamie
bz
markj
Group Reviewers
network
Summary

XXX: this is not a final commit message, but a discussion starter for
phabricator!

The 1dda8ba77a20 did not change the storage logic of inpcbs, but added a
few assertions that were not there before. The assertion in human language
would be: if an inpcb was not found in the exact hash and it doesn't have
INP_UNCONNECTED flag set, then it must be present in the wildcard hash.
However, this assertion can not be checked with existing lookup functions
for certain edge case:

Here is the failing scenario:

struct in_addr addrs[] = { { FIRST }, { SECOND }, };
struct jail jconf = {
        .version = JAIL_API_VERSION,
        .path = __DECONST(char *, "/"),
        .hostname = __DECONST(char *,"test"),
        .ip4s = nitems(addrs),
        .ip4 = addrs,
};
struct sockaddr_in sin = { .sin_family = AF_INET };
socklen_t slen = sizeof(sin);
int s;

ATF_REQUIRE(jail(&jconf) > 0);
ATF_REQUIRE((s = socket(PF_INET, SOCK_DGRAM, 0)) > 0);
ATF_REQUIRE(bind(s, (struct sockaddr *)&sin, sizeof(sin)) == 0);
ATF_REQUIRE(getsockname(s, (struct sockaddr *)&sin, &slen) == 0);

/*

  • Note that jailed address reports self as INADDR_ANY! However on
  • input it won't catch any destinations, only FIRST and SECOND.
	 */
        ATF_REQUIRE_MSG(sin.sin_addr.s_addr == INADDR_ANY && sin.sin_port != 0,
            "jailed unconnected socket name %s:%u", inet_ntoa(sin.sin_addr),
            ntohs(sin.sin_port));

/*

  • This connect(2) will panic in MPASS(i).
	 */
        sin.sin_addr.s_addr = REMOTE;
        sin.sin_port = htons(6666);
        ATF_REQUIRE(connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0);

Other options that I see:

  1. Remove assertions completely.
  2. Add a more relaxed wildcard lookup function for INVARIANTS use.
  3. Use different laddr for lookup:

if (inp->inp_laddr == htonl(INADDR_ANY) &&

	    prison_flag(inp->inp_cred, PR_IP4))
		prison_get_ip4(inp->inp_cred, &laddr);

else

		laddr = inp->inp_laddr;

i = in_pcblookup_wild_locked(ipictx.pcbinfo,

	    laddr, inp->inp_lport, RT_ALL_FIBS, &ipictx.wbucket);

MPASS(i);

  1. Your idea?

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76220
Build 73103: arc lint + arc unit