summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/socketvar.h
diff options
context:
space:
mode:
authorAnders Persson <Anders.Persson@Sun.COM>2010-04-26 14:42:41 -0700
committerAnders Persson <Anders.Persson@Sun.COM>2010-04-26 14:42:41 -0700
commit5f1fdc187ec74acfbc49a47e07b89d7f64519f7b (patch)
treec5e16fd2badef45f65279cbc043d6fecefc6daf6 /usr/src/uts/common/sys/socketvar.h
parentc5866e1dd55ab5acc06a0e2fb2d896f7fddc9695 (diff)
downloadillumos-joyent-5f1fdc187ec74acfbc49a47e07b89d7f64519f7b.tar.gz
6943440 race in solookup() can cause smod_refcnt to be bumped multiple times for a single sockparams
Diffstat (limited to 'usr/src/uts/common/sys/socketvar.h')
-rw-r--r--usr/src/uts/common/sys/socketvar.h22
1 files changed, 12 insertions, 10 deletions
diff --git a/usr/src/uts/common/sys/socketvar.h b/usr/src/uts/common/sys/socketvar.h
index 7c28154af8..268adc6103 100644
--- a/usr/src/uts/common/sys/socketvar.h
+++ b/usr/src/uts/common/sys/socketvar.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -425,11 +424,11 @@ typedef struct sockparams_stats {
/*
* sockparams
*
- * Used for mapping family/type/protocol to module
+ * Used for mapping family/type/protocol to a socket module or STREAMS device
*/
struct sockparams {
/*
- * The family, type, protocol, sdev_info and smod_info are
+ * The family, type, protocol, sdev_info and smod_name are
* set when the entry is created, and they will never change
* thereafter.
*/
@@ -439,10 +438,11 @@ struct sockparams {
sdev_info_t sp_sdev_info; /* STREAM device */
char *sp_smod_name; /* socket module name */
- smod_info_t *sp_smod_info; /* socket module */
- kmutex_t sp_lock; /* lock for refcnt */
+ kmutex_t sp_lock; /* lock for refcnt and smod_info */
uint64_t sp_refcnt; /* entry reference count */
+ smod_info_t *sp_smod_info; /* socket module */
+
sockparams_stats_t sp_stats;
kstat_t *sp_kstat;
@@ -489,7 +489,7 @@ extern smod_info_t *smod_lookup_byname(const char *);
* kernel. If the module can't unload, just leave the module entry with
* a zero refcnt.
*/
-#define SMOD_DEC_REF(sp, smodp) { \
+#define SMOD_DEC_REF(smodp, modname) { \
ASSERT((smodp) != NULL); \
ASSERT((smodp)->smod_refcnt != 0); \
atomic_dec_uint(&(smodp)->smod_refcnt); \
@@ -500,7 +500,7 @@ extern smod_info_t *smod_lookup_byname(const char *);
* here is multiple calls to mod_remove_by_name(), which is OK. \
*/ \
if ((smodp)->smod_refcnt == 0) \
- (void) mod_remove_by_name((sp)->sp_smod_name); \
+ (void) mod_remove_by_name(modname); \
}
/* Increase the reference count */
@@ -530,8 +530,10 @@ extern smod_info_t *smod_lookup_byname(const char *);
sockparams_ephemeral_drop_last_ref((sp)); \
} else { \
(sp)->sp_refcnt--; \
- if ((sp)->sp_smod_info != NULL) \
- SMOD_DEC_REF(sp, (sp)->sp_smod_info); \
+ if ((sp)->sp_smod_info != NULL) { \
+ SMOD_DEC_REF((sp)->sp_smod_info, \
+ (sp)->sp_smod_name); \
+ } \
(sp)->sp_smod_info = NULL; \
mutex_exit(&(sp)->sp_lock); \
} \