static int mem_stat(resmgr_context_t *ctp, io_stat_t *msg, void *vocb) { struct mem_ocb *ocb = vocb; union object *obp = ocb ? ocb->object : 0; size_t size = ocb ? (obp ? OBJECT_SIZE(obp) : UINT_MAX) : 0; memset(&msg->o, 0x00, sizeof msg->o); msg->o.st_size = size; msg->o.st_nblocks = (size + (__PAGESIZE-1)) / __PAGESIZE; msg->o.st_blocksize = msg->o.st_blksize = __PAGESIZE; msg->o.st_ctime = msg->o.st_mtime = msg->o.st_atime =(obp ? obp->mem.pm.mtime : time(0)); msg->o.st_ino = obp ? (uintptr_t)INODE_XOR(obp) : 1; if(ocb && obp) { msg->o.st_uid = obp->mem.pm.uid; msg->o.st_gid = obp->mem.pm.gid; msg->o.st_mode = (obp->mem.pm.mode != 0) ? obp->mem.pm.mode : S_IFNAM | S_IPERMS; msg->o.st_nlink = obp->hdr.refs; msg->o.st_dev = path_devno; msg->o.st_rdev = S_ISNAM(msg->o.st_mode) ? S_INSHD : 0; } else { //The /dev/mem device is set to rw root only, the /dev/shmem //device is set to rwx for all, since it is un-enforced. msg->o.st_mode = ocb ? S_IFREG | 0600 : S_IFDIR | 0777; msg->o.st_nlink = ocb ? 1 : 2; msg->o.st_dev = mem_devno; msg->o.st_rdev = 0; } msg->o.st_dev |= (ctp->info.srcnd << ND_NODE_BITS); return _RESMGR_PTR(ctp, &msg->o, sizeof msg->o); }
const char * string_perm (mode_t mode_bits) { static char mode[11]; strcpy (mode, "----------"); if (S_ISDIR (mode_bits)) mode[0] = 'd'; if (S_ISCHR (mode_bits)) mode[0] = 'c'; if (S_ISBLK (mode_bits)) mode[0] = 'b'; if (S_ISLNK (mode_bits)) mode[0] = 'l'; if (S_ISFIFO (mode_bits)) mode[0] = 'p'; if (S_ISNAM (mode_bits)) mode[0] = 'n'; if (S_ISSOCK (mode_bits)) mode[0] = 's'; if (S_ISDOOR (mode_bits)) mode[0] = 'D'; if (ismode (mode_bits, S_IXOTH)) mode[9] = 'x'; if (ismode (mode_bits, S_IWOTH)) mode[8] = 'w'; if (ismode (mode_bits, S_IROTH)) mode[7] = 'r'; if (ismode (mode_bits, S_IXGRP)) mode[6] = 'x'; if (ismode (mode_bits, S_IWGRP)) mode[5] = 'w'; if (ismode (mode_bits, S_IRGRP)) mode[4] = 'r'; if (ismode (mode_bits, S_IXUSR)) mode[3] = 'x'; if (ismode (mode_bits, S_IWUSR)) mode[2] = 'w'; if (ismode (mode_bits, S_IRUSR)) mode[1] = 'r'; #ifdef S_ISUID if (ismode (mode_bits, S_ISUID)) mode[3] = (mode[3] == 'x') ? 's' : 'S'; #endif /* S_ISUID */ #ifdef S_ISGID if (ismode (mode_bits, S_ISGID)) mode[6] = (mode[6] == 'x') ? 's' : 'S'; #endif /* S_ISGID */ #ifdef S_ISVTX if (ismode (mode_bits, S_ISVTX)) mode[9] = (mode[9] == 'x') ? 't' : 'T'; #endif /* S_ISVTX */ return mode; }
static char ftypelet (mode_t bits) { if (S_ISBLK (bits)) return 'b'; if (S_ISCHR (bits)) return 'c'; if (S_ISDIR (bits)) return 'd'; if (S_ISREG (bits)) return '-'; if (S_ISFIFO (bits)) return 'p'; if (S_ISLNK (bits)) return 'l'; if (S_ISSOCK (bits)) return 's'; if (S_ISMPC (bits)) return 'm'; if (S_ISNWK (bits)) return 'n'; if (S_ISDOOR (bits)) return 'D'; if (S_ISCTG (bits)) return 'C'; /* Added by Alexander Lamaison for Swish project */ if (S_ISWHT (bits)) return 'w'; if (S_ISMPB (bits)) return 'B'; if (S_ISNAM (bits)) return 'x'; /* Added 2006.08.20 */ /* The following two tests are for Cray DMF (Data Migration Facility), which is a HSM file system. A migrated file has a `st_dm_mode' that is different from the normal `st_mode', so any tests for migrated files should use the former. */ if (S_ISOFD (bits)) /* off line, with data */ return 'M'; /* off line, with no data */ if (S_ISOFL (bits)) return 'M'; return '?'; }
/* make permissions string from file mode */ char *str_mode(mode_t fmode) { static char perms[1+3+3+3+1]; /* static so we can return it */ char *p = perms; /* directory ? */ if (S_ISDIR(fmode)) *p='d'; else if (S_ISNAM(fmode)) *p='n'; else if (S_ISLNK(fmode)) *p='l'; else if (S_ISCHR(fmode)) *p='c'; else if (S_ISBLK(fmode)) *p='b'; else if (S_ISSOCK(fmode)) *p='s'; else if (S_ISFIFO(fmode)) *p='p'; else *p='-'; p++; /* Handle USER permissions */ *p++ = (fmode & S_IRUSR) ? 'r' : '-'; *p++ = (fmode & S_IWUSR) ? 'w' : '-'; if (fmode & S_ISUID) *p++ = (fmode & S_IXUSR) ? 's' : 'S'; else *p++ = (fmode & S_IXUSR) ? 'x' : '-'; /* Handle GROUP permissions */ *p++ = (fmode & S_IRGRP) ? 'r' : '-'; *p++ = (fmode & S_IWGRP) ? 'w' : '-'; if (fmode & S_ISGID) *p++ = (fmode & S_IXGRP) ? 's' : 'L'; else *p++ = (fmode & S_IXGRP) ? 'x' : '-'; /* Handle OTHER permissions */ *p++ = (fmode & S_IROTH) ? 'r' : '-'; *p++ = (fmode & S_IWOTH) ? 'w' : '-'; if (fmode & S_ISVTX) *p++ = (fmode & S_IXOTH) ? 't' : 'T'; else *p++ = (fmode & S_IXOTH) ? 'x' : '-'; *p = 0; return perms; }
static int mem_change_attr(resmgr_context_t *ctp, resmgr_iomsgs_t *msg, void *vocb) { iofunc_ocb_t nocb; iofunc_attr_t attr; struct mem_ocb *ocb = vocb; union object *obp; int ret; if(!ocb || !(obp = ocb->object) || (!S_ISNAM(obp->mem.pm.mode) && !S_ISREG(obp->mem.pm.mode))) { return _RESMGR_DEFAULT; } memset(&nocb, 0, sizeof(nocb)); nocb.ioflag = ocb->ioflag; memset(&attr, 0, sizeof(attr)); attr.mode = obp->mem.pm.mode, attr.gid = obp->mem.pm.gid, attr.uid = obp->mem.pm.uid; switch(msg->type) { case _IO_CHOWN: if((ret = iofunc_chown(ctp, &msg->chown, &nocb, &attr)) == EOK) { obp->mem.pm.gid = attr.gid; obp->mem.pm.uid = attr.uid; } break; case _IO_CHMOD: if((ret = iofunc_chmod(ctp, &msg->chmod, &nocb, &attr)) == EOK) { obp->mem.pm.mode = attr.mode; } break; default: ret = _RESMGR_DEFAULT; break; } return ret; }
#endif S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH, S_ISUID, S_ISGID, S_ISVTX, S_ISBLK (S_IFREG), S_ISCHR (S_IFREG), S_ISDIR (S_IFREG), S_ISFIFO (S_IFREG), S_ISREG (S_IFREG), S_ISLNK (S_IFREG), S_ISSOCK (S_IFREG), S_ISDOOR (S_IFREG), S_ISMPB (S_IFREG), S_ISMPX (S_IFREG), S_ISNAM (S_IFREG), S_ISNWK (S_IFREG), S_ISPORT (S_IFREG), S_ISCTG (S_IFREG), S_ISOFD (S_IFREG), S_ISOFL (S_IFREG), S_ISWHT (S_IFREG) }; /* Sanity checks. */ verify (S_IRWXU == (S_IRUSR | S_IWUSR | S_IXUSR)); verify (S_IRWXG == (S_IRGRP | S_IWGRP | S_IXGRP)); verify (S_IRWXO == (S_IROTH | S_IWOTH | S_IXOTH)); #ifdef S_IFBLK
static int php_random_bytes(void *bytes, size_t size) { #if PHP_WIN32 /* Defer to CryptGenRandom on Windows */ if (php_win32_get_random_bytes(bytes, size) == FAILURE) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001)) arc4random_buf(bytes, size); #elif HAVE_DECL_GETRANDOM /* Linux getrandom(2) syscall */ size_t read_bytes = 0; size_t amount_to_read = 0; ssize_t n; /* Keep reading until we get enough entropy */ do { amount_to_read = size - read_bytes; /* Below, (bytes + read_bytes) is pointer arithmetic. bytes read_bytes size | | | [#######=============] (we're going to write over the = region) \\\\\\\\\\\\\ amount_to_read */ n = syscall(SYS_getrandom, bytes + read_bytes, amount_to_read, 0); if (n == -1) { if (errno == EINTR || errno == EAGAIN) { /* Try again */ continue; } /* If the syscall fails, we are doomed. The loop that calls php_random_bytes should be terminated by the exception instead of proceeding to demand more entropy. */ zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", errno); return FAILURE; } read_bytes += (size_t) n; } while (read_bytes < size); #else int fd = RANDOM_G(fd); struct stat st; size_t read_bytes = 0; ssize_t n; if (fd < 0) { #if HAVE_DEV_URANDOM fd = open("/dev/urandom", O_RDONLY); #endif if (fd < 0) { zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); return FAILURE; } /* Does the file exist and is it a character device? */ if (fstat(fd, &st) != 0 || # ifdef S_ISNAM !(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) # else !S_ISCHR(st.st_mode) # endif ) { close(fd); zend_throw_exception(zend_ce_exception, "Error reading from source device", 0); return FAILURE; } RANDOM_G(fd) = fd; } while (read_bytes < size) { n = read(fd, bytes + read_bytes, size - read_bytes); if (n <= 0) { break; } read_bytes += n; } if (read_bytes < size) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } #endif return SUCCESS; }
char const * file_type (struct stat const *st) { /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 for some of these formats. To keep diagnostics grammatical in English, the returned string must start with a consonant. */ /* Do these three first, as they're the most common. */ if (S_ISREG (st->st_mode)) return st->st_size == 0 ? _("regular empty file") : _("regular file"); if (S_ISDIR (st->st_mode)) return _("directory"); if (S_ISLNK (st->st_mode)) return _("symbolic link"); /* Do the S_TYPEIS* macros next, as they may be implemented in terms of S_ISNAM, and we want the more-specialized interpretation. */ if (S_TYPEISMQ (st)) return _("message queue"); if (S_TYPEISSEM (st)) return _("semaphore"); if (S_TYPEISSHM (st)) return _("shared memory object"); if (S_TYPEISTMO (st)) return _("typed memory object"); /* The remaining are in alphabetical order. */ if (S_ISBLK (st->st_mode)) return _("block special file"); if (S_ISCHR (st->st_mode)) return _("character special file"); if (S_ISCTG (st->st_mode)) return _("contiguous data"); if (S_ISFIFO (st->st_mode)) return _("fifo"); if (S_ISDOOR (st->st_mode)) return _("door"); if (S_ISMPB (st->st_mode)) return _("multiplexed block special file"); if (S_ISMPC (st->st_mode)) return _("multiplexed character special file"); if (S_ISMPX (st->st_mode)) return _("multiplexed file"); if (S_ISNAM (st->st_mode)) return _("named file"); if (S_ISNWK (st->st_mode)) return _("network special file"); if (S_ISOFD (st->st_mode)) return _("migrated file with data"); if (S_ISOFL (st->st_mode)) return _("migrated file without data"); if (S_ISPORT (st->st_mode)) return _("port"); if (S_ISSOCK (st->st_mode)) return _("socket"); if (S_ISWHT (st->st_mode)) return _("whiteout"); return _("weird file"); }
/* {{{ */ PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw) { #ifdef PHP_WIN32 /* Defer to CryptGenRandom on Windows */ if (php_win32_get_random_bytes(bytes, size) == FAILURE) { if (should_throw) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); } return FAILURE; } #elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001)) arc4random_buf(bytes, size); #else size_t read_bytes = 0; ssize_t n; #if defined(__linux__) && defined(SYS_getrandom) /* Linux getrandom(2) syscall */ /* Keep reading until we get enough entropy */ while (read_bytes < size) { /* Below, (bytes + read_bytes) is pointer arithmetic. bytes read_bytes size | | | [#######=============] (we're going to write over the = region) \\\\\\\\\\\\\ amount_to_read */ size_t amount_to_read = size - read_bytes; n = syscall(SYS_getrandom, bytes + read_bytes, amount_to_read, 0); if (n == -1) { if (errno == ENOSYS) { /* This can happen if PHP was compiled against a newer kernel where getrandom() * is available, but then runs on an older kernel without getrandom(). If this * happens we simply fall back to reading from /dev/urandom. */ ZEND_ASSERT(read_bytes == 0); break; } else if (errno == EINTR || errno == EAGAIN) { /* Try again */ continue; } else { /* If the syscall fails, fall back to reading from /dev/urandom */ break; } } read_bytes += (size_t) n; } #endif if (read_bytes < size) { int fd = RANDOM_G(fd); struct stat st; if (fd < 0) { #if HAVE_DEV_URANDOM fd = open("/dev/urandom", O_RDONLY); #endif if (fd < 0) { if (should_throw) { zend_throw_exception(zend_ce_exception, "Cannot open source device", 0); } return FAILURE; } /* Does the file exist and is it a character device? */ if (fstat(fd, &st) != 0 || # ifdef S_ISNAM !(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) # else !S_ISCHR(st.st_mode) # endif ) { close(fd); if (should_throw) { zend_throw_exception(zend_ce_exception, "Error reading from source device", 0); } return FAILURE; } RANDOM_G(fd) = fd; } for (read_bytes = 0; read_bytes < size; read_bytes += (size_t) n) { n = read(fd, bytes + read_bytes, size - read_bytes); if (n <= 0) { break; } } if (read_bytes < size) { if (should_throw) { zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); } return FAILURE; } } #endif return SUCCESS; }