В макбуках найдена «бомба замедленного действия». Она незаметно ломает сеть через 50 часов непрерывной работы ОС
В macOS обнаружена «бомба замедленного действия», которая вызывает отказ TCP-стека операционной системы Apple ровно через 49 дней 17 часов 2 минуты и 47 секунд после последней перезагрузки. «Лечится» это банальной перезагрузкой.Баг в macOS
Специалисты компании Photon выявили изъян в операционной системе macOS, которая поставляется с персональными компьютерами корпорации Apple.
Как выяснилось, сетевая подсистема ОС работает корректно чуть дольше чем 49 дней с момента загрузки, после чего теряет возможность устанавливать новые соединения по протоколу TCP, одному из главных в интернете. Проблема решается сама собой после перезапуска системы, но возникает вновь по прошествии упомянутого выше временного интервала.
Photon специализируется на разработке инструментов для создания и управления ИИ-агентами. Флагманский продукт компании – Spectrum, инструментарий для создания нативных агентов для обмена сообщениями через мессенджеры, в том числе через Apple iMessage, с применением декларативного подхода.
macOS преимущественно используется в качестве десктопной ОС, а ее пользователя в основном склонны перезагружать или выключать свои ПК чаще, чем раз чем в 1,5 месяца. Поэтому проблема периодического отказа TCP/IP-стека не столь актуальна для этой категории пользователей и могла спокойно оставаться незамеченной.
Компания Photon, в свою очередь, применяет компьютерное оборудование Apple в роли серверов. Целый парк таких машин используется для мониторинга работоспособности сервисов, работающих с iMessage. Он функционирует в режиме 24/7 и перезагружается только при крайней необходимости. В инфраструктуре Photon работает сервер – центральный контроллер, который периодически отправляет по сети ICPM-запросы (ping) входящим в нее компьютерам mac для оценки скорости их отклика.
Загадочный сбой
30 марта 2026 г., ровно через 49 дней 17 часов 2 минуты и 47 секунд, с момента последней перезагрузки часть парка компьютеров mac перестала регистрировать новые TCP-соединения, без сообщений об ошибках, совершенно молча, отмечает Photon в своем официальном блоге.
Примечательно, что команда ping на проблемные машины продолжала проходить, а существующие TCP-соединения – работать. Однако любые операции, предполагающие создание нового TCP-сокета – программного интерфейса, обеспечивающего обмен данными между процессами.
Специалисты компании, помня о некоторых других ситуациях, в которых фигурировали 49 дней и 17 часов в контексте проблем в работе ПО, выдвинули гипотезу, касающуюся причин происходящего, и провели ряд тестов, которые позволили ее подтвердить.
Например, операционные системы Microsoft Windows 95/98 имели свойство «падать» по прошествии такого же временного промежутка. Это, как выяснилось, было связано с целочисленным переполнением 32-битной переменной в коде ядра ОС.
Технические подробности причин возникновения проблемы
Завершив свою работу, TCP-соединение в macOS не исчезает бесследно в ту же секунду. Сторона обмена данными, инициировавшая операцию его завершения, переходит в состояние, называемое TIME_WAIT. Находящееся в нем соединение не используется для дальнейшей пересылки данных, но операционная система считает необходимым в течение короткого промежутка времени сохранять его существование. Это может быть необходимо по ряду причин, связанных со спецификой протокола TCP.
Согласно оригинальной спецификации протокола TCP (RFC 793 от 1981 г.), параметр MSL (максимальное время жизни сегмента сети), должен составлять 2 минуты. Продолжительность состояния TIME_WAIT определяется как значение MSL, умноженное на два. Таким образом, оно должно составлять 4 минуты. Однако в современных операционных системах этот параметр, как правило, имеет гораздо меньшее значение: 60 секунд – в Linux, 120 секунд – в Windows, 30 секунды – в macOS.
XNU, ядро macOS, имеет счетчик времени, прошедшего со старта системы. Реализован он в виде переменной tcp_now, в которой сохраняется соответствующее значение в миллисекундах.
Тип переменной разработчиками Apple, по всей видимости, был выбран uint32_t, который позволяет хранить 32-битное целое число без знака, то есть может принимать значения в диапазоне от 0 до 4294967295, или 232 – 1. Верхняя граница диапазона и составляет «загадочные» 49 дней, 17 часов и 2 минуты в миллисекундах. При попытке выйти за границу диапазона, система значение просто обнуляет, не провоцируя исключение или критическую ошибку, которая могла бы привести к «поломке» ОС.
Всякий раз, когда TCP-подсистеме macOS требуется значение tcp_now, она вызывает функцию calculate_tcp_clock(), которая вычисляет его с точностью до миллисекунды. Внутри этой функции специалисты Photon обнаружили фрагмент, который по задумке разработчиков Apple, должен гарантировать, что значение tcp_now изменяется только в сторону увеличения, но на деле не учитывает возможность переполнения переменной с ее последующим обнулением. Когда же оно происходит – спустя 49 дней и 17 часов – значение tcp_now благодаря calculate_tcp_clock() откатывается обратно к верхней границе и в дальнейшем уже фактически не обновляется, вплоть до перезагрузки ОС.
Когда TCP-соединение переходит в состояние TIME_WAIT, ядро macOS записывает абсолютное значение времени, по наступлении которого это соединение должно быть окончательно уничтожено. Специальный компонент ядра (сборщик мусора) периодически проверяет, не закончилось время ожидания для всего перечня TCP-соединений в состоянии TIME_WAIT, сравнивая связанную с ним отметку времени со значением tcp_now. Однако поскольку последнее теперь всегда составляет 4294967295, результат проверки всегда отрицательный – «ожидаемое время еще не наступило».
В результате TCP-соединение никогда не будет выведено из состояния TIME_WAIT, и количество таких «зависших» соединений и количество задействованных портов будет только продолжать расти. В конце концов пул сетевых портов иссякнет, а нагрузка ядра macOS на процессор значительно вырастет из-за необходимости постоянно тщетно вновь и вновь просматривать огромную очередь TCP-соединений на закрытие. Ситуация усугубится за счет попыток повторного установления соединений со стороны приложений, использующих TCP.
В конечном счете, как отмечают в Photon, работоспособным остается только протокол ICMP (в том числе команда ping), которой не нужны порты TCP, и которая не ориентируется в своей работе на внутренний таймер TCP.




