1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless requied by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 /* 19 * This socket tagging test is to ensure that the 20 * netfilter/xt_qtaguid kernel module somewhat behaves as expected 21 * with respect to tagging sockets. 22 */ 23 #include <assert.h> 24 #include <errno.h> 25 #include <fcntl.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <gtest/gtest.h> 29 #include <sys/socket.h> 30 #include <sys/types.h> 31 #include <string> 32 33 #define LOG_TAG "socketTagTest" 34 #include <utils/Log.h> 35 #include <testUtil.h> 36 37 namespace android { 38 39 class SockInfo { 40 public: 41 SockInfo() : fd(-1), addr(NULL) {}; 42 int setup(uint64_t tag); 43 bool checkTag(uint64_t tag, uid_t uid); 44 int fd; 45 void *addr; 46 }; 47 48 49 int openCtrl() { 50 int ctrl; 51 ctrl = open("/proc/net/xt_qtaguid/ctrl", O_RDWR); 52 if (!ctrl) { 53 testPrintE("qtaguid ctrl open failed: %s", strerror(errno)); 54 } 55 return ctrl; 56 } 57 58 int doCtrlCommand(const char *fmt, ...) { 59 char *buff; 60 int ctrl; 61 int res; 62 va_list argp; 63 64 va_start(argp, fmt); 65 ctrl = openCtrl(); 66 vasprintf(&buff, fmt, argp); 67 errno = 0; 68 res = write(ctrl, buff, strlen(buff)); 69 testPrintI("cmd: '%s' res=%d %d/%s", buff, res, errno, strerror(errno)); 70 close(ctrl); 71 free(buff); 72 va_end(argp); 73 return res; 74 } 75 76 77 int writeModuleParam(const char *param, const char *data) { 78 int param_fd; 79 int res; 80 std::string filename("/sys/module/xt_qtaguid/parameters/"); 81 82 filename += param; 83 param_fd = open(filename.c_str(), O_WRONLY); 84 if (param_fd < 0) { 85 testPrintE("qtaguid param open failed: %s", strerror(errno)); 86 return -1; 87 } 88 res = write(param_fd, data, strlen(data)); 89 if (res < 0) { 90 testPrintE("qtaguid param write failed: %s", strerror(errno)); 91 } 92 close(param_fd); 93 return res; 94 } 95 96 /*----------------------------------------------------------------*/ 97 int SockInfo::setup(uint64_t tag) { 98 fd = socket(AF_INET, SOCK_STREAM, 0); 99 if (fd < 0) { 100 testPrintE("socket creation failed: %s", strerror(errno)); 101 return -1; 102 } 103 if (doCtrlCommand("t %d %llu", fd, tag) < 0) { 104 testPrintE("socket setup: failed to tag"); 105 close(fd); 106 return -1; 107 } 108 if (!checkTag(tag, getuid())) { 109 testPrintE("socket setup: Unexpected results: tag not found"); 110 close(fd); 111 return -1; 112 } 113 if (doCtrlCommand("u %d", fd) < 0) { 114 testPrintE("socket setup: Unexpected results"); 115 close(fd); 116 return -1; 117 } 118 return 0; 119 } 120 121 /* checkTag() also tries to lookup the socket address in the kernel and 122 * return it when *addr == NULL. 123 * This allows for better look ups when another process is also setting the same 124 * tag + uid. But it is not fool proof. 125 * Without the kernel reporting more info on who setup the socket tag, it is 126 * not easily verifiable from user-space. 127 * Returns: true if tag found. 128 */ 129 bool SockInfo::checkTag(uint64_t acct_tag, uid_t uid) { 130 int ctrl_fd; 131 ctrl_fd = openCtrl(); 132 char ctrl_data[1024]; 133 ssize_t read_size; 134 char *buff; 135 char *pos; 136 int res; 137 char *match_template; 138 uint64_t k_tag; 139 uint32_t k_uid; 140 uint64_t full_tag; 141 long dummy_count; 142 pid_t dummy_pid; 143 144 read_size = read(ctrl_fd, ctrl_data, sizeof(ctrl_data)); 145 if (read_size < 0) { 146 testPrintE("Unable to read active tags from ctrl %d/%s", 147 errno, strerror(errno)); 148 } 149 ctrl_data[read_size] = '\0'; 150 testPrintI("<ctrl_raw_data>\n%s</ctrl_raw_data>", ctrl_data); 151 152 if (addr) { 153 assert(sizeof(void*) == sizeof(long int)); // Why does %p use 0x? grrr. %lx. 154 asprintf(&match_template, "sock=%lx %s", addr, "tag=0x%llx (uid=%u)"); 155 } 156 else { 157 /* Allocate for symmetry */ 158 asprintf(&match_template, "%s", " tag=0x%llx (uid=%u)"); 159 } 160 161 full_tag = acct_tag | uid; 162 163 asprintf(&buff, match_template, full_tag | uid, uid); 164 testPrintI("looking for '%s'", buff); 165 pos = strstr(ctrl_data, buff); 166 167 if (pos && !addr) { 168 assert(sizeof(void*) == sizeof(long int)); // Why does %p use 0x? grrr. %lx. 169 res = sscanf(pos - strlen("sock=1234abcd"), 170 "sock=%lx tag=0x%llx (uid=%lu) pid=%u f_count=%lu", 171 &addr, &k_tag, &k_uid, &dummy_pid, &dummy_count ); 172 if (!(res == 5 && k_tag == full_tag && k_uid == uid)) { 173 testPrintE("Unable to read sock addr res=%d", res); 174 addr = 0; 175 } 176 else { 177 testPrintI("Got sock_addr %lx", addr); 178 } 179 } 180 free(buff); 181 free(match_template); 182 close(ctrl_fd); 183 return pos != NULL; 184 } 185 186 187 class SocketTaggingTest : public ::testing::Test { 188 protected: 189 virtual void SetUp() { 190 ctrl_fd = -1; 191 dev_fd = -1; 192 my_uid = getuid(); 193 my_pid = getpid(); 194 srand48(my_pid * my_uid); 195 // Adjust fake UIDs and tags so that multiple instances can run in parallel. 196 fake_uid = testRand(); 197 fake_uid2 = testRand(); 198 valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); 199 valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); 200 valid_tag2 &= 0xffffff00ffffffffllu; // Leave some room to make counts visible. 201 testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu" 202 " tag1=0x%llx/%llu tag2=0x%llx/%llu", 203 my_pid, my_uid, fake_uid, fake_uid, fake_uid2, fake_uid2, 204 valid_tag1, valid_tag1, valid_tag2, valid_tag2); 205 max_uint_tag = 0xffffffff00000000llu; 206 max_uint_tag = 1llu << 63 | (((uint64_t)my_pid << 48) ^ max_uint_tag); 207 208 testPrintI("kernel has qtaguid"); 209 ctrl_fd = openCtrl(); 210 ASSERT_GE(ctrl_fd, 0) << "qtaguid ctrl open failed"; 211 close(ctrl_fd); 212 dev_fd = open("/dev/xt_qtaguid", O_RDONLY); 213 EXPECT_GE(dev_fd, 0) << "qtaguid dev open failed"; 214 215 // We want to clean up any previous faulty test runs. 216 testPrintI("delete command does not fail"); 217 EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid), 0) << "Failed to delete fake_uid"; 218 EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid2), 0) << "Failed to delete fake_uid2"; 219 EXPECT_GE(doCtrlCommand("d 0 %u", my_uid), 0) << "Failed to delete my_uid"; 220 221 testPrintI("setup sock0 and addr via tag"); 222 ASSERT_FALSE(sock0.setup(valid_tag1)) << "socket0 setup failed"; 223 testPrintI("setup sock1 and addr via tag"); 224 ASSERT_FALSE(sock1.setup(valid_tag1)) << "socket1 setup failed"; 225 } 226 227 virtual void TearDown() { 228 if (dev_fd >= 0) { 229 close(dev_fd); 230 } 231 if (ctrl_fd >= 0) { 232 close(ctrl_fd); 233 } 234 } 235 236 SockInfo sock0; 237 SockInfo sock1; 238 int ctrl_fd; 239 int dev_fd; 240 uid_t fake_uid; 241 uid_t fake_uid2; 242 uid_t my_uid; 243 pid_t my_pid; 244 uint64_t valid_tag1; 245 uint64_t valid_tag2; 246 uint64_t max_uint_tag; 247 static const uint64_t invalid_tag1 = 0x0000000100000001llu; 248 static const int max_tags = 5; 249 }; 250 251 TEST_F(SocketTaggingTest, TagData) { 252 max_uint_tag = 0xffffffff00000000llu; 253 char *max_tags_str; 254 255 testPrintI("setup tag limit"); 256 asprintf(&max_tags_str, "%d", max_tags); 257 ASSERT_GE(writeModuleParam("max_sock_tags", max_tags_str), 0) << "Failed to setup tag limit"; 258 259 testPrintI("tag quota reach limit"); 260 for (int cnt = 0; cnt < max_tags; cnt++ ) { 261 uint64_t tag = valid_tag2 + ((uint64_t)cnt << 32); 262 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, tag , fake_uid2), 0) 263 << "Tagging within limit failed"; 264 EXPECT_TRUE(sock0.checkTag(tag, fake_uid2))<< "Unexpected results: tag not found"; 265 } 266 267 testPrintI("tag quota go over limit"); 268 uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32); 269 EXPECT_LT(doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2), 0); 270 EXPECT_TRUE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), 271 fake_uid2)) << "Unexpected results: tag not found"; 272 273 testPrintI("valid untag"); 274 EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0); 275 EXPECT_FALSE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2)) 276 << "Untagged tag should not be there"; 277 278 testPrintI("tag after untag should not free up max tags"); 279 uint64_t new_tag2 = valid_tag2 + ((uint64_t)max_tags << 32); 280 EXPECT_LT(doCtrlCommand("t %d %llu %u", sock0.fd, new_tag2 , fake_uid2), 0); 281 EXPECT_FALSE(sock0.checkTag(valid_tag2 + ((uint64_t)max_tags << 32), fake_uid2)) 282 << "Tag should not be there"; 283 284 testPrintI("delete one tag"); 285 uint64_t new_tag3 = valid_tag2 + (((uint64_t)max_tags / 2) << 32); 286 EXPECT_GE(doCtrlCommand("d %llu %u", new_tag3, fake_uid2), 0); 287 288 testPrintI("2 tags after 1 delete pass/fail"); 289 uint64_t new_tag4; 290 new_tag4 = valid_tag2 + (((uint64_t)max_tags + 1 ) << 32); 291 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, new_tag4 , fake_uid2), 0); 292 EXPECT_TRUE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 1) << 32), fake_uid2)) 293 << "Tag not found"; 294 new_tag4 = valid_tag2 + (((uint64_t)max_tags + 2 ) << 32); 295 EXPECT_LT(doCtrlCommand("t %d %llu %u", sock0.fd, new_tag4 , fake_uid2), 0); 296 EXPECT_FALSE(sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 2) << 32), fake_uid2)) 297 << "Tag should not be there"; 298 299 /* TODO(jpa): test tagging two different sockets with same tags and 300 * check refcounts the tag_node should be +2 301 */ 302 } 303 304 TEST_F(SocketTaggingTest, InsufficientArgsFails) { 305 // Insufficient args. Expected failure 306 EXPECT_LE(doCtrlCommand("t"), 0) << "Insufficient args, should fail."; 307 } 308 309 TEST_F(SocketTaggingTest, BadCommandFails) { 310 // Bad command. Expected failure"; 311 EXPECT_LE(doCtrlCommand("?"), 0) << "Bad command, should fail"; 312 } 313 314 TEST_F(SocketTaggingTest, NoTagNoUid) { 315 // no tag, no uid 316 EXPECT_GE(doCtrlCommand("t %d", sock0.fd), 0); 317 ASSERT_TRUE(sock0.checkTag(0, my_uid)) << "Tag not found"; 318 } 319 320 TEST_F(SocketTaggingTest, InvalidTagFail) { 321 // Invalid tag. Expected failure 322 EXPECT_LE(doCtrlCommand("t %d %llu", sock0.fd, invalid_tag1), 0); 323 ASSERT_FALSE(sock0.checkTag(invalid_tag1, my_uid)) << "Tag should not be there"; 324 } 325 326 TEST_F(SocketTaggingTest, ValidTagWithNoUid) { 327 // Valid tag with no uid 328 EXPECT_GE(doCtrlCommand("t %d %llu", sock0.fd, valid_tag1), 0); 329 EXPECT_TRUE(sock0.checkTag(valid_tag1, my_uid)) << "Tag not found"; 330 } 331 332 TEST_F(SocketTaggingTest, ValidUntag) { 333 // Valid untag 334 EXPECT_GE(doCtrlCommand("t %d %llu", sock0.fd, valid_tag1), 0); 335 EXPECT_TRUE(sock0.checkTag(valid_tag1, my_uid)) << "Tag not found"; 336 EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0); 337 EXPECT_FALSE(sock0.checkTag(valid_tag1, my_uid)) << "Tag should be removed"; 338 } 339 340 TEST_F(SocketTaggingTest, ValidFirsttag) { 341 // Valid 1st tag 342 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid), 0); 343 EXPECT_TRUE(sock0.checkTag(valid_tag2, fake_uid)) << "Tag not found."; 344 } 345 346 TEST_F(SocketTaggingTest, ValidReTag) { 347 // Valid re-tag 348 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid), 0); 349 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid), 0); 350 EXPECT_TRUE(sock0.checkTag(valid_tag2, fake_uid)) << "Tag not found."; 351 } 352 353 TEST_F(SocketTaggingTest, ValidReTagWithAcctTagChange) { 354 // Valid re-tag with acct_tag change 355 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid), 0); 356 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, fake_uid), 0); 357 EXPECT_TRUE(sock0.checkTag(valid_tag1, fake_uid)) << "Tag not found."; 358 } 359 360 TEST_F(SocketTaggingTest, ReTagWithUidChange) { 361 // Re-tag with uid change 362 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, fake_uid), 0); 363 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid2), 0); 364 } 365 366 TEST_F(SocketTaggingTest, Valid64BitAcctTag) { 367 // Valid 64bit acct tag 368 EXPECT_GE(doCtrlCommand("t %d %llu", sock0.fd, max_uint_tag), 0); 369 EXPECT_TRUE(sock0.checkTag(max_uint_tag, my_uid)) << "Tag not found."; 370 } 371 372 TEST_F(SocketTaggingTest, TagAnotherSocket) { 373 testPrintI("Tag two sockets"); 374 EXPECT_GE(doCtrlCommand("t %d %llu", sock0.fd, max_uint_tag), 0); 375 EXPECT_GE(doCtrlCommand("t %d %llu %u", sock1.fd, valid_tag1, fake_uid2), 0); 376 EXPECT_TRUE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag not found."; 377 testPrintI("Untag socket0 of them only."); 378 EXPECT_GE(doCtrlCommand("u %d", sock0.fd), 0); 379 EXPECT_FALSE(sock0.checkTag(max_uint_tag, fake_uid)) << "Tag should not be there"; 380 EXPECT_TRUE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag not found"; 381 testPrintI("Now untag socket1 as well."); 382 EXPECT_GE(doCtrlCommand("u %d", sock1.fd), 0); 383 EXPECT_FALSE(sock1.checkTag(valid_tag1, fake_uid2)) << "Tag should not be there"; 384 } 385 386 TEST_F(SocketTaggingTest, TagInvalidSocketFail) { 387 // Invalid tag. Expected failure 388 close(sock0.fd); 389 EXPECT_LE(doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, my_uid), 0); 390 EXPECT_FALSE(sock0.checkTag(valid_tag1, my_uid)) << "Tag should not be there"; 391 } 392 393 TEST_F(SocketTaggingTest, UntagInvalidSocketFail) { 394 // Invalid untag. Expected failure"; 395 close(sock1.fd); 396 EXPECT_LE(doCtrlCommand("u %d", sock1.fd), 0); 397 } 398 399 } // namespace android 400