Print this page
OS-4865 lxbrand async socket errors catch programs off guard
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4213 lxbrand should be able to set TCP_DEFER_ACCEPT after other socket operations

@@ -295,19 +295,20 @@
 
 #define SS_RCVATMARK            0x00001000 /* at mark on input */
 #define SS_OOBPEND              0x00002000 /* OOB pending or present - poll */
 #define SS_HAVEOOBDATA          0x00004000 /* OOB data present */
 #define SS_HADOOBDATA           0x00008000 /* OOB data consumed */
-#define SS_CLOSING              0x00010000 /* in process of closing */
 
+#define SS_CLOSING              0x00010000 /* in process of closing */
 #define SS_FIL_DEFER            0x00020000 /* filter deferred notification */
 #define SS_FILOP_OK             0x00040000 /* socket can attach filters */
 #define SS_FIL_RCV_FLOWCTRL     0x00080000 /* filter asserted rcv flow ctrl */
+
 #define SS_FIL_SND_FLOWCTRL     0x00100000 /* filter asserted snd flow ctrl */
 #define SS_FIL_STOP             0x00200000 /* no more filter actions */
-
 #define SS_SODIRECT             0x00400000 /* transport supports sodirect */
+#define SS_FILOP_UNSF           0x00800000 /* block attaching unsafe filters */
 
 #define SS_SENTLASTREADSIG      0x01000000 /* last rx signal has been sent */
 #define SS_SENTLASTWRITESIG     0x02000000 /* last tx signal has been sent */
 
 #define SS_FALLBACK_DRAIN       0x20000000 /* data was/is being drained */

@@ -319,11 +320,12 @@
 #define SS_CANTREBIND   (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING|\
                             SS_CANTSENDMORE|SS_CANTRCVMORE|SS_ACCEPTCONN)
 
 /*
  * Sockets that can fall back to TPI must ensure that fall back is not
- * initiated while a thread is using a socket.
+ * initiated while a thread is using a socket. Otherwise this disables all
+ * future filter attachment.
  */
 #define SO_BLOCK_FALLBACK(so, fn)                               \
         ASSERT(MUTEX_NOT_HELD(&(so)->so_lock));                 \
         rw_enter(&(so)->so_fallback_rwlock, RW_READER);         \
         if ((so)->so_state & (SS_FALLBACK_COMP|SS_FILOP_OK)) {  \

@@ -335,10 +337,28 @@
                         (so)->so_state &= ~SS_FILOP_OK;         \
                         mutex_exit(&(so)->so_lock);             \
                 }                                               \
         }
 
+/*
+ * Sockets that can fall back to TPI must ensure that fall back is not
+ * initiated while a thread is using a socket. Otherwise this disables all
+ * future unsafe filter attachment. Safe filters can still attach after
+ * we execute the function in which this macro is used.
+ */
+#define SO_BLOCK_FALLBACK_SAFE(so, fn)                          \
+        ASSERT(MUTEX_NOT_HELD(&(so)->so_lock));                 \
+        rw_enter(&(so)->so_fallback_rwlock, RW_READER);         \
+        if ((so)->so_state & SS_FALLBACK_COMP) {                \
+                rw_exit(&(so)->so_fallback_rwlock);             \
+                return (fn);                                    \
+        } else if (((so)->so_state & SS_FILOP_UNSF) == 0) {     \
+                mutex_enter(&(so)->so_lock);                    \
+                (so)->so_state |= SS_FILOP_UNSF;                \
+                mutex_exit(&(so)->so_lock);                     \
+        }
+
 #define SO_UNBLOCK_FALLBACK(so) {                       \
         rw_exit(&(so)->so_fallback_rwlock);             \
 }
 
 #define SO_SND_FLOWCTRLD(so)    \

@@ -366,10 +386,11 @@
 #define SM_KERNEL               0x200   /* kernel socket */
 
 /* The modes below are only for non-streams sockets */
 #define SM_ACCEPTSUPP           0x400   /* can handle accept() */
 #define SM_SENDFILESUPP         0x800   /* Private: proto supp sendfile  */
+#define SM_DEFERERR             0x1000  /* Private: defer so_error delivery */
 
 /*
  * Socket versions. Used by the socket library when calling _so_socket().
  */
 #define SOV_STREAM      0       /* Not a socket - just a stream */