- st = sk->sk_state;
- if (st != TCP_TIME_WAIT && st != TCP_CLOSE && st != TCP_LAST_ACK &&
- sk->sk_socket && sk->sk_socket->file) {
- ugp->fw_uid = sk->sk_socket->file->_CURR_UID;
- uid = ugp->fw_uid;
- ugp->fw_groups[0] = sk->sk_socket->file->_CURR_GID;
-#ifdef CONFIG_VSERVER
- ugp->fw_groups[1] = sk->sk_xid;
- ugp->fw_groups[2] = sk->sk_nid;
-#endif
- ret = 1;
+
+#define GOOD_STATES ( \
+ (1<<TCP_LISTEN) | (1<<TCP_SYN_RECV) | (1<<TCP_SYN_SENT) | \
+ (1<<TCP_ESTABLISHED) | (1<<TCP_FIN_WAIT1) | (1<<TCP_FIN_WAIT2) )
+ // surely exclude TCP_CLOSE, TCP_TIME_WAIT, TCP_LAST_ACK
+ // uncertain TCP_CLOSE_WAIT and TCP_CLOSING
+
+ if ((1<<st) & GOOD_STATES) {
+ read_lock_bh(&sk->sk_callback_lock);
+ if (sk->sk_socket && sk->sk_socket->file) {
+ u->uid = sk->sk_socket->file->_CURR_UID;
+ u->gid = sk->sk_socket->file->_CURR_GID;
+ }
+ read_unlock_bh(&sk->sk_callback_lock);
+ } else {
+ u->uid = u->gid = 0;