summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorDan McDonald <danmcd@joyent.com>2022-01-18 13:30:10 -0500
committerDan McDonald <danmcd@joyent.com>2022-01-18 13:30:10 -0500
commitdaf61a2ba69d236f9da41f1a991cf8af3f3ff72c (patch)
treef63cff2bcde5511605ed4466f719e2a7ccb54087 /usr/src
parent561a2476a800c02bf5a1e7720002e17699fcaf27 (diff)
parentf859e7171bb5db34321e45585839c6c3200ebb90 (diff)
downloadillumos-joyent-daf61a2ba69d236f9da41f1a991cf8af3f3ff72c.tar.gz
[illumos-gate merge]
commit f859e7171bb5db34321e45585839c6c3200ebb90 14424 tmpfs can be induced to deadlock commit d278f1c9d93ca9beb430b23636bc2a848535e0e0 14350 uath: mismatched bound commit 53496f229747a02889ac4f8518b2e4b44ff2f9e0 14349 libcrypt: mismatched bound commit dc1259b65efc626c37cd057774d3e3393e84c33c 14328 cscope-fast: this 'if' clause does not guard...
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/libcrypt/common/cryptio.c12
-rw-r--r--usr/src/tools/cscope-fast/cgrep.c29
-rw-r--r--usr/src/uts/common/fs/tmpfs/tmp_dir.c66
-rw-r--r--usr/src/uts/common/io/uath/uath.c9
4 files changed, 86 insertions, 30 deletions
diff --git a/usr/src/lib/libcrypt/common/cryptio.c b/usr/src/lib/libcrypt/common/cryptio.c
index 78b96aff48..613fdb3a31 100644
--- a/usr/src/lib/libcrypt/common/cryptio.c
+++ b/usr/src/lib/libcrypt/common/cryptio.c
@@ -25,9 +25,7 @@
*/
/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* All Rights Reserved */
#pragma weak _run_setkey = run_setkey
#pragma weak _run_crypt = run_crypt
@@ -48,7 +46,7 @@
#define READER 0
#define WRITER 1
-#define KSIZE 8
+#define KSIZE 8
/* Global Variables */
static char key[KSIZE+1];
@@ -65,7 +63,7 @@ static int writekey();
void _exit();
int
-run_setkey(int p[2], const char *keyparam)
+run_setkey(int *p, const char *keyparam)
{
(void) mutex_lock(&lock);
if (cryptopen(p) == -1) {
@@ -119,7 +117,7 @@ writekey(int p[2], char *keyarg)
int
-run_crypt(long offset, char *buffer, unsigned int count, int p[2])
+run_crypt(long offset, char *buffer, unsigned int count, int *p)
{
struct header header;
void (*pstat) ();
@@ -193,7 +191,7 @@ crypt_close_nolock(int p[2])
}
int
-crypt_close(int p[2])
+crypt_close(int *p)
{
(void) mutex_lock(&lock);
(void) crypt_close_nolock(p);
diff --git a/usr/src/tools/cscope-fast/cgrep.c b/usr/src/tools/cscope-fast/cgrep.c
index 7875789364..bd7c3e8043 100644
--- a/usr/src/tools/cscope-fast/cgrep.c
+++ b/usr/src/tools/cscope-fast/cgrep.c
@@ -20,16 +20,13 @@
* CDDL HEADER END
*/
/* Copyright (c) 1990 AT&T */
-/* All Rights Reserved */
-
+/* All Rights Reserved */
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* cscope - interactive C symbol or text cross-reference
*
@@ -209,7 +206,7 @@ typedef struct {
#define ADD(N) if (qtail) qtail = qtail->next = NEW(N); \
else qtail = qhead = NEW(N)
#define DEL() { Link *_l = qhead; if ((qhead = qhead->next) == NULL) \
- qtail = NULL; _l->next = froot; froot = _l; }
+ { qtail = NULL; } _l->next = froot; froot = _l; }
static uchar_t *buffer;
static uchar_t *bufend;
@@ -718,10 +715,8 @@ followstate(re_re *r, State *s, int a, Positionset *fpos)
for (q = e->follow, eq = q + e->flen; q < eq; q++) {
SET(fpos, *q, r->posbase[j].fcount + 1)
#ifdef DEBUG
- printf("CHAR %c FC %c COUNT %d\n",
- a,
- r->ptr[*q]->lit,
- r->posbase[j].fcount+1);
+ printf("CHAR %c FC %c COUNT %d\n", a,
+ r->ptr[*q]->lit, r->posbase[j].fcount+1);
#endif
}
}
@@ -889,8 +884,8 @@ stateof(re_re *r, Positionset *ps)
if (s->npos == ps->count) {
for (p = s->pos+r->posbase, e = p+s->npos; p < e; p++)
if (ps->base[p->id].id == 0 ||
- ps->base[p->id].fcount != p->fcount)
- goto next;
+ ps->base[p->id].fcount != p->fcount)
+ goto next;
return (s);
}
next:;
@@ -962,8 +957,9 @@ lex(re_re *r, PATTERN *pat)
if (pat->loc1 == pat->loc2) {
err("syntax error - missing character "
"after \\");
- } else
- toklit = r->cmap[*pat->loc1++];
+ } else {
+ toklit = r->cmap[*pat->loc1++];
+ }
break;
case '^': case '$': toktype = Literal; toklit = NL; break;
default: toktype = Literal; toklit = r->cmap[toklit]; break;
@@ -990,8 +986,7 @@ ccl(PATTERN *pat, uchar_t *tab)
lastc = *pat->loc1++;
}
/* scan for chars */
- for (; (pat->loc1 < pat->loc2) && (*pat->loc1 != ']');
- pat->loc1++) {
+ for (; (pat->loc1 < pat->loc2) && (*pat->loc1 != ']'); pat->loc1++) {
if (*pat->loc1 == '-') {
if (lastc < 0) CCL_SET(tab, pat->cmap['-']);
else range = 1;
@@ -1109,7 +1104,7 @@ d1(re_re *r, PATTERN *pat)
e = d2(r, pat);
while ((toktype == Literal) || (toktype == Dot) || (toktype == Lpar) ||
- (toktype == Backslash) || (toktype == Charclass)) {
+ (toktype == Backslash) || (toktype == Charclass)) {
f = d2(r, pat);
e = newexpr(Cat, 0, e, f);
}
@@ -1784,7 +1779,7 @@ fgetfile(LINE *cur_ptr)
*/
int bytes; /* bytes read in current buffer */
int bufsize = MAXBUFSIZE; /* free space in data buffer */
- int save_current;
+ int save_current;
uchar_t *begin = cur_ptr->prntbuf;
/*
diff --git a/usr/src/uts/common/fs/tmpfs/tmp_dir.c b/usr/src/uts/common/fs/tmpfs/tmp_dir.c
index 1a620642cc..d689c512c1 100644
--- a/usr/src/uts/common/fs/tmpfs/tmp_dir.c
+++ b/usr/src/uts/common/fs/tmpfs/tmp_dir.c
@@ -54,6 +54,11 @@ static int tdiraddentry(struct tmpnode *, struct tmpnode *, char *,
#define T_HASH_SIZE 8192 /* must be power of 2 */
#define T_MUTEX_SIZE 64
+/* Non-static so compilers won't constant-fold these away. */
+clock_t tmpfs_rename_backoff_delay = 1;
+unsigned int tmpfs_rename_backoff_tries = 0;
+unsigned long tmpfs_rename_loops = 0;
+
static struct tdirent *t_hashtable[T_HASH_SIZE];
static kmutex_t t_hashmutex[T_MUTEX_SIZE];
@@ -266,8 +271,65 @@ tdirenter(
* to see if it has been removed while it was unlocked.
*/
if (op == DE_LINK || op == DE_RENAME) {
- if (tp != dir)
- rw_enter(&tp->tn_rwlock, RW_WRITER);
+ if (tp != dir) {
+ unsigned int tries = 0;
+
+ /*
+ * If we are acquiring tp->tn_rwlock (for SOURCE)
+ * inside here, we must consider the following:
+ *
+ * - dir->tn_rwlock (TARGET) is already HELD (see
+ * above ASSERT()).
+ *
+ * - It is possible our SOURCE is a parent of our
+ * TARGET. Yes it's unusual, but it will return an
+ * error below via tdircheckpath().
+ *
+ * - It is also possible that another thread,
+ * concurrent to this one, is performing
+ * rmdir(TARGET), which means it will first acquire
+ * SOURCE's lock, THEN acquire TARGET's lock, which
+ * could result in this thread holding TARGET and
+ * trying for SOURCE, but the other thread holding
+ * SOURCE and trying for TARGET. This is deadlock,
+ * and it's inducible.
+ *
+ * To prevent this, we borrow some techniques from UFS
+ * and rw_tryenter(), delaying if we fail, and
+ * if someone tweaks the number of backoff tries to be
+ * nonzero, return EBUSY after that number of tries.
+ */
+ while (!rw_tryenter(&tp->tn_rwlock, RW_WRITER)) {
+ /*
+ * Sloppy, but this is a diagnostic so atomic
+ * increment would be overkill.
+ */
+ tmpfs_rename_loops++;
+
+ if (tmpfs_rename_backoff_tries != 0) {
+ if (tries > tmpfs_rename_backoff_tries)
+ return (EBUSY);
+ tries++;
+ }
+ /*
+ * NOTE: We're still holding dir->tn_rwlock,
+ * so drop it over the delay, so any other
+ * thread can get its business done.
+ *
+ * No state change or state inspection happens
+ * prior to here, so it is not wholly dangerous
+ * to release-and-reacquire dir->tn_rwlock.
+ *
+ * Hold the vnode of dir in case it gets
+ * released by another thread, though.
+ */
+ VN_HOLD(TNTOV(dir));
+ rw_exit(&dir->tn_rwlock);
+ delay(tmpfs_rename_backoff_delay);
+ rw_enter(&dir->tn_rwlock, RW_WRITER);
+ VN_RELE(TNTOV(dir));
+ }
+ }
mutex_enter(&tp->tn_tlock);
if (tp->tn_nlink == 0) {
mutex_exit(&tp->tn_tlock);
diff --git a/usr/src/uts/common/io/uath/uath.c b/usr/src/uts/common/io/uath/uath.c
index 4d24e55316..ee8469b0af 100644
--- a/usr/src/uts/common/io/uath/uath.c
+++ b/usr/src/uts/common/io/uath/uath.c
@@ -241,12 +241,13 @@ static int uath_loadsym(ddi_modhandle_t, char *, char **, size_t *);
static int uath_loadfirmware(struct uath_softc *);
static int uath_alloc_cmd_list(struct uath_softc *,
struct uath_cmd *, int, int);
-static int uath_init_cmd_list(struct uath_softc *);
+static int uath_init_cmd_list(struct uath_softc *);
static void uath_free_cmd_list(struct uath_cmd *, int);
static int uath_host_available(struct uath_softc *);
static void uath_get_capability(struct uath_softc *, uint32_t, uint32_t *);
static int uath_get_devcap(struct uath_softc *);
-static int uath_get_devstatus(struct uath_softc *, uint8_t *);
+static int uath_get_devstatus(struct uath_softc *,
+ uint8_t [IEEE80211_ADDR_LEN]);
static int uath_get_status(struct uath_softc *, uint32_t, void *, int);
static void uath_cmd_lock_init(struct uath_cmd_lock *);
@@ -1534,12 +1535,12 @@ uath_tx_data_xfer(struct uath_softc *sc, mblk_t *mp)
req->bulk_len = msgdsize(mp);
req->bulk_data = mp;
- req->bulk_client_private = (usb_opaque_t)sc;
+ req->bulk_client_private = (usb_opaque_t)sc;
req->bulk_timeout = UATH_DATA_TIMEOUT;
req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
req->bulk_cb = uath_data_txeof;
req->bulk_exc_cb = uath_data_txeof;
- req->bulk_completion_reason = 0;
+ req->bulk_completion_reason = 0;
req->bulk_cb_flags = 0;
if ((err = usb_pipe_bulk_xfer(sc->tx_data_pipe, req, 0)) !=