/* checkTag() also tries to lookup the socket address in the kernel and * return it when *addr == NULL. * This allows for better look ups when another process is also setting the same * tag + uid. But it is not fool proof. * Without the kernel reporting more info on who setup the socket tag, it is * not easily verifiable from user-space. * Returns: true if tag found. */ bool SockInfo::checkTag(uint64_t acct_tag, uid_t uid) { int ctrl_fd; ctrl_fd = openCtrl(); char ctrl_data[1024]; ssize_t read_size; char *buff; char *pos; int res; char *match_template; uint64_t k_tag; uint32_t k_uid; uint64_t full_tag; long dummy_count; pid_t dummy_pid; read_size = read(ctrl_fd, ctrl_data, sizeof(ctrl_data)); if (read_size < 0) { testPrintE("Unable to read active tags from ctrl %d/%s", errno, strerror(errno)); } ctrl_data[read_size] = '\0'; testPrintI("<ctrl_raw_data>\n%s</ctrl_raw_data>", ctrl_data); if (addr) { assert(sizeof(void*) == sizeof(long int)); // Why does %p use 0x? grrr. %lx. asprintf(&match_template, "sock=%" PRIxPTR " %s", (uintptr_t)addr, "tag=0x%" PRIx64" (uid=%u)"); } else { /* Allocate for symmetry */ asprintf(&match_template, "%s", " tag=0x%" PRIx64 " (uid=%u)"); } full_tag = acct_tag | uid; asprintf(&buff, match_template, full_tag | uid, uid); testPrintI("looking for '%s'", buff); pos = strstr(ctrl_data, buff); if (pos && !addr) { assert(sizeof(void*) == sizeof(long int)); // Why does %p use 0x? grrr. %lx. res = sscanf(pos - strlen("sock=1234abcd"), "sock=%" SCNxPTR " tag=0x%" SCNx64 " (uid=%" SCNu32 ") pid=%u f_count=%lu", (uintptr_t *)&addr, &k_tag, &k_uid, &dummy_pid, &dummy_count ); if (!(res == 5 && k_tag == full_tag && k_uid == uid)) { testPrintE("Unable to read sock addr res=%d", res); addr = 0; } else { testPrintI("Got sock_addr %lx", addr); } } free(buff); free(match_template); close(ctrl_fd); return pos != NULL; }
int doCtrlCommand(const char *fmt, ...) { char *buff; int ctrl; int res; va_list argp; va_start(argp, fmt); ctrl = openCtrl(); vasprintf(&buff, fmt, argp); errno = 0; res = write(ctrl, buff, strlen(buff)); testPrintI("cmd: '%s' res=%d %d/%s", buff, res, errno, strerror(errno)); close(ctrl); free(buff); va_end(argp); return res; }
virtual void SetUp() { ctrl_fd = -1; dev_fd = -1; my_uid = getuid(); my_pid = getpid(); srand48(my_pid * my_uid); // Adjust fake UIDs and tags so that multiple instances can run in parallel. fake_uid = testRand(); fake_uid2 = testRand(); valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); valid_tag2 &= 0xffffff00ffffffffllu; // Leave some room to make counts visible. testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu" " tag1=0x%" PRIx64 "/%" PRIu64 " tag2=0x%" PRIx64 "/% " PRIu64, (unsigned long)my_pid, (unsigned long)my_uid, (unsigned long)fake_uid, (unsigned long)fake_uid, (unsigned long)fake_uid2, (unsigned long)fake_uid2, valid_tag1, valid_tag1, valid_tag2, valid_tag2); max_uint_tag = 0xffffffff00000000llu; max_uint_tag = 1llu << 63 | (((uint64_t)my_pid << 48) ^ max_uint_tag); testPrintI("kernel has qtaguid"); ctrl_fd = openCtrl(); ASSERT_GE(ctrl_fd, 0) << "qtaguid ctrl open failed"; close(ctrl_fd); dev_fd = open("/dev/xt_qtaguid", O_RDONLY); EXPECT_GE(dev_fd, 0) << "qtaguid dev open failed"; // We want to clean up any previous faulty test runs. testPrintI("delete command does not fail"); EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid), 0) << "Failed to delete fake_uid"; EXPECT_GE(doCtrlCommand("d 0 %u", fake_uid2), 0) << "Failed to delete fake_uid2"; EXPECT_GE(doCtrlCommand("d 0 %u", my_uid), 0) << "Failed to delete my_uid"; testPrintI("setup sock0 and addr via tag"); ASSERT_FALSE(sock0.setup(valid_tag1)) << "socket0 setup failed"; testPrintI("setup sock1 and addr via tag"); ASSERT_FALSE(sock1.setup(valid_tag1)) << "socket1 setup failed"; }
int main( int argc, char **argv ) { int oldpid, oldumask, fd, noDaemonMode; char *pt, *errorLogFile, **opts; /* make sure at least world write access is disabled */ if (((oldumask = umask( 022 )) & 002) == 002) (void)umask( oldumask ); /* give /dev/null as stdin */ if ((fd = open( "/dev/null", O_RDONLY )) > 0) { dup2( fd, 0 ); close( fd ); } if (fcntl( 1, F_GETFD ) < 0) dup2( 0, 1 ); if (fcntl( 2, F_GETFD ) < 0) dup2( 0, 2 ); if (argv[0][0] == '/') { if (!StrDup( &progpath, argv[0] )) Panic( "Out of memory" ); } else #ifdef __linux__ { /* note that this will resolve symlinks ... */ int len; char fullpath[PATH_MAX]; if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0) Panic( "Invoke with full path specification or mount /proc" ); if (!StrNDup( &progpath, fullpath, len )) Panic( "Out of memory" ); } #else # if 0 Panic( "Must be invoked with full path specification" ); # else { char directory[PATH_MAX+1]; if (!getcwd( directory, sizeof(directory) )) Panic( "Can't find myself (getcwd failed)" ); if (strchr( argv[0], '/' )) StrApp( &progpath, directory, "/", argv[0], (char *)0 ); else { int len; char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; if (!(path = getenv( "PATH" ))) Panic( "Can't find myself (no PATH)" ); len = strlen( argv[0] ); name = nambuf + PATH_MAX - len; memcpy( name, argv[0], len + 1 ); *--name = '/'; do { if (!(pathe = strchr( path, ':' ))) pathe = path + strlen( path ); len = pathe - path; if (!len || (len == 1 && *path == '.')) { len = strlen( directory ); path = directory; } thenam = name - len; if (thenam >= nambuf) { memcpy( thenam, path, len ); if (!access( thenam, X_OK )) goto found; } path = pathe; } while (*path++ != '\0'); Panic( "Can't find myself (not in PATH)" ); found: if (!StrDup( &progpath, thenam )) Panic( "Out of memory" ); } } # endif #endif prog = strrchr( progpath, '/' ) + 1; #if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) Title = argv[0]; TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title; #endif /* * Parse command line options */ noDaemonMode = getppid(); errorLogFile = 0; if (!(opts = Malloc( 2 * sizeof(char *) ))) return 1; opts[0] = (char *)""; opts[1] = 0; while (*++argv) { if (**argv != '-') break; pt = *argv + 1; if (*pt == '-') pt++; if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) { printf( "Usage: %s [options] [tty]\n" " -daemon\t - Daemonize even when started by init\n" " -nodaemon\t - Don't daemonize even when started from command line\n" " -config <file> - Use alternative master configuration file\n" " -xrm <res>\t - Override frontend-specific resource\n" " -error <file>\t - Use alternative log file\n" " -debug <num>\t - Debug option bitfield:\n" "\t\t\t0x1 - core log\n" "\t\t\t0x2 - config reader log\n" "\t\t\t0x4 - greeter log\n" "\t\t\t0x8 - IPC log\n" "\t\t\t0x10 - session sub-daemon post-fork delay\n" "\t\t\t0x20 - config reader post-start delay\n" "\t\t\t0x40 - greeter post-start delay\n" "\t\t\t0x80 - don't use syslog\n" "\t\t\t0x100 - core Xauth log\n" "\t\t\t0x400 - valgrind config reader and greeter\n" "\t\t\t0x800 - strace config reader and greeter\n" , prog ); exit( 0 ); } else if (!strcmp( pt, "daemon" )) noDaemonMode = 0; else if (!strcmp( pt, "nodaemon" )) noDaemonMode = 1; else if (argv[1] && !strcmp( pt, "config" )) StrDup( opts, *++argv ); else if (argv[1] && !strcmp( pt, "xrm" )) opts = addStrArr( opts, *++argv, -1 ); else if (argv[1] && !strcmp( pt, "debug" )) sscanf( *++argv, "%i", &debugLevel ); else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" ))) errorLogFile = *++argv; else { fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv ); exit( 1 ); } } /* * Only allow root to run in non-debug mode to avoid problems */ if (!debugLevel && getuid()) { fprintf( stderr, "Only root wants to run %s\n", prog ); exit( 1 ); } InitErrorLog( errorLogFile ); if (noDaemonMode != 1) BecomeDaemon(); /* * Step 1 - load configuration parameters */ if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0) LogPanic( "Config reader failed. Aborting ...\n" ); /* SUPPRESS 560 */ if ((oldpid = StorePid())) { if (oldpid == -1) LogError( "Can't create/lock pid file %s\n", pidFile ); else LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n", pidFile, oldpid ); exit( 1 ); } #ifdef NEED_ENTROPY AddOtherEntropy(); #endif /* * We used to clean up old authorization files here. As authDir is * supposed to be /var/run/xauth or /tmp, we needn't to care for it. */ #ifdef XDMCP init_session_id(); #else Debug( "not compiled for XDMCP\n" ); #endif if (pipe( signalFds )) LogPanic( "Unable to create signal notification pipe.\n" ); RegisterInput( signalFds[0] ); RegisterCloseOnFork( signalFds[0] ); RegisterCloseOnFork( signalFds[1] ); (void)Signal( SIGTERM, SigHandler ); (void)Signal( SIGINT, SigHandler ); (void)Signal( SIGHUP, SigHandler ); (void)Signal( SIGCHLD, SigHandler ); (void)Signal( SIGUSR1, SigHandler ); /* * Step 2 - run a sub-daemon for each entry */ #ifdef XDMCP UpdateListenSockets(); #endif openCtrl( 0 ); MainLoop(); closeCtrl( 0 ); if (sdRec.how) { commitBootOption(); if (Fork() <= 0) { char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot; execute( parseArgs( (char **)0, cmd ), (char **)0 ); LogError( "Failed to execute shutdown command %\"s\n", cmd ); exit( 1 ); } else { sigset_t mask; sigemptyset( &mask ); sigaddset( &mask, SIGCHLD ); sigaddset( &mask, SIGHUP ); sigsuspend( &mask ); } } Debug( "nothing left to do, exiting\n" ); return 0; }
int testTagData(void) { SockInfo sock0; SockInfo sock1; int res; int total_errors = 0; int ctrl_fd = -1; int dev_fd = -1; const uint64_t invalid_tag1 = 0x0000000100000001llu; uint64_t valid_tag1; uint64_t valid_tag2; uint64_t max_uint_tag = 0xffffffff00000000llu; uid_t fake_uid; uid_t fake_uid2; const char *test_name; uid_t my_uid = getuid(); pid_t my_pid = getpid(); const int max_tags = 5; srand48(my_pid * my_uid); /* Adjust fake UIDs and tags so that multiple instances can run in parallel. */ fake_uid = testRand(); fake_uid2 = testRand(); valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); valid_tag2 &= 0xffffff00ffffffffllu; // Leave some room to make counts visible. testSetLogCatTag(LOG_TAG); testPrintI("** %s ** ============================", __FUNCTION__); testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu" " tag1=0x%llx/%llu tag2=0x%llx/%llu", my_pid, my_uid, fake_uid, fake_uid, fake_uid2, fake_uid2, valid_tag1, valid_tag1, valid_tag2, valid_tag2); // --------------- test_name = "kernel has qtaguid"; testPrintI("* test: %s ", test_name); ctrl_fd = openCtrl(); if (ctrl_fd < 0) { testPrintE("qtaguid ctrl open failed: %s", strerror(errno)); return 1; } close(ctrl_fd); dev_fd = open("/dev/xt_qtaguid", O_RDONLY); if (dev_fd < 0) { testPrintE("! %s: qtaguid dev open failed: %s", test_name, strerror(errno)); total_errors++; } // --------------- test_name = "delete command doesn't fail"; testPrintI("* test: %s", test_name); res = doCtrlCommand("d 0 %u", fake_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } res = doCtrlCommand("d 0 %u", fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } res = doCtrlCommand("d 0 %u", my_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } // --------------- test_name = "setup sock0 and addr via tag"; testPrintI("* test: %s", test_name); if (sock0.setup(valid_tag1)) { testPrintE("socket setup failed: %s", strerror(errno)); return 1; } // --------------- test_name = "setup sock1 and addr via tag"; testPrintI("* test: %s", test_name); if (sock1.setup(valid_tag1)) { testPrintE("socket setup failed: %s", strerror(errno)); return 1; } // --------------- test_name = "setup tag limit"; testPrintI("* test: %s ", test_name); char *max_tags_str; asprintf(&max_tags_str, "%d", max_tags); res = writeModuleParam("max_sock_tags", max_tags_str); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); free(max_tags_str); return 1; } // --------------- test_name = "tag quota reach limit"; testPrintI("* test: %s", test_name); for (int cnt = 0; cnt < max_tags; cnt++ ) { uint64_t new_tag = valid_tag2 + ((uint64_t)cnt << 32); res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(new_tag, fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } } test_name = "tag quota go over limit"; testPrintI("* test: %s", test_name); { uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32); res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } } // --------------- test_name = "valid untag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("u %d", sock0.fd); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(valid_tag2 + (((uint64_t)max_tags - 1) << 32), fake_uid2)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } // --------------- test_name = "tag after untag shouldn't free up max tags"; testPrintI("* test: %s", test_name); { uint64_t new_tag = valid_tag2 + ((uint64_t)max_tags << 32); res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(valid_tag2 + ((uint64_t)max_tags << 32), fake_uid2)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } } // --------------- test_name = "delete one tag"; testPrintI("* test: %s", test_name); { uint64_t new_tag = valid_tag2 + (((uint64_t)max_tags / 2) << 32); res = doCtrlCommand("d %llu %u", new_tag, fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } } // --------------- test_name = "2 tags after 1 delete pass/fail"; testPrintI("* test: %s", test_name); { uint64_t new_tag; new_tag = valid_tag2 + (((uint64_t)max_tags + 1 ) << 32); res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 1) << 32), fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } new_tag = valid_tag2 + (((uint64_t)max_tags + 2 ) << 32); res = doCtrlCommand("t %d %llu %u", sock0.fd, new_tag , fake_uid2); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(valid_tag2 + (((uint64_t)max_tags + 2) << 32), fake_uid2)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } } /* TODO(jpa): test tagging two different sockets with same tags and * check refcounts the tag_node should be +2 */ // --------------- if (total_errors) { testPrintE("! Errors found"); } else { testPrintI("No Errors found"); } done: if (dev_fd >= 0) { close(dev_fd); } if (ctrl_fd >= 0) { close(ctrl_fd); } return total_errors; }
/*----------------------------------------------------------------*/ int testSocketTagging(void) { SockInfo sock0; SockInfo sock1; int res; int total_errors = 0; int ctrl_fd = -1; int dev_fd = -1; const uint64_t invalid_tag1 = 0x0000000100000001llu; uint64_t valid_tag1; uint64_t valid_tag2; uint64_t max_uint_tag = 0xffffffff00000000llu; uid_t fake_uid; uid_t fake_uid2; const char *test_name; uid_t my_uid = getuid(); pid_t my_pid = getpid(); srand48(my_pid * my_uid); /* Adjust fake UIDs and tags so that multiple instances can run in parallel. */ fake_uid = testRand(); fake_uid2 = testRand(); valid_tag1 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); valid_tag2 = ((uint64_t)my_pid << 48) | ((uint64_t)testRand() << 32); max_uint_tag = 1llu << 63 | (((uint64_t)my_pid << 48) ^ max_uint_tag); testSetLogCatTag(LOG_TAG); testPrintI("** %s ** ============================", __FUNCTION__); testPrintI("* start: pid=%lu uid=%lu uid1=0x%lx/%lu uid2=0x%lx/%lu" " tag1=0x%llx/%llu tag2=0x%llx/%llu", my_pid, my_uid, fake_uid, fake_uid, fake_uid2, fake_uid2, valid_tag1, valid_tag1, valid_tag2, valid_tag2); // --------------- test_name = "kernel has qtaguid"; testPrintI("* test: %s ", test_name); ctrl_fd = openCtrl(); if (ctrl_fd < 0) { testPrintE("qtaguid ctrl open failed: %s", strerror(errno)); total_errors++; goto done; } close(ctrl_fd); dev_fd = open("/dev/xt_qtaguid", O_RDONLY); if (dev_fd < 0) { testPrintE("qtaguid dev open failed: %s", strerror(errno)); total_errors++; } // --------------- test_name = "delete command doesn't fail"; testPrintI("* test: %s", test_name); res = doCtrlCommand("d 0 %u", fake_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } res = doCtrlCommand("d 0 %u", fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } res = doCtrlCommand("d 0 %u", my_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } // --------------- test_name = "setup sock0 and addr via tag"; testPrintI("* test: %s", test_name); if (sock0.setup(valid_tag1) < 0) { testPrintE("socket setup failed: %s", strerror(errno)); total_errors++; goto done; } // --------------- test_name = "setup sock1 and addr via tag"; testPrintI("* test: %s", test_name); if (sock1.setup(valid_tag1) < 0) { testPrintE("socket setup failed: %s", strerror(errno)); total_errors++; goto done; } // --------------- test_name = "insufficient args. Expected failure"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t"); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } // --------------- test_name = "bad command. Expected failure"; testPrintI("* test: %s", test_name); res = doCtrlCommand("?"); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } // --------------- test_name = "no tag, no uid"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d", sock0.fd); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(0, my_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "invalid tag. Expected failure"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu", sock0.fd, invalid_tag1); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(invalid_tag1, my_uid)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } // --------------- test_name = "valid tag with no uid"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu", sock0.fd, valid_tag1); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag1, my_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "valid untag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("u %d", sock0.fd); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(valid_tag1, my_uid)) { testPrintE("! %s: Unexpected results: tag not removed", test_name); total_errors++; } // --------------- test_name = "valid 1st tag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag2, fake_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "valid re-tag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag2, fake_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "valid re-tag with acct_tag change"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, fake_uid); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag1, fake_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "re-tag with uid change"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag2, fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(valid_tag2, fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "valid 64bit acct tag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu", sock0.fd, max_uint_tag); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock0.checkTag(max_uint_tag, my_uid)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "tag another socket"; testPrintI("* test: %s", test_name); res = doCtrlCommand("t %d %llu %u", sock1.fd, valid_tag1, fake_uid2); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (!sock1.checkTag(valid_tag1, fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } // --------------- test_name = "valid untag"; testPrintI("* test: %s", test_name); res = doCtrlCommand("u %d", sock0.fd); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(max_uint_tag, fake_uid)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } if (!sock1.checkTag(valid_tag1, fake_uid2)) { testPrintE("! %s: Unexpected results: tag not found", test_name); total_errors++; } res = doCtrlCommand("u %d", sock1.fd); if (res < 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock1.checkTag(valid_tag1, fake_uid2)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } // --------------- test_name = "invalid sock0.fd. Expected failure"; testPrintI("* test: %s", test_name); close(sock0.fd); res = doCtrlCommand("t %d %llu %u", sock0.fd, valid_tag1, my_uid); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (sock0.checkTag(valid_tag1, my_uid)) { testPrintE("! %s: Unexpected results: tag should not be there", test_name); total_errors++; } // --------------- test_name = "invalid untag. Expected failure"; testPrintI("* test: %s", test_name); close(sock1.fd); res = doCtrlCommand("u %d", sock1.fd); if (res > 0) { testPrintE("! %s: Unexpected results", test_name); total_errors++; } if (total_errors) { testPrintE("! Errors found"); } else { testPrintI("No Errors found"); } done: if (dev_fd >= 0) { close(dev_fd); } if (ctrl_fd >= 0) { close(ctrl_fd); } return total_errors; }