Don't leak map fds in BpfCoordinator#dump.

Currently, the dump methods open BpfMap objects and never close
them. This leaks filedescriptors, and if dump is called often
enough, will crash the networkstack process.

Fix this by using try-with-resources statements that
automatically close the map when exiting the try block.

Change the signature of BpfMap#close from "throws Exception" to
"throws ErrnoException" since it does not throw any other type
of checked exceptions.

Test: "lsof | grep network_st" while running "dumpsys tethering bpf" in a loop
Change-Id: I66c407454c2715bf41bf3a2e81bd582f9ea5a905
This commit is contained in:
Lorenzo Colitti
2021-02-09 23:07:17 +09:00
parent 4431655a4d
commit 555472a186
2 changed files with 15 additions and 17 deletions

View File

@@ -766,17 +766,16 @@ public class BpfCoordinator {
} }
private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) { private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) {
final BpfMap<TetherUpstream6Key, Tether6Value> ipv6UpstreamMap = mDeps.getBpfUpstream6Map(); try (BpfMap<TetherUpstream6Key, Tether6Value> map = mDeps.getBpfUpstream6Map()) {
if (ipv6UpstreamMap == null) { if (map == null) {
pw.println("No IPv6 upstream"); pw.println("No IPv6 upstream");
return; return;
} }
try { if (map.isEmpty()) {
if (ipv6UpstreamMap.isEmpty()) {
pw.println("No IPv6 upstream rules"); pw.println("No IPv6 upstream rules");
return; return;
} }
ipv6UpstreamMap.forEach((k, v) -> pw.println(ipv6UpstreamRuletoString(k, v))); map.forEach((k, v) -> pw.println(ipv6UpstreamRuletoString(k, v)));
} catch (ErrnoException e) { } catch (ErrnoException e) {
pw.println("Error dumping IPv4 map: " + e); pw.println("Error dumping IPv4 map: " + e);
} }
@@ -797,19 +796,18 @@ public class BpfCoordinator {
} }
private void dumpIpv4ForwardingRules(IndentingPrintWriter pw) { private void dumpIpv4ForwardingRules(IndentingPrintWriter pw) {
final BpfMap<Tether4Key, Tether4Value> ipv4UpstreamMap = mDeps.getBpfUpstream4Map(); try (BpfMap<Tether4Key, Tether4Value> map = mDeps.getBpfUpstream4Map()) {
if (ipv4UpstreamMap == null) { if (map == null) {
pw.println("No IPv4 support"); pw.println("No IPv4 support");
return; return;
} }
try { if (map.isEmpty()) {
if (ipv4UpstreamMap.isEmpty()) {
pw.println("No IPv4 rules"); pw.println("No IPv4 rules");
return; return;
} }
pw.println("[IPv4]: iif(iface) oif(iface) src nat dst"); pw.println("[IPv4]: iif(iface) oif(iface) src nat dst");
pw.increaseIndent(); pw.increaseIndent();
ipv4UpstreamMap.forEach((k, v) -> pw.println(ipv4RuleToString(k, v))); map.forEach((k, v) -> pw.println(ipv4RuleToString(k, v)));
} catch (ErrnoException e) { } catch (ErrnoException e) {
pw.println("Error dumping IPv4 map: " + e); pw.println("Error dumping IPv4 map: " + e);
} }

View File

@@ -218,7 +218,7 @@ public class BpfMap<K extends Struct, V extends Struct> implements AutoCloseable
} }
@Override @Override
public void close() throws Exception { public void close() throws ErrnoException {
closeMap(mMapFd); closeMap(mMapFd);
} }