Skip to content

Commit

Permalink
xnu-1699.24.8
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 31b714e commit 2d9567d
Show file tree
Hide file tree
Showing 41 changed files with 2,318 additions and 1,947 deletions.
3,291 changes: 1,622 additions & 1,669 deletions bsd/crypto/aes/i386/aes_modes_hw.s

Large diffs are not rendered by default.

47 changes: 38 additions & 9 deletions bsd/dev/random/randomdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <dev/random/YarrowCoreLib/include/yarrow.h>

#include <libkern/OSByteOrder.h>
#include <libkern/OSAtomic.h>

#include <mach/mach_time.h>
#include <machine/machine_routines.h>
Expand Down Expand Up @@ -101,13 +102,14 @@ static struct cdevsw random_cdevsw =


/* Used to detect whether we've already been initialized */
static int gRandomInstalled = 0;
static UInt8 gRandomInstalled = 0;
static PrngRef gPrngRef;
static int gRandomError = 1;
static lck_grp_t *gYarrowGrp;
static lck_attr_t *gYarrowAttr;
static lck_grp_attr_t *gYarrowGrpAttr;
static lck_mtx_t *gYarrowMutex = 0;
static UInt8 gYarrowInitializationLock = 0;

#define RESEED_TICKS 50 /* how long a reseed operation can take */

Expand Down Expand Up @@ -307,6 +309,27 @@ PreliminarySetup(void)
{
prng_error_status perr;

/* Multiple threads can enter this as a result of an earlier
* check of gYarrowMutex. We make sure that only one of them
* can enter at a time. If one of them enters and discovers
* that gYarrowMutex is no longer NULL, we know that another
* thread has initialized the Yarrow state and we can exit.
*/

/* The first thread that enters this function will find
* gYarrowInitializationLock set to 0. It will atomically
* set the value to 1 and, seeing that it was zero, drop
* out of the loop. Other threads will see that the value is
* 1 and continue to loop until we are initialized.
*/

while (OSTestAndSet(0, &gYarrowInitializationLock)); /* serialize access to this function */

if (gYarrowMutex) {
/* we've already been initialized, clear and get out */
goto function_exit;
}

/* create a Yarrow object */
perr = prngInitialize(&gPrngRef);
if (perr != 0) {
Expand All @@ -321,6 +344,8 @@ PreliminarySetup(void)
char buffer [16];

/* get a little non-deterministic data as an initial seed. */
/* On OSX, securityd will add much more entropy as soon as it */
/* comes up. On iOS, entropy is added with each system interrupt. */
microtime(&tt);

/*
Expand All @@ -334,7 +359,7 @@ PreliminarySetup(void)
if (perr != 0) {
/* an error, complain */
printf ("Couldn't seed Yarrow.\n");
return;
goto function_exit;
}

/* turn the data around */
Expand All @@ -350,6 +375,10 @@ PreliminarySetup(void)
gYarrowMutex = lck_mtx_alloc_init(gYarrowGrp, gYarrowAttr);

fips_initialize ();

function_exit:
/* allow other threads to figure out whether or not we have been initialized. */
gYarrowInitializationLock = 0;
}

