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
36class SockInfo {
37public:
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
47int 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
56int 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
75int 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/*----------------------------------------------------------------*/
94int 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 */
126bool 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/*----------------------------------------------------------------*/
184int 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
471done:
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
481int 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
685done:
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
697int 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