背景
android 11的接口setFirewallUidRule 使用中 发现设置有问题
对比了下新系统流程
找到变更
流程分析
INetworkManagementService.aidl
void setFirewallUidRule(int chain, int uid, int rule);
void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
NetworkManagementService.java
public void setFirewallUidRule(int chain, int uid, int rule) {
enforceSystemUid();
synchronized (mQuotaLock) {
setFirewallUidRuleLocked(chain, uid, rule);
}
}
private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
if (updateFirewallUidRuleLocked(chain, uid, rule)) {
final int ruleType = getFirewallRuleType(chain, rule);
try {
mNetdService.firewallSetUidRule(chain, uid, ruleType);
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
}
INetd.aidl
void firewallSetUidRule(int childChain, int uid, int firewallRule);
NetdNativeService.cpp
binder::Status NetdNativeService::firewallSetUidRule(int32_t childChain, int32_t uid,
int32_t firewallRule) {
NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
auto chain = static_cast<ChildChain>(childChain);
auto rule = static_cast<FirewallRule>(firewallRule);
int res = gCtls->firewallCtrl.setUidRule(chain, uid, rule);
return statusFromErrcode(res);
}
FirewallController.cpp
int FirewallController::setUidRule(ChildChain chain, int uid, FirewallRule rule) {
const char* op;
const char* target;
FirewallType firewallType = getFirewallType(chain);
if (firewallType == WHITELIST) {
target = "RETURN";
// When adding, insert RETURN rules at the front, before the catch-all DROP at the end.
op = (rule == ALLOW)? "-I" : "-D";
} else { // BLACKLIST mode
target = "DROP";
// When adding, append DROP rules at the end, after the RETURN rule that matches TCP RSTs.
op = (rule == DENY)? "-A" : "-D";
}
std::vector<std::string> chainNames;
switch(chain) {
case DOZABLE:
chainNames = { LOCAL_DOZABLE };
break;
case STANDBY:
chainNames = { LOCAL_STANDBY };
break;
case POWERSAVE:
chainNames = { LOCAL_POWERSAVE };
break;
case NONE:
chainNames = { LOCAL_INPUT, LOCAL_OUTPUT };
break;
default:
ALOGW("Unknown child chain: %d", chain);
return -EINVAL;
}
//android 11的变更点 需要设置对应的chain 才能进行下去
**if (mUseBpfOwnerMatch) {
return gCtls->trafficCtrl.changeUidOwnerRule(chain, uid, rule, firewallType);**
}
std::string command = "*filter\n";
for (const std::string& chainName : chainNames) {
StringAppendF(&command, "%s %s -m owner --uid-owner %d -j %s\n",
op, chainName.c_str(), uid, target);
}
StringAppendF(&command, "COMMIT\n");
return (execIptablesRestore(V4V6, command) == 0) ? 0 : -EREMOTEIO;
}
TrafficController.cpp
int TrafficController::changeUidOwnerRule(ChildChain chain, uid_t uid, FirewallRule rule,
FirewallType type) {
if (!mBpfEnabled) {
ALOGE("bpf is not set up, should use iptables rule");
return -ENOSYS;
}
Status res;
switch (chain) {
case DOZABLE:
res = updateOwnerMapEntry(DOZABLE_MATCH, uid, rule, type);
break;
case STANDBY:
res = updateOwnerMapEntry(STANDBY_MATCH, uid, rule, type);
break;
case POWERSAVE:
res = updateOwnerMapEntry(POWERSAVE_MATCH, uid, rule, type);
break;
case NONE:
default:
return -EINVAL;
}
if (!isOk(res)) {
ALOGE("change uid(%u) rule of %d failed: %s, rule: %d, type: %d", uid, chain,
res.msg().c_str(), rule, type);
return -res.code();
}
return 0;
}
总结
参数 chain name 不能设置为none