В ядре Linux устранена следующая уязвимость: nfsd: исправить RELEASE_LOCKOWNER. Проверка so_count в nfsd4_release_lockowner() бессмысленна …
В ядре Linux устранена следующая уязвимость: nfsd: исправить RELEASE_LOCKOWNER. Проверка so_count в nfsd4_release_lockowner() бессмысленна и вредна. Вернитесь к использованию check_for_locks(), изменив ее так, чтобы она не засыпала. Во-первых: вредно. Как задокументировано в комментарии kdoc для nfsd4_release_lockowner(), проверка so_count может временно вернуть ложноположительный результат, приводящий к возврату NFS4ERR_LOCKS_HELD, когда на самом деле никакие блокировки не удерживаются. Это явно является нарушением протокола, и с клиентом Linux NFS это может вызвать неправильное поведение. Если RELEASE_LOCKOWNER отправляется, пока некоторый другой поток все еще обрабатывает запрос LOCK, который не удался, потому что на момент получения этого запроса данный владелец удерживал конфликтующую блокировку, тогда поток nfsd, обрабатывающий этот запрос LOCK, может удерживать ссылку (conflock) на владельца блокировки, что приводит к тому, что nfsd4_release_lockowner() возвращает неправильную ошибку. Клиент Linux NFS игнорирует эту ошибку NFS4ERR_LOCKS_HELD, потому что он никогда не отправляет NFS4_RELEASE_LOCKOWNER без предварительного освобождения каких-либо блокировок, поэтому он знает, что ошибка невозможна. Он предполагает, что владелец блокировки был фактически освобожден, поэтому он чувствует себя вправе использовать тот же идентификатор владельца блокировки в каком-то более позднем запросе блокировки. Когда он повторно использует идентификатор владельца блокировки, для которого предыдущий RELEASE не удался, он, естественно, будет использовать lock_seqid, равный нулю. Однако сервер, который не освободил владельца блокировки, будет ожидать больший lock_seqid и поэтому ответит с NFS4ERR_BAD_SEQID. Так что явно вредно допускать ложноположительный результат, который позволяет проверка so_count. Проверка бессмысленна, потому что... ну... она ничего не значит. so_count - это сумма трех разных счетчиков. 1/ набор состояний, перечисленных в so_stateids 2/ набор активных блокировок vfs, принадлежащих любому из этих состояний 3/ различные временные счетчики, такие как для конфликтующих блокировок. Когда он проверяется на '2', становится ясно, что одним из них является временная ссылка, полученная с помощью find_lockowner_str_locked(). Неясно, каким должен быть другой. На практике счетчик часто равен 2, потому что в so_stateids есть ровно одно состояние. Если бы их было больше, это бы не удалось. В моем тестировании я вижу два обстоятельства, когда вызывается RELEASE_LOCKOWNER. В одном случае CLOSE вызывается перед RELEASE_LOCKOWNER. Это приводит к удалению всех состояний блокировки, и поэтому владелец блокировки отбрасывается (он удаляется, когда больше нет ссылок, что обычно происходит, когда состояние блокировки отбрасывается). Когда nfsd4_release_lockowner() обнаруживает, что владелец блокировки не существует, он возвращает успех. Другой случай показывает so_count, равный '2', и ровно одно состояние, перечисленное в so_stateid. Похоже, что клиент Linux использует отдельного владельца блокировки для каждого файла, что приводит к одному состоянию блокировки на владельца блокировки, поэтому эта проверка на '2' безопасна. Для другого клиента это может быть небезопасно. Таким образом, этот патч изменяет check_for_locks(), чтобы использовать (новейшую) find_any_file_locked(), чтобы он не принимал ссылку на nfs4_file и поэтому никогда не вызывал nfsd_file_put() и поэтому никогда не засыпал. С этой проверкой безопасно восстановить использование check_for_locks() вместо проверки so_count на таинственное '2'.
Функция или операция возвращает некорректное возвращаемое значение или код состояния, который не отражает истинный результат выполнения, что приводит к изменению поведения продукта на основе некорректного результата.
https://cwe.mitre.org/data/definitions/393.html →Открыть в коллекции CWE →Программный продукт не обеспечивает надлежащего захвата или освобождения блокировки ресурса, что приводит к непредвиденным изменениям состояния ресурса и нештатному поведению.
https://cwe.mitre.org/data/definitions/667.html →Открыть в коллекции CWE →Злоумышленник провоцирует и эксплуатирует состояние взаимоблокировки в целевом программном обеспечении, чтобы вызвать отказ в обслуживании. Взаимоблокировка может возникнуть, когда два или более конкурирующих действия ожидают завершения друг друга и в итоге ни одно из них не завершается. Состояния взаимоблокировки бывает сложно обнаружить.
https://capec.mitre.org/data/definitions/25.html →Открыть в коллекции CAPEC →Злоумышленник нацеливается на состояние гонки, возникающее когда несколько процессов одновременно обращаются к одному ресурсу и манипулируют им, а результат выполнения зависит от конкретного порядка этих обращений. Злоумышленник может эксплуатировать состояние гонки, «участвуя в гонке»: изменяя ресурс и нарушая нормальный порядок выполнения. Например, состояние гонки может возникнуть при обращении к файлу: злоумышленник может обмануть систему, подменив исходный файл своей версией и заставив систему прочитать вредоносный файл.
https://capec.mitre.org/data/definitions/26.html →Открыть в коллекции CAPEC →Данная атака эксплуатирует использование символических ссылок (Symlink) для записи в конфиденциальные файлы. Злоумышленник может создать символическую ссылку на целевой файл, к которому у него нет прямого доступа. Когда привилегированная программа пытается создать временный файл с тем же именем, что и символическая ссылка, она фактически записывает данные в целевой файл, на который указывает символическая ссылка злоумышленника. Если злоумышленник может поместить вредоносное содержимое во временный файл, он тем самым запишет его в конфиденциальный файл через символическую ссылку. Состояние гонки возникает потому, что система проверяет существование временного файла, а затем создаёт его. Злоумышленник, как правило, создаёт символическую ссылку в промежутке между проверкой и созданием временного файла.
https://capec.mitre.org/data/definitions/27.html →Открыть в коллекции CAPEC →| Продукт | Вендор | Статус |
|---|---|---|
| kernel | Отслеживается | |
| kernel | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux | Отслеживается | |
| linux-6.1 | Отслеживается | |
| linux-6.1 | Отслеживается | |
| linux-6.1 | Отслеживается | |
| linux-allwinner-5.19 | Отслеживается | |
| linux-aws | Отслеживается | |
| linux-aws | Отслеживается |