const Block kKnownAnswer = {0x92, 0xb4, 0x04, 0xe5, 0x56, 0x58, 0x8c, 0xed, 0x6c, 0x1a, 0xcd, 0x4e, 0xbf, 0x05, 0x3f, 0x68, 0x09, 0xf7, 0x3a, 0x93};
Expand Down Expand Up @@ -384,14 +413,11 @@ random_init(void)
{
int ret;

if (gRandomInstalled)
if (OSTestAndSet(0, &gRandomInstalled)) {
/* do this atomically so that it works correctly with
multiple threads */
return;

/* install us in the file system */
gRandomInstalled = 1;

/* setup yarrow and the mutex */
PreliminarySetup();
}

ret = cdevsw_add(RANDOM_MAJOR, &random_cdevsw);
if (ret < 0) {
Expand All @@ -409,6 +435,9 @@ random_init(void)
*/
devfs_make_node(makedev (ret, 1), DEVFS_CHAR,
UID_ROOT, GID_WHEEL, 0666, "urandom", 0);

/* setup yarrow and the mutex if needed*/
PreliminarySetup();
}

int
Expand Down
38 changes: 36 additions & 2 deletions bsd/hfs/hfs_catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,22 @@ cat_create(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr

buildthreadkey(nextCNID, std_hfs, (CatalogKey *) &bto->iterator.key);

result = BTInsertRecord(fcb, &bto->iterator, &btdata, datalen);
/*
* If the CNID wraparound bit is set, then we need to validate if there
* is a cnode in the hash already with this ID (even if it no longer exists
* on disk). If so, then just skip this ID and move on to the next one.
*/
if (!std_hfs && (hfsmp->vcbAtrb & kHFSCatalogNodeIDsReusedMask)) {
if (hfs_chash_snoop (hfsmp, nextCNID, 1, NULL, NULL) == 0) {
/* It was found in the cnode hash!*/
result = btExists;
}
}

if (result == 0) {
result = BTInsertRecord(fcb, &bto->iterator, &btdata, datalen);
}

if ((result == btExists) && !std_hfs && (hfsmp->vcbAtrb & kHFSCatalogNodeIDsReusedMask)) {
/*
* Allow CNIDs on HFS Plus volumes to wrap around
Expand Down Expand Up @@ -2089,6 +2104,9 @@ cat_createlink(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *
int thread_inserted = 0;
int alias_allocated = 0;
int result = 0;
int std_hfs;

std_hfs = (hfsmp->hfs_flags & HFS_STANDARD);

fcb = hfsmp->hfs_catalog_cp->c_datafork;

Expand Down Expand Up @@ -2128,8 +2146,24 @@ cat_createlink(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *

for (;;) {
buildthreadkey(nextCNID, 0, (CatalogKey *) &bto->iterator.key);

/*
* If the CNID wraparound bit is set, then we need to validate if there
* is a cnode in the hash already with this ID (even if it no longer exists
* on disk). If so, then just skip this ID and move on to the next one.
*/
if (!std_hfs && (hfsmp->vcbAtrb & kHFSCatalogNodeIDsReusedMask)) {
/* Verify that the CNID does not already exist in the cnode hash... */
if (hfs_chash_snoop (hfsmp, nextCNID, 1, NULL, NULL) == 0) {
/* It was found in the cnode hash!*/
result = btExists;
}
}

if (result == 0) {
result = BTInsertRecord(fcb, &bto->iterator, &btdata, datalen);
}

result = BTInsertRecord(fcb, &bto->iterator, &btdata, datalen);
if ((result == btExists) && (hfsmp->vcbAtrb & kHFSCatalogNodeIDsReusedMask)) {
/*
* Allow CNIDs on HFS Plus volumes to wrap around
Expand Down
24 changes: 22 additions & 2 deletions bsd/hfs/hfs_chash.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ hfs_chash_getvnode(struct hfsmount *hfsmp, ino_t inum, int wantrsrc, int skiploc
*
*/
int
hfs_chash_snoop(struct hfsmount *hfsmp, ino_t inum, int (*callout)(const struct cat_desc *,
hfs_chash_snoop(struct hfsmount *hfsmp, ino_t inum, int existence_only, int (*callout)(const struct cat_desc *,
const struct cat_attr *, void *), void * arg)
{
struct cnode *cp;
Expand All @@ -242,7 +242,27 @@ hfs_chash_snoop(struct hfsmount *hfsmp, ino_t inum, int (*callout)(const struct
for (cp = CNODEHASH(hfsmp, inum)->lh_first; cp; cp = cp->c_hash.le_next) {
if (cp->c_fileid != inum)
continue;
/* Skip cnodes that have been removed from the catalog */

/*
* Under normal circumstances, we would want to return ENOENT if a cnode is in
* the hash and it is marked C_NOEXISTS or C_DELETED. However, if the CNID
* namespace has wrapped around, then we have the possibility of collisions.
* In that case, we may use this function to validate whether or not we
* should trust the nextCNID value in the hfs mount point.
*
* If we didn't do this, then it would be possible for a cnode that is no longer backed
* by anything on-disk (C_NOEXISTS) to still exist in the hash along with its
* vnode. The cat_create routine could then create a new entry in the catalog
* re-using that CNID. Then subsequent hfs_getnewvnode calls will repeatedly fail
* trying to look it up/validate it because it is marked C_NOEXISTS. So we want
* to prevent that from happening as much as possible.
*/
if (existence_only) {
result = 0;
break;
}

/* Skip cnodes that have been removed from the catalog */
if (cp->c_flag & (C_NOEXISTS | C_DELETED)) {
break;
}
Expand Down
4 changes: 3 additions & 1 deletion bsd/hfs/hfs_cnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ extern struct vnode * hfs_chash_getvnode(struct hfsmount *hfsmp, ino_t inum, int
int skiplock, int allow_deleted);
extern struct cnode * hfs_chash_getcnode(struct hfsmount *hfsmp, ino_t inum, struct vnode **vpp,
int wantrsrc, int skiplock, int *out_flags, int *hflags);
extern int hfs_chash_snoop(struct hfsmount *, ino_t, int (*)(const struct cat_desc *,
extern int hfs_chash_snoop(struct hfsmount *, ino_t, int, int (*)(const struct cat_desc *,
const struct cat_attr *, void *), void *);
extern int hfs_valid_cnode(struct hfsmount *hfsmp, struct vnode *dvp, struct componentname *cnp,
cnid_t cnid, struct cat_attr *cattr, int *error);
Expand All @@ -345,6 +345,8 @@ extern int hfs_chash_set_childlinkbit(struct hfsmount *hfsmp, cnid_t cnid);
* E. Overflow Extents B-tree file (always exclusive, supports recursion)
* 5. hfs mount point (always last)
*
*
* I. HFS cnode hash lock (must not acquire any new locks while holding this lock, always taken last)
*/
enum hfslocktype {HFS_SHARED_LOCK = 1, HFS_EXCLUSIVE_LOCK = 2, HFS_FORCE_LOCK = 3, HFS_RECURSE_TRUNCLOCK = 4};
#define HFS_SHARED_OWNER (void *)0xffffffff
Expand Down
31 changes: 21 additions & 10 deletions bsd/hfs/hfs_quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,38 @@ hfs_getinoquota(cp)
struct hfsmount *hfsmp;
struct vnode *vp;
int error;
int drop_usrquota = false;

vp = cp->c_vp ? cp->c_vp : cp->c_rsrc_vp;
hfsmp = VTOHFS(vp);
/*
* Set up the user quota based on file uid.
* EINVAL means that quotas are not enabled.
*/
if (cp->c_dquot[USRQUOTA] == NODQUOT &&
(error =
dqget(cp->c_uid, &hfsmp->hfs_qfiles[USRQUOTA], USRQUOTA, &cp->c_dquot[USRQUOTA])) &&
error != EINVAL)
return (error);
if (cp->c_dquot[USRQUOTA] == NODQUOT) {
error = dqget(cp->c_uid, &hfsmp->hfs_qfiles[USRQUOTA], USRQUOTA, &cp->c_dquot[USRQUOTA]);
if ((error != 0) && (error != EINVAL)) {
return error;
} else if (error == 0) {
drop_usrquota = true;
}
}

/*
* Set up the group quota based on file gid.
* EINVAL means that quotas are not enabled.
*/
if (cp->c_dquot[GRPQUOTA] == NODQUOT &&
(error =
dqget(cp->c_gid, &hfsmp->hfs_qfiles[GRPQUOTA], GRPQUOTA, &cp->c_dquot[GRPQUOTA])) &&
error != EINVAL)
return (error);
if (cp->c_dquot[GRPQUOTA] == NODQUOT) {
error = dqget(cp->c_gid, &hfsmp->hfs_qfiles[GRPQUOTA], GRPQUOTA, &cp->c_dquot[GRPQUOTA]);
if ((error != 0) && (error != EINVAL)) {
if (drop_usrquota == true) {
dqrele(cp->c_dquot[USRQUOTA]);
cp->c_dquot[USRQUOTA] = NODQUOT;
}
return error;
}
}

return (0);
}

Expand Down
2 changes: 1 addition & 1 deletion bsd/hfs/hfs_readwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ do_attr_lookup(struct hfsmount *hfsmp, struct access_cache *cache, cnid_t cnid,
struct cinfo c_info;

/* otherwise, check the cnode hash incase the file/dir is incore */
if (hfs_chash_snoop(hfsmp, cnid, snoop_callback, &c_info) == 0) {
if (hfs_chash_snoop(hfsmp, cnid, 0, snoop_callback, &c_info) == 0) {
cnattrp->ca_uid = c_info.uid;
cnattrp->ca_gid = c_info.gid;
cnattrp->ca_mode = c_info.mode;
Expand Down
8 changes: 5 additions & 3 deletions bsd/hfs/hfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ hfs_syncer(void *arg0, void *unused)
//
if (hfsmp->hfs_mp->mnt_pending_write_size > hfsmp->hfs_max_pending_io) {
int counter=0;
uint64_t pending_io, start, rate;
uint64_t pending_io, start, rate = 0;

no_max = 0;

Expand Down Expand Up @@ -1027,7 +1027,9 @@ hfs_syncer(void *arg0, void *unused)
clock_get_calendar_microtime(&secs, &usecs);
now = ((uint64_t)secs * 1000000ULL) + (uint64_t)usecs;
hfsmp->hfs_last_sync_time = now;
rate = ((pending_io * 1000000ULL) / (now - start)); // yields bytes per second
if (now != start) {
rate = ((pending_io * 1000000ULL) / (now - start)); // yields bytes per second
}

hfs_end_transaction(hfsmp);

Expand All @@ -1037,7 +1039,7 @@ hfs_syncer(void *arg0, void *unused)
// than 2 seconds, adjust hfs_max_pending_io so that we
// will allow about 1.5 seconds of i/o to queue up.
//
if ((now - start) >= 300000) {
if (((now - start) >= 300000) && (rate != 0)) {
uint64_t scale = (pending_io * 100) / rate;

if (scale < 100 || scale > 200) {
Expand Down
22 changes: 12 additions & 10 deletions bsd/hfs/hfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,16 +482,6 @@ hfs_vnop_open(struct vnop_open_args *ap)
if (cp->c_fileid == hfsmp->hfs_jnlfileid)
return (EPERM);

/* If we're going to write to the file, initialize quotas. */
#if QUOTA
if ((ap->a_mode & FWRITE) && (hfsmp->hfs_flags & HFS_QUOTAS))
(void)hfs_getinoquota(cp);
#endif /* QUOTA */

/*
* On the first (non-busy) open of a fragmented
* file attempt to de-frag it (if its less than 20MB).
*/
if ((hfsmp->hfs_flags & HFS_READ_ONLY) ||
(hfsmp->jnl == NULL) ||
#if NAMEDSTREAMS
Expand All @@ -504,6 +494,17 @@ hfs_vnop_open(struct vnop_open_args *ap)

if ((error = hfs_lock(cp, HFS_EXCLUSIVE_LOCK)))
return (error);

#if QUOTA
/* If we're going to write to the file, initialize quotas. */
if ((ap->a_mode & FWRITE) && (hfsmp->hfs_flags & HFS_QUOTAS))
(void)hfs_getinoquota(cp);
#endif /* QUOTA */

/*
* On the first (non-busy) open of a fragmented
* file attempt to de-frag it (if its less than 20MB).
*/
fp = VTOF(vp);
if (fp->ff_blocks &&
fp->ff_extents[7].blockCount != 0 &&
Expand Down Expand Up @@ -535,6 +536,7 @@ hfs_vnop_open(struct vnop_open_args *ap)
vfs_context_proc(ap->a_context));
}
}

hfs_unlock(cp);

return (0);
Expand Down
Loading

0 comments on commit 2d9567d

Please sign in to comment.