void testChown() { this->catalog->setOwner(FOLDER, -1, getGid(ctx, 1)); dmlite::ExtendedStat stat = this->catalog->extendedStat(FOLDER); CPPUNIT_ASSERT_EQUAL((size_t)4, stat.acl.size()); CPPUNIT_ASSERT_EQUAL(dmlite::AclEntry::kUserObj, stat.acl[0].type); CPPUNIT_ASSERT_EQUAL(getUid(ctx), stat.acl[0].id); CPPUNIT_ASSERT_EQUAL(7u, (unsigned)stat.acl[0].perm); CPPUNIT_ASSERT_EQUAL(dmlite::AclEntry::kGroupObj, stat.acl[1].type); CPPUNIT_ASSERT_EQUAL(getGid(ctx, 1), stat.acl[1].id); CPPUNIT_ASSERT_EQUAL(0u, (unsigned)stat.acl[1].perm); }
void Scheduler::notifyFutexWaitWoken(uint32_t pid, uint32_t tid) { futex_lock(&schedLock); ThreadInfo* th = gidMap[getGid(pid, tid)]; DEBUG_FUTEX("[%d/%d] waitWoken", pid, tid); th->futexJoin = {FJA_WAIT, 0, 0}; futex_unlock(&schedLock); }
uint64_t Scheduler::getFutexWakePhase(bool realtime, FutexInfo fi, CONTEXT* ctxt, SYSCALL_STANDARD std) { int64_t waitNsec = 0; uint64_t wakeupPhase = 0; waitNsec = fi.timeout.tv_sec*1000000000L + fi.timeout.tv_nsec; if (fi.op & FUTEX_CLOCK_REALTIME || realtime) { uint32_t domain = zinfo->procArray[procIdx]->getClockDomain(); uint64_t simNs = cyclesToNs(zinfo->globPhaseCycles); uint64_t offsetNs = simNs + zinfo->clockDomainInfo[domain].realtimeOffsetNs; warn(" REALTIME FUTEX: %ld %ld %ld %ld", waitNsec, simNs, offsetNs, waitNsec-offsetNs); waitNsec = (waitNsec > (int64_t)offsetNs)? (waitNsec - offsetNs) : 0; } if (waitNsec > 0) { struct timespec fakeTimeouts = (struct timespec){0}; //Never timeout. PIN_SetSyscallArgument(ctxt, std, 3, (ADDRINT)&fakeTimeouts); uint64_t waitCycles = waitNsec*zinfo->freqMHz/1000; uint64_t waitPhases = waitCycles/zinfo->phaseLength; wakeupPhase = zinfo->numPhases + waitPhases; } return wakeupPhase; } bool Scheduler::futexSynchronized(uint32_t pid, uint32_t tid, FutexInfo fi) { futex_lock(&schedLock); uint32_t gid = getGid(pid, tid); ThreadInfo* th = gidMap[gid]; futex_unlock(&schedLock); while (true) { int futex_res = syscall(SYS_futex, th->futexWord, FUTEX_WAIT, 1 /*a racing thread waking us up will change value to 0, and we won't block*/, nullptr, nullptr, 0); if (futex_res == 0 || th->futexWord != 1) break; } join(pid, tid); return true; }
void Scheduler::notifyFutexWakeEnd(uint32_t pid, uint32_t tid, uint32_t wokenUp) { futex_lock(&schedLock); ThreadInfo* th = gidMap[getGid(pid, tid)]; DEBUG_FUTEX("[%d/%d] wakeEnd woken %d", pid, tid, wokenUp); th->futexJoin.action = FJA_WAKE; th->futexJoin.wokenUp = wokenUp; futex_unlock(&schedLock); }
/*! Set the group identity for the process. Returns 0 on success. */ int Process::setgid (const char *gid) { #ifndef WIN32 if (gid && gid[0]) return ::setgid (getGid (gid)); #endif return 0; }
//Must be called without lock. Returns # waiters. int Scheduler::futexWakeNWaiters(int bitmask, bool p_waiter, int *uaddr, int val) { DEBUG_FUTEX("Scheduler: FUTEX WAKE N WAITERS called with bitmask %d pi %d uaddr %p val %d", bitmask, p_waiter, uaddr, val); futex_lock(&schedLock); int waitersToWake = 0; int waitersFailed = 0; bool piWakeInUserSpace = ((futexTable[uaddr].size() == 1) && futexTable[uaddr].front().pi_waiter); assert(!piWakeInUserSpace) if(p_waiter) { for(int i = 1; (uint32_t)i < futexTable[uaddr].size(); i++) { if(futexTable[uaddr][i].pi_waiter) { FutexWaiter tempWaiter = futexTable[uaddr][i]; futexTable[uaddr].erase(futexTable[uaddr].begin() + waitersFailed); futexTable[uaddr].push_front(tempWaiter); DEBUG_FUTEX("we had a pi requestor jump to front of line"); uint32_t gid = getGid(tempWaiter.pid, tempWaiter.tid); ThreadInfo* th = gidMap[gid]; assert(th->state == SLEEPING); notifySleepEnd(tempWaiter.pid, tempWaiter.tid); wakeup(th, true); futex_unlock(&schedLock); return 1; } } } while((uint32_t)waitersToWake < futexTable[uaddr].size() && waitersToWake < val) { FutexWaiter tempWaiter = futexTable[uaddr][waitersFailed]; if(bitmask && tempWaiter.mask & ~bitmask) { waitersFailed++; } else { waitersToWake++; futexTable[uaddr].erase(futexTable[uaddr].begin() + waitersFailed); } uint32_t gid = getGid(tempWaiter.pid, tempWaiter.tid); ThreadInfo* th = gidMap[gid]; assert(th->state == SLEEPING); notifySleepEnd(tempWaiter.pid, tempWaiter.tid); DEBUG_FUTEX("WAKE N finished sleep end"); wakeup(th, true); DEBUG_FUTEX("WAKE N finished wakeup"); } DEBUG_FUTEX("WAKE N WAITERS Looped %d times", waitersFailed + waitersToWake); futex_unlock(&schedLock); return waitersToWake; }
sf::IntRect TileLoader::getTextureRect(int x, int y, const char* layerName) { int gid = getGid(x, y, layerName); if (gid != 0) { sf::Vector2i coords = getTextureCoords(x, y, layerName); return sf::IntRect(coords.x * mTileWidth, coords.y *mTileHeight, mTileWidth, mTileHeight); } // No Texture return sf::IntRect(-1,-1,-1,-1); }
// External interface, must be non-blocking void Scheduler::notifyFutexWakeStart(uint32_t pid, uint32_t tid, uint32_t maxWakes) { futex_lock(&schedLock); ThreadInfo* th = gidMap[getGid(pid, tid)]; DEBUG_FUTEX("[%d/%d] wakeStart max %d", pid, tid, maxWakes); assert(th->futexJoin.action == FJA_NONE); // Programs sometimes call FUTEX_WAIT with maxWakes = UINT_MAX to wake // everyone waiting on it; we cap to a reasonably high number to avoid // overflows on maxAllowedFutexWakeups maxWakes = MIN(maxWakes, 1<<24 /*16M wakes*/); maxAllowedFutexWakeups += maxWakes; th->futexJoin.maxWakes = maxWakes; futex_unlock(&schedLock); }
void setUp() { TestBase::setUp(); this->stackInstance->setSecurityCredentials(cred1); ctx = this->stackInstance->getSecurityContext(); std::stringstream ss; ss << "A7" << getUid(ctx) << ",C0" << getGid(ctx) << ",E70,F50"; ACL = dmlite::Acl(ss.str()); this->catalog->makeDir(FOLDER, 0700); this->catalog->setAcl(FOLDER, ACL); }
// Get the coordinates of the texture from the gid sf::Vector2i TileLoader::getTextureCoords(int x, int y, const char* layerName) { int gid = getGid(x, y, layerName); int index = getTilesetIndex(gid); gid -= mTilesetFirstGids[index]; int tilesetGridHeight = mTileset[index].imageheight / mTileset[index].tileheight; int tilesetGridWidth = mTileset[index].imagewidth / mTileset[index].tilewidth; int gidx = (gid % tilesetGridWidth); int gidy = 0; while(gid > gidx) { gid = gid - tilesetGridWidth; gidy++; } return sf::Vector2i(gidx, gidy); }
void testInherit() { // Set default ACL's dmlite::Acl parentAcl("A70,C00,E70,F50,a60,c50,f00"); this->catalog->setAcl(FOLDER, parentAcl); dmlite::ExtendedStat parent = this->catalog->extendedStat(FOLDER); // Make dir this->catalog->makeDir(NESTED, 0700); dmlite::ExtendedStat stat = this->catalog->extendedStat(NESTED); // Assert resulting ACL std::stringstream aclStr; aclStr << "A6" << getUid(ctx) << ",C0" << getGid(ctx) << ",F00,a60,c50,f00"; CPPUNIT_ASSERT_EQUAL(dmlite::Acl(aclStr.str()), stat.acl); }
void testChmod() { this->catalog->setMode(FOLDER, 0555); dmlite::ExtendedStat stat = this->catalog->extendedStat(FOLDER); CPPUNIT_ASSERT_EQUAL((size_t)4, stat.acl.size()); CPPUNIT_ASSERT_EQUAL(dmlite::AclEntry::kUserObj, stat.acl[0].type); CPPUNIT_ASSERT_EQUAL(getUid(ctx), stat.acl[0].id); CPPUNIT_ASSERT_EQUAL(5u, (unsigned)stat.acl[0].perm); CPPUNIT_ASSERT_EQUAL(dmlite::AclEntry::kGroupObj, stat.acl[1].type); CPPUNIT_ASSERT_EQUAL(getGid(ctx, 0), stat.acl[1].id); CPPUNIT_ASSERT_EQUAL(5u, (unsigned)stat.acl[1].perm); CPPUNIT_ASSERT_EQUAL(dmlite::AclEntry::kOther, stat.acl[3].type); CPPUNIT_ASSERT_EQUAL(5u, (unsigned)stat.acl[3].perm); }
// Accurate join-leave implementation void Scheduler::syscallLeave(uint32_t pid, uint32_t tid, uint32_t cid, uint64_t pc, int syscallNumber, uint64_t arg0, uint64_t arg1) { futex_lock(&schedLock); uint32_t gid = getGid(pid, tid); ThreadInfo* th = contexts[cid].curThread; assert(th->gid == gid); assert_msg(th->cid == cid, "%d != %d", th->cid, cid); assert(th->state == RUNNING); assert_msg(pid < blockingSyscalls.size(), "%d >= %ld?", pid, blockingSyscalls.size()); bool blacklisted = blockingSyscalls[pid].find(pc) != blockingSyscalls[pid].end(); if (blacklisted || th->markedForSleep) { DEBUG_FL("%s @ 0x%lx calling leave(), reason: %s", GetSyscallName(syscallNumber), pc, blacklisted? "blacklist" : "sleep"); futex_unlock(&schedLock); leave(pid, tid, cid); } else { DEBUG_FL("%s @ 0x%lx skipping leave()", GetSyscallName(syscallNumber), pc); FakeLeaveInfo* si = new FakeLeaveInfo(pc, th, syscallNumber, arg0, arg1); fakeLeaves.push_back(si); // FIXME(dsm): zsim.cpp's SyscallEnter may be checking whether we are in a syscall and not calling us. // If that's the case, this would be stale, which may lead to some false positives/negatives futex_unlock(&schedLock); } }
/*! Start the server. */ void Server::start (string &mainConf, string &mimeConf, string &vhostConf, string &externPath, MainConfiguration* (*genMainConf) (Server *server, const char *arg)) { int err = 0; this->genMainConf = genMainConf; displayBoot (); try { log (MYSERVER_LOG_MSG_INFO, _("Initializing server configuration...")); if (loadLibraries ()) { log (MYSERVER_LOG_MSG_INFO, _("The server could not be started")); return; } if (!resetConfigurationPaths (mainConf, mimeConf, vhostConf, externPath)) { log (MYSERVER_LOG_MSG_INFO, _("The server could not be started")); return; } err = initialize (); if (err) { log (MYSERVER_LOG_MSG_INFO, _("The server could not be started")); return; } log (MYSERVER_LOG_MSG_INFO, _("Loading server configuration from %s..."), mainConf.c_str ()); if (postLoad ()) { log (MYSERVER_LOG_MSG_INFO, _("The server could not be started")); return; } setProcessPermissions (); if (getGid ()[0]) log (MYSERVER_LOG_MSG_INFO, _("Using gid: %s"), gid.c_str ()); if (getUid ()[0]) log (MYSERVER_LOG_MSG_INFO, _("Using uid: %s"), uid.c_str ()); log (MYSERVER_LOG_MSG_INFO, _("Server is ready!")); if (logLocation.find ("console://") != string::npos) log (MYSERVER_LOG_MSG_INFO, _("Press Ctrl-C to terminate its execution")); serverReady = true; /* Finally we can give control to the main loop. */ mainLoop (); } catch (bad_alloc &ba) { log (MYSERVER_LOG_MSG_ERROR, _("Bad alloc: %s"), ba.what ()); } catch (exception &e) { log (MYSERVER_LOG_MSG_ERROR, _("Error: %s"), e.what ()); }; this->terminate (); finalCleanup (); #ifdef WIN32 WSACleanup (); #endif log (MYSERVER_LOG_MSG_INFO, _("Server terminated")); }
bool Scheduler::futexWait(bool bitmask, bool pi_waiter, uint32_t pid, uint32_t tid, FutexInfo fi, CONTEXT* ctxt, SYSCALL_STANDARD std) { DEBUG_FUTEX("Scheduler: FUTEX WAIT called with bitmask %d pi %d pid %u tid %u", bitmask, pi_waiter, pid, tid); uint64_t wakeUpPhases = getFutexWakePhase(pi_waiter, fi, ctxt, std); //pi versions all interpret as realtime futex_lock(&schedLock); uint32_t cid = gidMap[getGid(pid, tid)]->cid; futex_unlock(&schedLock); if(wakeUpPhases == 0) { wakeUpPhases = 0xffffffff; } FutexWaiter tempWaiter; tempWaiter.pid = pid; tempWaiter.tid = tid; tempWaiter.pi_waiter = pi_waiter; tempWaiter.mask = 0xffffffff; tempWaiter.val = fi.val; tempWaiter.fi = fi; tempWaiter.allow_requeue = !pi_waiter; if(!pi_waiter) { //Normal cases if(fi.val != *fi.uaddr) { DEBUG_FUTEX("Cur val didn't match val in futex wait"); return false; } DEBUG_FUTEX("WAIT took normal path"); if(bitmask) { tempWaiter.mask = fi.val3; } futexTable[fi.uaddr].push_back(tempWaiter); markForSleep(pid, tid, wakeUpPhases); leave(pid, tid, cid); } else { //if pi_waiter switch (fi.op & FUTEX_CMD_MASK) { case FUTEX_LOCK_PI: DEBUG_FUTEX("WAIT took lock path"); if(futexTable[fi.uaddr].size() == 0) // Check that no one else is in line. { DEBUG_FUTEX("FUTEX_LOCK_PI successfully locked"); futexTable[fi.uaddr].push_back(tempWaiter); //Notice we don't deschedule return true; } else { DEBUG_FUTEX("LOCK delayed"); if(bitmask) { tempWaiter.mask = fi.val3; } futexTable[fi.uaddr].push_back(tempWaiter); markForSleep(pid, tid, wakeUpPhases); leave(pid, tid, cid); } break; case FUTEX_WAIT_REQUEUE_PI: DEBUG_FUTEX("WAIT took reque pi path"); if(fi.val != *fi.uaddr) { DEBUG_FUTEX("Cur val didn't match val in futex wait"); return false; } tempWaiter.allow_requeue = true; if(bitmask) { tempWaiter.mask = fi.val3; } markForSleep(pid, tid, wakeUpPhases); leave(pid, tid, cid); futexTable[fi.uaddr].push_back(tempWaiter); break; case FUTEX_TRYLOCK_PI: DEBUG_FUTEX("WAIT took trylock path"); if(futexTable[fi.uaddr].size() == 0) { DEBUG_FUTEX("FUTEX_LOCK_PI successfully locked"); futexTable[fi.uaddr].push_back(tempWaiter); //Notice we don't deschedule return true; } else { return false; } break; default: panic("We missed something in futex wait."); } } return true; }
ListeDescripteurs liste(char* nom_fichier, bool affichage) { int fd = open(nom_fichier, O_RDONLY); if (fd == -1) { printf("%s n'a pas pu être ouvert... Merci de vérifier son chemin\n", nom_fichier); return NULL; } //printf("Avant lseek\n"); off_t finDescripteurs = lseek(fd, ((-1) * sizeof(uint)), SEEK_END); //on se met au descripteur global d'archive uint archive; //printf("avant read\n"); read(fd, &archive, 32); //printf("avant premierDescripteur\n"); off_t premierDescripteur = getPremierDescripteur(archive); //on construit le 1° descripteur lseek(fd, premierDescripteur, SEEK_SET); uint bufferDescripteursBruts; uint* descripteursBruts = malloc(255 * sizeof(uint)); int lus; int i=0; while((lus = read(fd, &bufferDescripteursBruts, sizeof(uint))) > 0){ descripteursBruts[i] = bufferDescripteursBruts; } // On a récupérer les descripteurs en "brut" (que des int qui se suivent) if(descripteursBruts == NULL){ printf("le buffer est vide\n"); } // Cette fonction nous créé une liste de descripteurs ListeDescripteurs liste = getIntToDescripteurs(descripteursBruts); // partie affichage if (affichage) { int j; printf("type:date:nom"); if (affiche) printf(":taille(octets):uid:gid:droits"); printf("\n"); int profTab = 0; if(courant(liste) == NULL){ printf("Erreur : impossible de récupérer la configuration de l'archive\n"); detruireListeDescripteurs(liste); return NULL; } do{ char* espacement_actuel = ""; profTab = getProfondeur(courant(liste)); for (j = 0; j < profTab; j++) { //tabulation par rapport a la profondeur du fichier strcat(espacement_actuel, espacement); } char* nameS = getFilename(courant(liste)); printf("nom de fichier%s\n", getNbCarac(courant(liste))); printf("%s->%u:%u:%s", espacement_actuel, getType(courant(liste)), getDate(courant(liste)), nameS), getFilename(courant(liste)); if (affiche) { //le reste des parametres de l'archive si demandé printf(":%u:%u:%u:%u", getTailleFichier(courant(liste)), getUid(courant(liste)), getGid(courant(liste)), getDroits(courant(liste))); } printf("\n"); }while(suivant(liste)); } close(fd); return liste; }
// Return a reference to the texture given by the layer string sf::Texture& TileLoader::getTexture(int x, int y, const char* layerName) { int gid = getGid(x, y, layerName); return mTileset[getTilesetIndex(gid)].texture; }