snapshot: sagernet/gvisor v0.0.0-20260727.0-sing-box-mod.1 + SPEC 048 guard

Обновление снапшота с v0.0.0-20250811.0 на пин, которого требует
sing-box после мержа 235 коммитов (upstream d620bbbf2 "Update gvisor to
20260727.0"). Прежний снапшот был взят 2026-08-04 ровно с той версии,
на которой тогда стоял апстрим; разрыв возник 2026-08-05 вместе с его
бампом.

За год апстрим-gvisor изменил ~14 000 строк в 292 файлах. Значимое для
нас — сетевой стек: tcp/connect.go (PMTU-discovery + исправление
начального RTT/RTO: раньше задержка ACK внутри стека завышала стартовый
таймаут на несколько RTT), tcp/snd.go, tcp/rcv.go, stack/conntrack.go,
stack/packet_buffer.go. Всего 30 файлов в TCP и 37 в stack.

Баг SPEC 048 апстрим НЕ исправил — проверено по коду новой версии:
handleConnecting по-прежнему проверяет состояние endpoint'а, но не ep.h,
а performHandshake так же зануляет h и отпускает мьютекс до Close().
Поэтому guard перенесён (12 строк) вместе со своим тестом (45 строк).

Red/green проверен на новой базе: без guard'а тест падает с той же
nil-паникой, что в полевом крашдампе; с ним зелёный.
This commit is contained in:
Leadaxe 2026-08-05 14:53:31 +03:00
parent ffebe42860
commit 117243aa02
293 changed files with 16413 additions and 2842 deletions

View file

@ -17,6 +17,7 @@ package linux
import (
"fmt"
"strings"
"structs"
"github.com/sagernet/gvisor/pkg/abi"
)
@ -42,6 +43,20 @@ const (
O_TMPFILE = 0o20000000 // __O_TMPFILE in Linux
)
// Constants for file mode (struct file::f_mode in Linux).
const (
// FMODE_READ indicates the file is open for reading.
// It is set when MayReadFileWithOpenFlags(flags) is true.
FMODE_READ = 0x1
// FMODE_WRITE indicates the file is open for writing.
// It is set when MayWriteFileWithOpenFlags(flags) is true. When set,
// the FileDescription holds a write count on vd.mount.
FMODE_WRITE = 0x2
// FMODE_CREATED is set when a file is newly created by an open
// operation (O_CREAT and the file did not already exist).
FMODE_CREATED = 0x100000
)
// Constants for fstatat(2).
const (
AT_SYMLINK_NOFOLLOW = 0x100
@ -85,6 +100,64 @@ const (
UMOUNT_NOFOLLOW = 0x8
)
// Constants for fsopen(2).
const (
FSOPEN_CLOEXEC = 0x1
)
// Constants for fsconfig(2).
const (
FSCONFIG_SET_FLAG = 0x0
FSCONFIG_SET_STRING = 0x1
FSCONFIG_SET_BINARY = 0x2
FSCONFIG_SET_PATH = 0x3
FSCONFIG_SET_PATH_EMPTY = 0x4
FSCONFIG_SET_FD = 0x5
FSCONFIG_CMD_CREATE = 0x6
FSCONFIG_CMD_RECONFIGURE = 0x7
FSCONFIG_CMD_CREATE_EXCL = 0x8
)
// Constants for fsmount(2).
const (
FSMOUNT_CLOEXEC = 0x1
)
// Constants for move_mount(2).
const (
MOVE_MOUNT_F_SYMLINKS = 0x00000001
MOVE_MOUNT_F_AUTOMOUNTS = 0x00000002
MOVE_MOUNT_F_EMPTY_PATH = 0x00000004
MOVE_MOUNT_T_SYMLINKS = 0x00000010
MOVE_MOUNT_T_AUTOMOUNTS = 0x00000020
MOVE_MOUNT_T_EMPTY_PATH = 0x00000040
MOVE_MOUNT_SET_GROUP = 0x00000100
MOVE_MOUNT_BENEATH = 0x00000200
)
// Constants for mount_setattr(2).
const (
MOUNT_ATTR_RDONLY = 0x00000001
MOUNT_ATTR_NOSUID = 0x00000002
MOUNT_ATTR_NODEV = 0x00000004
MOUNT_ATTR_NOEXEC = 0x00000008
MOUNT_ATTR__ATIME = 0x00000070
MOUNT_ATTR_RELATIME = 0x00000000
MOUNT_ATTR_NOATIME = 0x00000010
MOUNT_ATTR_STRICTATIME = 0x00000020
MOUNT_ATTR_NODIRATIME = 0x00000080
MOUNT_ATTR_IDMAP = 0x00100000
MOUNT_ATTR_NOSYMFOLLOW = 0x00200000
AT_RECURSIVE = 0x8000
)
// Constants for open_tree(2).
const (
OPEN_TREE_CLONE = (1 << 0)
OPEN_TREE_NAMESPACE = (1 << 1)
OPEN_TREE_CLOEXEC = O_CLOEXEC
)
// Constants for unlinkat(2).
const (
AT_REMOVEDIR = 0x200
@ -265,6 +338,7 @@ const (
STATX_BLOCKS = 0x00000400
STATX_BASIC_STATS = 0x000007ff
STATX_BTIME = 0x00000800
STATX_MNT_ID = 0x00001000
STATX_ALL = 0x00000fff
STATX__RESERVED = 0x80000000
)
@ -284,6 +358,7 @@ const (
//
// +marshal boundCheck slice:StatxSlice
type Statx struct {
_ structs.HostLayout
Mask uint32
Blksize uint32
Attributes uint64
@ -304,12 +379,13 @@ type Statx struct {
RdevMinor uint32
DevMajor uint32
DevMinor uint32
MntID uint64
}
// String implements fmt.Stringer.String.
func (s *Statx) String() string {
return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d}",
s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor)
return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d, MntId: %d}",
s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor, s.MntID)
}
// SizeOfStatx is the size of a Statx struct.
@ -340,6 +416,19 @@ func (m FileMode) IsDir() bool {
return m.FileType() == S_IFDIR
}
// IsSpecialFile returns true if m is the mode of a "special file": a character
// or block device, FIFO, or socket.
//
// Analogous to include/linux/fs.h:special_file().
func (m FileMode) IsSpecialFile() bool {
switch m.FileType() {
case ModeCharacterDevice, ModeBlockDevice, ModeNamedPipe, ModeSocket:
return true
default:
return false
}
}
// String returns a string representation of m.
func (m FileMode) String() string {
var s []string