Page MenuHomeFreeBSD

capsicum: Limit socket operations in capability mode
ClosedPublic

Authored by markj on Mar 25 2021, 4:57 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Mar 18, 11:44 PM
Unknown Object (File)
Dec 23 2023, 12:21 AM
Unknown Object (File)
Dec 12 2023, 5:43 PM
Unknown Object (File)
Dec 4 2023, 5:22 PM
Unknown Object (File)
Nov 29 2023, 7:25 AM
Unknown Object (File)
Nov 28 2023, 4:28 AM
Unknown Object (File)
Nov 14 2023, 8:25 PM
Unknown Object (File)
Nov 11 2023, 12:03 AM

Details

Summary

Plain socket(2) is permitted in capability mode. The reasoning seems to
be that unconnected, unbound sockets do not represent capabilities.
However, this is false is a few cases:

  • raw sockets can be used to receive data without being connected
  • routing sockets are automatically connected and provide access to routing tables
  • network interfaces are configured with ioctl() on a socket of any type

The system's interface list and routing tables are global namespaces
that should not be accessible to processes in capability mode, even if
they are privileged.

This change plugs these holes. In particular, protocols must now opt in
to allowing creation of a socket in capability mode. This is signaled
by setting PR_CAPATTACH in the protocol switch. Local and internet
sockets are permitted. The former because one may legitimately create
and bind a local socket to a relative path using bindat(2). The latter
because some existing code (e.g., capsicum tests) depends on this
ability.

ioctl() is handled by disallowing calls to ifioctl(), in_control() and
in6_control() from capability model. It may be useful at some point to
enable specific ioctls like we do for sysctls. Some testing with
capsicumized programs in the base system hasn't yet revealed any such
ioctls.

Test Plan
  • capsicum test suite
  • manual testing of some sandboxed programs, including dhclient, tcpdump and rtsold

Diff Detail

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

Event Timeline

markj requested review of this revision.Mar 25 2021, 4:57 PM
markj added a reviewer: capsicum.

@arichardson has done a bunch of recent work on capsicum-test, so CC for "... internet sockets are permitted ... because some existing code (e.g., capsicum tests) depends on this ability."

If this is only supported for the sake of tests (i.e., there is no actual use case for creating a PF_INET socket in a real capability mode sandbox) I'd rather we change the test.

@arichardson has done a bunch of recent work on capsicum-test, so CC for "... internet sockets are permitted ... because some existing code (e.g., capsicum tests) depends on this ability."

If this is only supported for the sake of tests (i.e., there is no actual use case for creating a PF_INET socket in a real capability mode sandbox) I'd rather we change the test.

I'm kind of on the fence about it. I don't think it creates much additional attack surface, and if it does, it could well be an issue regardless of whether socket creation is permitted or not. My reasoning is basically that unconnected, unbound PF_INET sockets shouldn't really represent capabilities. And the fact that software in the base system is affected gives me pause, even though so far it's just the test suite, so I took a more conservative approach.

Ping? I would like to commit this early next week if possible.

Some minor notes.
Thank you for working on this.

sys/kern/uipc_socket.c
530

Shouldn't we do this check as early as we can?

531

Should we return ECAPMODE ?

sys/net/if.c
2978

ECAPMODE?

sys/netinet/in.c
241

Shouldn't w do this check eariler?

markj marked 2 inline comments as done.

ENOTCAPABLE -> ECAPMODE

Sorry, uploaded a diff but didn't submit comments. :(

sys/kern/uipc_socket.c
530

I can reorder this with the preceding check, but that's it. Why is that preferable? Is to try and avoid providing information about protocol support in the kernel?

531

Oh, probably. I forgot about ECAPMODE.

sys/netinet/in.c
241

Assuming you mean reordering with the ifp == NULL check, sure, but again I don't really understand why.

LGTM.
I prefer this approach then forbidding whole socket syscall.

This revision is now accepted and ready to land.Apr 6 2021, 8:20 AM

This broke dhcpcd >_< We need some way of having a network configuration capability, not necessarily per-interface, but at least just some flag like SOCK_CONFIG (that can be only set on creation, outside of capability mode) that would allow ifioctls to work.

In D29423#671394, @greg_unrelenting.technology wrote:

This broke dhcpcd >_< We need some way of having a network configuration capability, not necessarily per-interface, but at least just some flag like SOCK_CONFIG (that can be only set on creation, outside of capability mode) that would allow ifioctls to work.

Ok, I will revert part of the change for now I think. rtsold has a similar problem, but that is much easier to patch.

It looks like dhcpcd uses a global socket for all network configuration ioctls. I was thinking of using __specialfd to create a new kind of descriptor which permits network ioctls, but scoped to a specific interface.

One mitigation which I think doesn't require changes to dhcpcd would be to disallow network ioctls on sockets created by a process that has entered capability mode.

One mitigation which I think doesn't require changes to dhcpcd would be to disallow network ioctls on sockets created by a process that has entered capability mode.

This approach seems to work at least for basic usages of dhcpcd. Anyway, I will commit the revert shortly. Sorry for the breakage.