fwmark.explicitlySelected = false;
fwmark.protectedFromVpn = false;
permission = PERMISSION_NONE;
- } else if (mNetworkController->canUserSelectNetwork(client->getUid(), command.netId)) {
+ } else {
+ if (int ret = mNetworkController->checkUserNetworkAccess(client->getUid(),
+ command.netId)) {
+ return ret;
+ }
fwmark.explicitlySelected = true;
fwmark.protectedFromVpn = mNetworkController->canProtect(client->getUid());
- } else {
- return -EPERM;
}
break;
}
Fwmark fwmark;
fwmark.protectedFromVpn = true;
fwmark.permission = PERMISSION_SYSTEM;
- if (canUserSelectNetworkLocked(uid, *netId)) {
+ if (checkUserNetworkAccessLocked(uid, *netId) == 0) {
// If a non-zero NetId was explicitly specified, and the user has permission for that
// network, use that network's DNS servers. Do not fall through to the default network even
// if the explicitly selected network is a split tunnel VPN or a VPN without DNS servers.
}
}
-bool NetworkController::canUserSelectNetwork(uid_t uid, unsigned netId) const {
+int NetworkController::checkUserNetworkAccess(uid_t uid, unsigned netId) const {
android::RWLock::AutoRLock lock(mRWLock);
- return canUserSelectNetworkLocked(uid, netId);
+ return checkUserNetworkAccessLocked(uid, netId);
}
int NetworkController::setPermissionForNetworks(Permission permission,
return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
}
-bool NetworkController::canUserSelectNetworkLocked(uid_t uid, unsigned netId) const {
+int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const {
Network* network = getNetworkLocked(netId);
+ if (!network) {
+ return -ENONET;
+ }
+
// If uid is INVALID_UID, this likely means that we were unable to retrieve the UID of the peer
// (using SO_PEERCRED). Be safe and deny access to the network, even if it's valid.
- if (!network || uid == INVALID_UID) {
- return false;
+ if (uid == INVALID_UID) {
+ return -EREMOTEIO;
}
Permission userPermission = getPermissionForUserLocked(uid);
if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
- return true;
+ return 0;
}
if (network->getType() == Network::VIRTUAL) {
- return static_cast<VirtualNetwork*>(network)->appliesToUser(uid);
+ return static_cast<VirtualNetwork*>(network)->appliesToUser(uid) ? 0 : -EPERM;
}
VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
if (virtualNetwork && virtualNetwork->isSecure() &&
mProtectableUsers.find(uid) == mProtectableUsers.end()) {
- return false;
+ return -EPERM;
}
Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
- return (userPermission & networkPermission) == networkPermission;
+ return ((userPermission & networkPermission) == networkPermission) ? 0 : -EACCES;
}
int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
Permission getPermissionForUser(uid_t uid) const;
void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids);
- bool canUserSelectNetwork(uid_t uid, unsigned netId) const;
+ int checkUserNetworkAccess(uid_t uid, unsigned netId) const;
int setPermissionForNetworks(Permission permission,
const std::vector<unsigned>& netIds) WARN_UNUSED_RESULT;
Network* getNetworkLocked(unsigned netId) const;
VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const;
Permission getPermissionForUserLocked(uid_t uid) const;
- bool canUserSelectNetworkLocked(uid_t uid, unsigned netId) const;
+ int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const;
int modifyRoute(unsigned netId, const char* interface, const char* destination,
const char* nexthop, bool add, bool legacy, uid_t uid) WARN_UNUSED_RESULT;