Page MenuHomeFreeBSD

ifnet_byindex() actually requires network epoch
ClosedPublic

Authored by glebius on Dec 4 2021, 9:16 PM.
Tags
None
Referenced Files
F83718039: D33263.diff
Mon, May 13, 11:06 PM
Unknown Object (File)
Tue, May 7, 9:07 AM
Unknown Object (File)
Sun, May 5, 9:51 PM
Unknown Object (File)
Fri, Apr 26, 6:13 PM
Unknown Object (File)
Thu, Apr 25, 9:51 PM
Unknown Object (File)
Wed, Apr 17, 5:29 AM
Unknown Object (File)
Wed, Apr 17, 4:19 AM
Unknown Object (File)
Feb 19 2024, 2:43 AM
Subscribers

Details

Summary

Sweep over potentially unsafe calls to ifnet_byindex() and wrap them
in epoch. Most of the code touched remains unsafe, as the returned
pointer is being used after epoch exit. Mark that with a comment.

Validate the index argument inside the function, reducing argument
validation requirement from the callers and making V_if_index
private to if.c.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 43142
Build 40030: arc lint + arc unit

Event Timeline

melifaro added inline comments.
sys/net/if.c
346

Worth considering using uint (or even uint32_t) as an index identifier.
It'll allow to avoid unnecessary (idx < 0 checks).

sys/netinet/igmp.c
512

Maybe worth moving it to out_locked: , so the future readers won't have to check whether ifp is indeed not used below?

sys/netinet6/mld6.c
359

Worth removing?

sys/netinet6/scope6.c
377

What do you think of having an explicit

bool ifnet_checkindex(unit idx)
{
  struct epoch_tracket et;

  NET_EPOCH_ENTER(et);
  bool result = ifnet_byindex(idx) != NULL;
  NET_EPOCH_EXIT(et);
}

?

sys/net/if.c
346

ifp->if_index is an unsigned int, so it makes sense to also use that here.

(As an aside, struct in6_defrouter and struct in6_prefix have it as a u_short, and probably need to be fixed. That might be painful, as they're shared with user space.)

glebius added inline comments.
sys/netinet/igmp.c
512

Not sure. SYSCTL_OUT() potentially may sleep. It won't sleep in this function, since we wire the buffer. But that may change. Anyway this function has its own problems, like unlocked access to the igi_head. I'd better not include improvements to particular protocols into this sweeping ifnet_byindex() KPI change.

sys/netinet6/scope6.c
377

Don't know much about IPv6. Would it be correct to set sin6_scope_id to non-existent index, freed a moment ago? Cause this can happen now. If this needs to be fixed, then once it is fixed, such function ifnet_checkindex() would be not used.

This revision was not accepted when it landed; it landed in state Needs Review.Dec 6 2021, 5:33 PM
This revision was automatically updated to reflect the committed changes.