diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2017-11-28 01:26:02 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2017-11-30 01:54:16 +0000 |
commit | 5c43799a4bc53d0db6f06e6b0a93914956428ca6 (patch) | |
tree | 1cc83a8fd0b3dd6da062ed493a16ee2732ebbd39 /server/NetlinkCommands.h | |
parent | c2db59afb266f31e9657f8a21b9ec1a9d221cd2b (diff) | |
download | netd-5c43799a4bc53d0db6f06e6b0a93914956428ca6.tar.gz |
Don't create rules with NLM_F_EXCL.
Some operations, such as changing a network's permissions, rely
on make-before-break, and in some cases create rules that are
identical to the ones that already exist. Starting around 4.9,
the kernel fails these operations with EEXIST.
We can't just ignore the EEXISTs because if we get EEXIST it
means that the rule was not created, but we'll think it was,
and later on we'll trip up trying to delete it.
It would be possible to refactor the code to ensure that these
no-op operations are never performed, but we would probably have
to pass a lot more state around to deal with only a few corner
cases.
Fix: 69607866
Test: builds
Change-Id: I1b563243b615daa73a2d9f527f77608df1f56251
Diffstat (limited to 'server/NetlinkCommands.h')
-rw-r--r-- | server/NetlinkCommands.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/server/NetlinkCommands.h b/server/NetlinkCommands.h index 7c0d4a86..ef1ff48a 100644 --- a/server/NetlinkCommands.h +++ b/server/NetlinkCommands.h @@ -29,7 +29,13 @@ namespace net { const sockaddr_nl KERNEL_NLADDR = {AF_NETLINK, 0, 0, 0}; const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK; -const uint16_t NETLINK_CREATE_REQUEST_FLAGS = NETLINK_REQUEST_FLAGS | NLM_F_CREATE | NLM_F_EXCL; +const uint16_t NETLINK_ROUTE_CREATE_FLAGS = NETLINK_REQUEST_FLAGS | NLM_F_CREATE | NLM_F_EXCL; +// Don't create rules with NLM_F_EXCL, because operations such as changing network permissions rely +// on make-before-break. The kernel did not complain about duplicate rules until ~4.9, at which +// point it started returning EEXIST. See for example b/69607866 . We can't just ignore the EEXIST +// because if we hit it, the rule was not created, but we will think it was, and we'll then trip up +// trying to delete it. +const uint16_t NETLINK_RULE_CREATE_FLAGS = NETLINK_REQUEST_FLAGS | NLM_F_CREATE; const uint16_t NETLINK_DUMP_FLAGS = NLM_F_REQUEST | NLM_F_DUMP; // Generic code for processing netlink dumps. |