194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti/* 294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * Copyright (C) 2016 The Android Open Source Project 394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * 494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * you may not use this file except in compliance with the License. 694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * You may obtain a copy of the License at 794a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * 894a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 994a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * 1094a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * Unless required by applicable law or agreed to in writing, software 1194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 1294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * See the License for the specific language governing permissions and 1494a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti * limitations under the License. 1594a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti */ 1694a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti 17fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <unistd.h> 18fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <sys/socket.h> 198464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 208464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/netlink.h> 218464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/sock_diag.h> 228464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti#include <linux/inet_diag.h> 238464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 24fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <functional> 25fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <set> 26fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 27c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti#include "Permission.h" 28fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include "UidRanges.h" 29fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 308464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colittistruct inet_diag_msg; 31f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitticlass SockDiagTest; 328464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 338464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitticlass SockDiag { 348464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 358464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti public: 368464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti static const int kBufferSize = 4096; 37fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 38fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti // Callback function that is called once for every socket in the dump. A return value of true 39fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti // means destroy the socket. 40fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti typedef std::function<bool(uint8_t proto, const inet_diag_msg *)> DumpCallback; 418464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 428464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti struct DestroyRequest { 438464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti nlmsghdr nlh; 448464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti inet_diag_req_v2 req; 458464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti } __attribute__((__packed__)); 468464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 47f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti SockDiag() : mSock(-1), mWriteSock(-1), mSocketsDestroyed(0) {} 488464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti bool open(); 498464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti virtual ~SockDiag() { closeSocks(); } 508464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 5194a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti int sendDumpRequest(uint8_t proto, uint8_t family, uint32_t states); 528464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int sendDumpRequest(uint8_t proto, uint8_t family, const char *addrstr); 538464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int readDiagMsg(uint8_t proto, DumpCallback callback); 548464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int sockDestroy(uint8_t proto, const inet_diag_msg *); 550726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti // Destroys all sockets on the given IPv4 or IPv6 address. 56f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti int destroySockets(const char *addrstr); 570726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti // Destroys all sockets for the given protocol and UID. 580726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti int destroySockets(uint8_t proto, uid_t uid, bool excludeLoopback); 590726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti // Destroys all "live" (CONNECTED, SYN_SENT, SYN_RECV) TCP sockets for the given UID ranges. 600726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti int destroySockets(const UidRanges& uidRanges, const std::set<uid_t>& skipUids, 610726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti bool excludeLoopback); 62c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti // Destroys all "live" (CONNECTED, SYN_SENT, SYN_RECV) TCP sockets that no longer have 63c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti // the permissions required by the specified network. 64c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti int destroySocketsLackingPermission(unsigned netId, Permission permission, 65c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti bool excludeLoopback); 668464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti 678464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti private: 680726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti friend class SockDiagTest; 698464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int mSock; 708464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti int mWriteSock; 71f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti int mSocketsDestroyed; 7294a7b43ecb13094313d5f1bdc2515be760a0b6beLorenzo Colitti int sendDumpRequest(uint8_t proto, uint8_t family, uint32_t states, iovec *iov, int iovcnt); 73f32fc598b01ba8d59873b0a1085716fd84678b54Lorenzo Colitti int destroySockets(uint8_t proto, int family, const char *addrstr); 74c6201c3754710e235f16118761b23760ff4136adLorenzo Colitti int destroyLiveSockets(DumpCallback destroy, const char *what, iovec *iov, int iovcnt); 758464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti bool hasSocks() { return mSock != -1 && mWriteSock != -1; } 768464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti void closeSocks() { close(mSock); close(mWriteSock); mSock = mWriteSock = -1; } 770726fec82842883a2332318aa675f7f04670db51Lorenzo Colitti static bool isLoopbackSocket(const inet_diag_msg *msg); 788464e1ed13a30ca91ae44dd2e334f63de7ade0f3Lorenzo Colitti}; 79