platform_bionic/libc/bionic/bind.cpp
Bram Bonné 95ca52a7d6 Reland: Soft-enable MAC address restrictions with allowlist.
Soft-limits apps from calling bind() on NETLINK_ROUTE sockets, and
getting link info through getifaddrs(), while still allowing apps on the
allowlist to temporarily perform these actions.

This is different from existing behavior, where apps targeting an API
level < 30 were exempted from this restriction.

Actual enforcement will happen through SELinux (as is currently the
case for apps targeting API >= 30). This temporary change will then be
reverted.

If you arrived at this change due to an app showing unexpected behavior,
please file a bug at go/netlink-bug.

Bug: 170188668
Bug: 170214442
Test: Call bind() on NETLINK_ROUTE for an app on the allowlist.
Test: Call bind() on NETLINK_ROUTE for an app not on the allowlist.
Test: Call getifaddrs() for an app on the allowlist.
Test: Call getifaddrs() for an app not on the allowlist.
Test: Call bind() on a AF_UNIX socket with its protocol set to
NETLINK_ROUTE, confirm it can succeed.
Test: Verify that previously broken apps are no longer broken.

Change-Id: I8738f7912fdc816e0d30205557728ff9e84bf7e6
2020-12-15 16:52:58 +01:00

65 lines
2.9 KiB
C++

/*
* Copyright (C) 2020 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
// b/170214442: Intercept bind calls on NETLINK_ROUTE sockets.
// This entire file will be reverted before release.
#include <async_safe/log.h>
#include <errno.h>
#include <linux/rtnetlink.h>
#include <string.h>
#include <sys/socket.h>
#include "bionic_appcompat.h"
extern "C" int __bind(int fd, const struct sockaddr* addr, socklen_t addr_length);
int bind(int fd, const struct sockaddr* addr, socklen_t addr_length) {
if (should_apply_soft_mac_bind_restrictions()) {
int sock_domain, sock_protocol;
socklen_t sock_domain_length = sizeof(sock_domain);
socklen_t sock_protocol_length = sizeof(sock_protocol);
if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &sock_domain, &sock_domain_length) < 0 ||
getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &sock_protocol, &sock_protocol_length) < 0) {
async_safe_format_log(ANDROID_LOG_ERROR, "mac-restrictions",
"Could not get socket type/protocol: %s", strerror(errno));
} else if (AF_NETLINK == sock_domain && NETLINK_ROUTE == sock_protocol) {
char package_name[MAX_PACKAGE_NAME_LENGTH + 1];
get_package_name(package_name, sizeof(package_name));
async_safe_format_log(
ANDROID_LOG_ERROR, "mac-restrictions",
"%s tried to call bind() on a NETLINK_ROUTE socket, which is not allowed. Please follow "
"instructions at go/netlink-bug if this app behaves incorrectly.",
package_name);
errno = EACCES;
return -1;
}
}
return __bind(fd, addr, addr_length);
}