Home | History | Annotate | Download | only in qtaguid
      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  * This socket tagging test is to ensure that the
     19  * netfilter/xt_qtaguid kernel module somewhat behaves as expected
     20  * with respect to tagging sockets.
     21  */
     22 #include <assert.h>
     23 #include <errno.h>
     24 #include <fcntl.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <sys/socket.h>
     28 #include <sys/types.h>
     29 #include <string>
     30 
     31 #define LOG_TAG "socketTagTest"
     32 #include <utils/Log.h>
     33 #include <testUtil.h>
     34 
     35 
     36 class SockInfo {
     37 public:
     38         SockInfo()
     39                 : fd(-1), addr(NULL) {};
     40         int setup(uint64_t tag);
     41         bool checkTag(uint64_t tag, uid_t uid);
     42         int fd;
     43         void *addr;
     44 };
     45 
     46 
     47 int openCtrl() {
     48     int ctrl;
     49     ctrl = open("/proc/net/xt_qtaguid/ctrl", O_RDWR);
     50     if (!ctrl) {
     51        testPrintE("qtaguid ctrl open failed: %s", strerror(errno));
     52     }
     53     return ctrl;
     54 }
     55 
     56 int doCtrlCommand(const char *fmt, ...) {
     57     char *buff;
     58     int ctrl;
     59     int res;
     60     va_list argp;
     61 
     62     va_start(argp, fmt);
     63     ctrl = openCtrl();
     64     vasprintf(&buff, fmt, argp);
     65     errno = 0;
     66     res = write(ctrl, buff, strlen(buff));
     67     testPrintI("cmd: '%s' res=%d %d/%s", buff, res, errno, strerror(errno));
     68     close(ctrl);
     69     free(buff);
     70     va_end(argp);
     71     return res;
     72 }
     73 
     74 
     75 int writeModuleParam(const char *param, const char *data) {
     76     int param_fd;
     77     int res;
     78     std::string filename("/sys/module/xt_qtaguid/parameters/");
     79 
     80     filename += param;
     81     param_fd = open(filename.c_str(), O_WRONLY);
     82     if (param_fd < 0) {
     83         testPrintE("qtaguid param open failed: %s", strerror(errno));
     84         return -1;
     85     }
     86     res = write(param_fd, data, strlen(data));
     87     if (res < 0) {
     88         testPrintE("qtaguid param write failed: %s", strerror(errno));
     89     }
     90     close(param_fd);
     91     return res;
     92 }
     93 /*----------------------------------------------------------------*/
     94 int SockInfo::setup(uint64_t tag) {
     95     fd = socket(AF_INET, SOCK_STREAM, 0);
     96     if (fd < 0) {
     97         testPrintE("socket creation failed: %s", strerror(errno));
     98         return -1;
     99     }
    100     if (doCtrlCommand("t %d %llu", fd, tag) < 0) {
    101         testPrintE("socket setup: failed to tag");
    102         close(fd);
    103         return -1;
    104     }
    105     if (!checkTag(tag, getuid())) {
    106         testPrintE("socket setup: Unexpected results: tag not found");
    107         close(fd);
    108         return -1;
    109     }
    110     if (doCtrlCommand("u %d", fd) < 0) {
    111         testPrintE("socket setup: Unexpected results");
    112         close(fd);
    113         return -1;
    114     }
    115     return 0;
    116 }
    117 
    118 /* checkTag() also tries to lookup the socket address in the kernel and
    119  * return it when *addr  == NULL.
    120  * This allows for better look ups when another process is also setting the same
    121  * tag + uid. But it is not fool proof.
    122  * Without the kernel reporting more info on who setup the socket tag, it is
    123  * not easily verifiable from user-space.
    124  * Returns: true if tag found.
    125  */
    126 bool SockInfo::checkTag(uint64_t acct_tag, uid_t uid) {
    127     int ctrl_fd;
    128     ctrl_fd = openCtrl();
    129     char ctrl_data[1024];
    130     ssize_t read_size;
    131     char *buff;
    132     char *pos;
    133     int res;
    134     char *match_template;
    135     uint64_t k_tag;
    136     uint32_t k_uid;
    137     uint64_t full_tag;
    138     long dummy_count;
    139     pid_t dummy_pid;
    140 
    141     read_size = read(ctrl_fd, ctrl_data, sizeof(ctrl_data));
    142     if (read_size < 0) {
    143        testPrintE("Unable to read active tags from ctrl %d/%s",
    144                   errno, strerror(errno));
    145     }
    146     ctrl_data[read_size] = '\0';
    147     testPrintI("<ctrl_raw_data>\n%s</ctrl_raw_data>", ctrl_data);
    148 
    149     if (addr) {
    150         assert(sizeof(void*) == sizeof(long int));  // Why does %p use 0x? grrr. %lx.
    151         asprintf(&match_template, "sock=%lx %s", addr, "tag=0x%llx (uid=%u)");
    152     }
    153     else {
    154         /* Allocate for symmetry */
    155         asprintf(&match_template, "%s", " tag=0x%llx (uid=%u)");
    156     }
    157 
    158     full_tag = acct_tag | uid;
    159 
    160     asprintf(&buff, match_template, full_tag | uid, uid);
    161     testPrintI("looking for '%s'", buff);
    162     pos = strstr(ctrl_data, buff);
    163 
    164     if (pos && !addr) {
    165         assert(sizeof(void*) == sizeof(long int));  // Why does %p use 0x? grrr. %lx.
    166         res = sscanf(pos - strlen("sock=1234abcd"),
    167                      "sock=%lx tag=0x%llx (uid=%lu) pid=%u f_count=%lu",
    168                      &addr, &k_tag, &k_uid, &dummy_pid, &dummy_count );
    169         if (!(res == 5 && k_tag == full_tag && k_uid == uid)) {
    170             testPrintE("Unable to read sock addr res=%d", res);
    171            addr = 0;
    172         }
    173         else {
    174             testPrintI("Got sock_addr %lx", addr);
    175         }
    176     }
    177     free(buff);
    178     free(match_template);
    179     close(ctrl_fd);
    180     return pos != NULL;
    181 }
    182 
    183 /*----------------------------------------------------------------*/
    184 int testSocketTagging(void) {
    185     SockInfo sock0;
    186     SockInfo sock1;
    187     int res;
    188     int total_errors = 0;
    189     int ctrl_fd = -1;
    190     int dev_fd = -1;
    191     const uint64_t invalid_tag1 = 0x0000000100000001llu;
    192     uint64_t valid_tag1;
    193     uint64_t valid_tag2;
    194     uint64_t max_uint_tag = 0xffffffff00000000llu;
    195     uid_t fake_uid;
    196     uid_t fake_uid2;
    197     const char *test_name;
    198     uid_t my_uid = getuid();
    199     pid_t my_pid = getpid();
    200 
    201     srand48(my_pid * my_uid);
    202     /* Adjust fake UIDs and tags so that multiple instances can run in parallel. */
    203     fake_uid = testRand();
    204     fake_uid2 = testRand();
    205     valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
    206     valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
    207     max_uint_tag = 1llu << 63 | (((uint64_t)my_pid << 48) ^ max_uint_tag);
    208     testSetLogCatTag(LOG_TAG);
    209 
    210     testPrintI("** %s ** ============================", __FUNCTION__);
    211     testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu"
    212                " tag1=0x%llx/%llu tag2=0x%llx/%llu",
    213                my_pid, my_uid, fake_uid, fake_uid, fake_uid2, fake_uid2,
    214                valid_tag1, valid_tag1, valid_tag2, valid_tag2);
    215 
    216     // ---------------
    217     test_name = "kernel has qtaguid";
    218     testPrintI("* test: %s ", test_name);
    219     ctrl_fd = openCtrl();
    220     if (ctrl_fd < 0) {
    221         testPrintE("qtaguid ctrl open failed: %s", strerror(errno));
    222         total_errors++;
    223         goto done;
    224     }
    225     close(ctrl_fd);
    226     dev_fd = open("/dev/xt_qtaguid", O_RDONLY);
    227     if (dev_fd < 0) {
    228         testPrintE("qtaguid dev open failed: %s", strerror(errno));
    229         total_errors++;
    230     }
    231     // ---------------
    232     test_name = "delete command doesn't fail";
    233     testPrintI("* test: %s", test_name);
    234     res = doCtrlCommand("d 0 %u", fake_uid);
    235     if (res < 0) {
    236             testPrintE("! %s: Unexpected results", test_name);
    237             total_errors++;
    238     }
    239 
    240     res = doCtrlCommand("d 0 %u", fake_uid2);
    241     if (res < 0) {
    242             testPrintE("! %s: Unexpected results", test_name);
    243             total_errors++;
    244     }
    245 
    246     res = doCtrlCommand("d 0 %u", my_uid);
    247     if (res < 0) {
    248             testPrintE("! %s: Unexpected results", test_name);
    249             total_errors++;
    250     }
    251     // ---------------
    252     test_name = "setup sock0 and addr via tag";
    253     testPrintI("* test: %s", test_name);
    254     if (sock0.setup(valid_tag1) < 0) {
    255         testPrintE("socket setup failed: %s", strerror(errno));
    256         total_errors++;
    257         goto done;
    258 
    259     }
    260     // ---------------
    261     test_name = "setup sock1 and addr via tag";
    262     testPrintI("* test: %s", test_name);
    263     if (sock1.setup(valid_tag1) < 0) {
    264         testPrintE("socket setup failed: %s", strerror(errno));
    265         total_errors++;
    266         goto done;
    267     }
    268     // ---------------
    269     test_name = "insufficient args. Expected failure";
    270     testPrintI("* test: %s", test_name);
    271     res = doCtrlCommand("t");
    272     if (res > 0) {
    273         testPrintE("! %s: Unexpected results", test_name);
    274         total_errors++;
    275     }
    276 
    277     // ---------------
    278     test_name = "bad command. Expected failure";
    279     testPrintI("* test: %s", test_name);
    280     res = doCtrlCommand("?");
    281     if (res > 0) {
    282             testPrintE("! %s: Unexpected results", test_name);
    283         total_errors++;
    284     }
    285 
    286     // ---------------
    287     test_name = "no tag, no uid";
    288     testPrintI("* test: %s", test_name);
    289     res = doCtrlCommand("t %d", sock0.fd);
    290     if (res < 0) {
    291         testPrintE("! %s: Unexpected results", test_name);
    292         total_errors++;
    293     }
    294     if (!sock0.checkTag(0, my_uid)) {
    295         testPrintE("! %s: Unexpected results: tag not found", test_name);
    296         total_errors++;
    297     }
    298 
    299     // ---------------
    300     test_name = "invalid tag. Expected failure";
    301     testPrintI("* test: %s", test_name);
    302     res = doCtrlCommand("t %d %llu", sock0.fd, invalid_tag1);
    303     if (res > 0) {
    304         testPrintE("! %s: Unexpected results", test_name);
    305         total_errors++;
    306     }
    307     if (sock0.checkTag(invalid_tag1, my_uid)) {
    308         testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    309         total_errors++;
    310     }
    311 
    312     // ---------------
    313     test_name = "valid tag with no uid";
    314     testPrintI("* test: %s", test_name);
    315     res = doCtrlCommand("t %d %llu", sock0.fd, valid_tag1);
    316     if (res < 0) {
    317         testPrintE("! %s: Unexpected results", test_name);
    318         total_errors++;
    319     }
    320     if (!sock0.checkTag(valid_tag1, my_uid)) {
    321         testPrintE("! %s: Unexpected results: tag not found", test_name);
    322         total_errors++;
    323     }
    324     // ---------------
    325     test_name = "valid untag";
    326     testPrintI("* test: %s", test_name);
    327     res = doCtrlCommand("u %d", sock0.fd);
    328     if (res < 0) {
    329         testPrintE("! %s: Unexpected results", test_name);
    330         total_errors++;
    331     }
    332     if (sock0.checkTag(valid_tag1, my_uid)) {
    333         testPrintE("! %s: Unexpected results: tag not removed", test_name);
    334         total_errors++;
    335     }
    336 
    337     // ---------------
    338     test_name = "valid 1st tag";
    339     testPrintI("* test: %s", test_name);
    340     res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid);
    341     if (res < 0) {
    342         testPrintE("! %s: Unexpected results", test_name);
    343         total_errors++;
    344     }
    345     if (!sock0.checkTag(valid_tag2, fake_uid)) {
    346         testPrintE("! %s: Unexpected results: tag not found", test_name);
    347         total_errors++;
    348     }
    349 
    350     // ---------------
    351     test_name = "valid re-tag";
    352     testPrintI("* test: %s", test_name);
    353     res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid);
    354     if (res < 0) {
    355         testPrintE("! %s: Unexpected results", test_name);
    356         total_errors++;
    357     }
    358     if (!sock0.checkTag(valid_tag2, fake_uid)) {
    359         testPrintE("! %s: Unexpected results: tag not found", test_name);
    360         total_errors++;
    361     }
    362 
    363     // ---------------
    364     test_name = "valid re-tag with acct_tag change";
    365     testPrintI("* test: %s", test_name);
    366     res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, fake_uid);
    367     if (res < 0) {
    368         testPrintE("! %s: Unexpected results", test_name);
    369         total_errors++;
    370     }
    371     if (!sock0.checkTag(valid_tag1, fake_uid)) {
    372         testPrintE("! %s: Unexpected results: tag not found", test_name);
    373         total_errors++;
    374     }
    375 
    376     // ---------------
    377     test_name = "re-tag with uid change";
    378     testPrintI("* test: %s", test_name);
    379     res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid2);
    380     if (res < 0) {
    381         testPrintE("! %s: Unexpected results", test_name);
    382         total_errors++;
    383     }
    384     if (!sock0.checkTag(valid_tag2, fake_uid2)) {
    385         testPrintE("! %s: Unexpected results: tag not found", test_name);
    386         total_errors++;
    387     }
    388 
    389     // ---------------
    390     test_name = "valid 64bit acct tag";
    391     testPrintI("* test: %s", test_name);
    392     res = doCtrlCommand("t %d %llu", sock0.fd, max_uint_tag);
    393     if (res < 0) {
    394         testPrintE("! %s: Unexpected results", test_name);
    395         total_errors++;
    396     }
    397     if (!sock0.checkTag(max_uint_tag, my_uid)) {
    398         testPrintE("! %s: Unexpected results: tag not found", test_name);
    399         total_errors++;
    400     }
    401 
    402     // ---------------
    403     test_name = "tag another socket";
    404     testPrintI("* test: %s", test_name);
    405     res = doCtrlCommand("t %d %llu %u", sock1.fd, valid_tag1, fake_uid2);
    406     if (res < 0) {
    407         testPrintE("! %s: Unexpected results", test_name);
    408         total_errors++;
    409     }
    410     if (!sock1.checkTag(valid_tag1, fake_uid2)) {
    411         testPrintE("! %s: Unexpected results: tag not found", test_name);
    412         total_errors++;
    413     }
    414 
    415     // ---------------
    416     test_name = "valid untag";
    417     testPrintI("* test: %s", test_name);
    418     res = doCtrlCommand("u %d", sock0.fd);
    419     if (res < 0) {
    420         testPrintE("! %s: Unexpected results", test_name);
    421         total_errors++;
    422     }
    423     if (sock0.checkTag(max_uint_tag, fake_uid)) {
    424         testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    425         total_errors++;
    426     }
    427     if (!sock1.checkTag(valid_tag1, fake_uid2)) {
    428         testPrintE("! %s: Unexpected results: tag not found", test_name);
    429         total_errors++;
    430     }
    431     res = doCtrlCommand("u %d", sock1.fd);
    432     if (res < 0) {
    433         testPrintE("! %s: Unexpected results", test_name);
    434         total_errors++;
    435     }
    436     if (sock1.checkTag(valid_tag1, fake_uid2)) {
    437         testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    438         total_errors++;
    439     }
    440 
    441     // ---------------
    442     test_name = "invalid sock0.fd. Expected failure";
    443     testPrintI("* test: %s", test_name);
    444     close(sock0.fd);
    445     res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, my_uid);
    446     if (res > 0) {
    447             testPrintE("! %s: Unexpected results", test_name);
    448         total_errors++;
    449     }
    450     if (sock0.checkTag(valid_tag1, my_uid)) {
    451         testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    452         total_errors++;
    453     }
    454 
    455     // ---------------
    456     test_name = "invalid untag. Expected failure";
    457     testPrintI("* test: %s", test_name);
    458     close(sock1.fd);
    459     res = doCtrlCommand("u %d", sock1.fd);
    460     if (res > 0) {
    461         testPrintE("! %s: Unexpected results", test_name);
    462         total_errors++;
    463     }
    464 
    465     if (total_errors) {
    466         testPrintE("! Errors found");
    467     } else {
    468         testPrintI("No Errors found");
    469     }
    470 
    471 done:
    472     if (dev_fd >= 0) {
    473         close(dev_fd);
    474     }
    475     if (ctrl_fd >= 0) {
    476         close(ctrl_fd);
    477     }
    478     return total_errors;
    479 }
    480 
    481 int testTagData(void) {
    482     SockInfo sock0;
    483     SockInfo sock1;
    484     int res;
    485     int total_errors = 0;
    486     int ctrl_fd = -1;
    487     int dev_fd = -1;
    488     const uint64_t invalid_tag1 = 0x0000000100000001llu;
    489     uint64_t valid_tag1;
    490     uint64_t valid_tag2;
    491     uint64_t max_uint_tag = 0xffffffff00000000llu;
    492     uid_t fake_uid;
    493     uid_t fake_uid2;
    494     const char *test_name;
    495     uid_t my_uid = getuid();
    496     pid_t my_pid = getpid();
    497     const int max_tags = 5;
    498 
    499     srand48(my_pid * my_uid);
    500     /* Adjust fake UIDs and tags so that multiple instances can run in parallel. */
    501     fake_uid = testRand();
    502     fake_uid2 = testRand();
    503     valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
    504     valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32);
    505     valid_tag2 &= 0xffffff00ffffffffllu;  // Leave some room to make counts visible.
    506     testSetLogCatTag(LOG_TAG);
    507 
    508     testPrintI("** %s ** ============================", __FUNCTION__);
    509     testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu"
    510                " tag1=0x%llx/%llu tag2=0x%llx/%llu",
    511                my_pid, my_uid, fake_uid, fake_uid, fake_uid2, fake_uid2,
    512                valid_tag1, valid_tag1, valid_tag2, valid_tag2);
    513 
    514     // ---------------
    515     test_name = "kernel has qtaguid";
    516     testPrintI("* test: %s ", test_name);
    517     ctrl_fd = openCtrl();
    518     if (ctrl_fd < 0) {
    519         testPrintE("qtaguid ctrl open failed: %s", strerror(errno));
    520         return 1;
    521     }
    522     close(ctrl_fd);
    523     dev_fd = open("/dev/xt_qtaguid", O_RDONLY);
    524     if (dev_fd < 0) {
    525         testPrintE("! %s: qtaguid dev open failed: %s", test_name, strerror(errno));
    526         total_errors++;
    527     }
    528     // ---------------
    529     test_name = "delete command doesn't fail";
    530     testPrintI("* test: %s", test_name);
    531     res = doCtrlCommand("d 0 %u", fake_uid);
    532     if (res < 0) {
    533             testPrintE("! %s: Unexpected results", test_name);
    534             total_errors++;
    535     }
    536 
    537     res = doCtrlCommand("d 0 %u", fake_uid2);
    538     if (res < 0) {
    539             testPrintE("! %s: Unexpected results", test_name);
    540             total_errors++;
    541     }
    542 
    543     res = doCtrlCommand("d 0 %u", my_uid);
    544     if (res < 0) {
    545             testPrintE("! %s: Unexpected results", test_name);
    546             total_errors++;
    547     }
    548 
    549     // ---------------
    550     test_name = "setup sock0 and addr via tag";
    551     testPrintI("* test: %s", test_name);
    552     if (sock0.setup(valid_tag1)) {
    553         testPrintE("socket setup failed: %s", strerror(errno));
    554         return 1;
    555     }
    556     // ---------------
    557     test_name = "setup sock1 and addr via tag";
    558     testPrintI("* test: %s", test_name);
    559     if (sock1.setup(valid_tag1)) {
    560         testPrintE("socket setup failed: %s", strerror(errno));
    561         return 1;
    562     }
    563     // ---------------
    564     test_name = "setup tag limit";
    565     testPrintI("* test: %s ", test_name);
    566     char *max_tags_str;
    567     asprintf(&max_tags_str, "%d", max_tags);
    568     res = writeModuleParam("max_sock_tags", max_tags_str);
    569     if (res < 0) {
    570         testPrintE("! %s: Unexpected results", test_name);
    571         free(max_tags_str);
    572         return 1;
    573     }
    574 
    575     // ---------------
    576     test_name = "tag quota reach limit";
    577     testPrintI("* test: %s", test_name);
    578     for (int cnt = 0; cnt < max_tags; cnt++ ) {
    579         uint64_t new_tag = valid_tag2 + ((uint64_t)cnt << 32);
    580         res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2);
    581         if (res < 0) {
    582                 testPrintE("! %s: Unexpected results", test_name);
    583                 total_errors++;
    584         }
    585         if (!sock0.checkTag(new_tag, fake_uid2)) {
    586                 testPrintE("! %s: Unexpected results: tag not found", test_name);
    587                 total_errors++;
    588         }
    589     }
    590     test_name = "tag quota go over limit";
    591     testPrintI("* test: %s", test_name);
    592     {
    593         uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32);
    594         res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2);
    595         if (res > 0) {
    596                 testPrintE("! %s: Unexpected results", test_name);
    597                 total_errors++;
    598         }
    599         if (!sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2)) {
    600                 testPrintE("! %s: Unexpected results: tag not found", test_name);
    601                 total_errors++;
    602         }
    603     }
    604 
    605     // ---------------
    606     test_name = "valid untag";
    607     testPrintI("* test: %s", test_name);
    608     res = doCtrlCommand("u %d", sock0.fd);
    609     if (res < 0) {
    610         testPrintE("! %s: Unexpected results", test_name);
    611         total_errors++;
    612     }
    613     if (sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2)) {
    614         testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    615         total_errors++;
    616     }
    617 
    618     // ---------------
    619     test_name = "tag after untag shouldn't free up max tags";
    620     testPrintI("* test: %s", test_name);
    621     {
    622         uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32);
    623         res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2);
    624         if (res > 0) {
    625                 testPrintE("! %s: Unexpected results", test_name);
    626                 total_errors++;
    627         }
    628         if (sock0.checkTag(valid_tag2 + ((uint64_t)max_tags << 32), fake_uid2)) {
    629             testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    630             total_errors++;
    631         }
    632     }
    633 
    634     // ---------------
    635     test_name = "delete one tag";
    636     testPrintI("* test: %s", test_name);
    637     {
    638             uint64_t new_tag = valid_tag2 + (((uint64_t)max_tags / 2) << 32);
    639             res = doCtrlCommand("d %llu %u", new_tag, fake_uid2);
    640             if (res < 0) {
    641                     testPrintE("! %s: Unexpected results", test_name);
    642                     total_errors++;
    643             }
    644     }
    645 
    646     // ---------------
    647     test_name = "2 tags after 1 delete pass/fail";
    648     testPrintI("* test: %s", test_name);
    649     {
    650         uint64_t new_tag;
    651         new_tag = valid_tag2 + (((uint64_t)max_tags + 1 ) << 32);
    652         res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2);
    653         if (res < 0) {
    654                 testPrintE("! %s: Unexpected results", test_name);
    655                 total_errors++;
    656         }
    657         if (!sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 1) << 32), fake_uid2)) {
    658             testPrintE("! %s: Unexpected results: tag not found", test_name);
    659             total_errors++;
    660         }
    661 
    662         new_tag = valid_tag2 + (((uint64_t)max_tags + 2 ) << 32);
    663         res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2);
    664         if (res > 0) {
    665                 testPrintE("! %s: Unexpected results", test_name);
    666                 total_errors++;
    667         }
    668         if (sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 2) << 32), fake_uid2)) {
    669             testPrintE("! %s: Unexpected results: tag should not be there", test_name);
    670             total_errors++;
    671         }
    672     }
    673 
    674     /* TODO(jpa): test tagging two different sockets with same tags and
    675      * check refcounts  the tag_node should be +2
    676      */
    677 
    678     // ---------------
    679     if (total_errors) {
    680         testPrintE("! Errors found");
    681     } else {
    682         testPrintI("No Errors found");
    683     }
    684 
    685 done:
    686     if (dev_fd >= 0) {
    687         close(dev_fd);
    688     }
    689     if (ctrl_fd >= 0) {
    690         close(ctrl_fd);
    691     }
    692     return total_errors;
    693 }
    694 
    695 /*----------------------------------------------------------------*/
    696 
    697 int main(int argc, char *argv[]) {
    698     int res = 0;
    699     res += testTagData();
    700     res += testSocketTagging();
    701     if (res) {
    702         testPrintE("!! %d Errors found", res);
    703     } else {
    704         testPrintE("No Errors found");
    705     }
    706     return res;
    707 }
    708