CryptoPro / libcore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ошибка при многократных вызовах метода проверки сертификата за короткий период на Linux

Poisent opened this issue · comments

Стэнд:

Operating System: RED OS MUROM (7.3.2)
CPE OS Name: cpe:/o:redos:redos:7
Kernel: Linux 5.15.87-1.el7.3.x86_64
CSP (Type:80) v5.0.10011 KC1 Release Ver:5.0.12600 OS:Linux CPU:AMD64 FastCode:READY:AVX. DISABLED:RSA;

Sdk.net :

Version:   6.0.406
Commit:    2988897946

LibCore.Linux.2023.2.14.1

У нас есть asp.net 6 приложение, которое занимается проверкой ЭП.
При многократных вызовах метода (25-30 вызовов подряд) SignedCms.CheckSignature(false) процесс под которым хостится приложение падает с ошибкой Segmentation fault.

В системном логе при каждой проверке появляется такая запись:
фев 16 13:12:02 fr-app-dev-02 dotnet[1961]:<capi20>pfx_FillPfxContextFromBlob!() asn1D_PFX failed
После падения:

 fr-app-dev-02 dotnet[1430]: <capi10>CryptDestroyKey!() invalid argument(s)!
Feb 16 14:51:41 fr-app-dev-02 dotnet[1430]: <capi10>CryptDestroyKey!failed: LastError = 0x57
Feb 16 14:51:41 fr-app-dev-02 dotnet[1430]: <capi10>CryptDestroyKey!() invalid argument(s)!
Feb 16 14:51:41 fr-app-dev-02 dotnet[1430]: <capi10>CryptDestroyKey!failed: LastError = 0x57

Также, периодически начинаем ловить ошибку (на одни и тех же данных), что алгоритм шифрования 1.2.643.7.1.1.2.2 не известен. После перезагрузки демона, всё начинает работать нормально. В течение следующих 25-30 вызовов.

private const string Signature = "MIIJNAYJKoZIhvcNAQcCoIIJJTCCCSECAQExDjAMBggqhQMHAQECAgUAMAsGCSqGSIb3DQEHAaCCBYIwggV+MIIFK6ADAgECAhN8AAEilXplQPQ8fWnfAAEAASKVMAoGCCqFAwcBAQMCMIIBCjEYMBYGBSqFA2QBEg0xMjM0NTY3ODkwMTIzMRowGAYIKoUDA4EDAQESDDAwMTIzNDU2Nzg5MDEvMC0GA1UECQwm0YPQuy4g0KHRg9GJ0ZHQstGB0LrQuNC5INCy0LDQuyDQtC4gMTgxCzAJBgNVBAYTAlJVMRkwFwYDVQQIDBDQsy4g0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxJTAjBgNVBAoMHNCe0J7QniAi0JrQoNCY0J/QotCeLdCf0KDQniIxOzA5BgNVBAMMMtCi0LXRgdGC0L7QstGL0Lkg0KPQpiDQntCe0J4gItCa0KDQmNCf0KLQni3Qn9Cg0J4iMB4XDTIwMDgyMDA4NDUyOFoXDTIwMTEyMDA4NTUyOFowggFSMTEwLwYDVQQKDCjQntCQ0J4g0JDQstGC0L7QtNC10YLQsNC70Ywt0KHQtdGA0LLQuNGBMRQwEgYFKoUDZAQMCTczMDM1MDAwMTEYMBYGBSqFA2QBEg0xMDI3MzAxNDg4NzYzMRgwFgYIKoUDA4EDAQESCjczMDMwMDg0NzQxKTAnBgNVBAwMINCm0LXRgNC10LzQvtC90LjQudC80LXQudGB0YLQtdGAMTMwMQYDVQQqDCrQkNCy0YLQvtC00LXRgtCw0LvRjCDQodC10YDQstC40YHQvtCy0LjRhzIxIzAhBgNVBAQMGtCf0YDQtdC00YHRgtCw0LLQuNGC0LXQu9GMMU4wTAYDVQQDDEXQn9GA0LXQtNGB0YLQsNCy0LjRgtC10LvRjCDQkNCy0YLQvtC00LXRgtCw0LvRjCDQodC10YDQstC40YHQvtCy0LjRhzIwZjAfBggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAO0c2VAkx4eDFipHE5QqJcJG6/QfIfKZD+6/YSXJGk6LtXrzM/5gkb99LBS1WRH8jAtkMGEvl4HPjKYRAAnIfOqOCAhUwggIRMBMGA1UdJQQMMAoGCCqFAwJAAQEBMA4GA1UdDwEB/wQEAwIE8DAdBgNVHQ4EFgQU/+TmBcy355lT4IiBoH6I1xZXEt0wHwYDVR0jBBgwFoAUm4Ve+4HcTVkHUWPPvt/aLH/JRDwwgcwGA1UdHwSBxDCBwTCBvqCBu6CBuIaBtWh0dHA6Ly90ZXN0Z29zdDIwMTIuY3J5cHRvcHJvLnJ1L0NlcnRFbnJvbGwvITA0MjIhMDQzNSEwNDQxITA0NDIhMDQzZSEwNDMyITA0NGIhMDQzOSUyMCEwNDIzITA0MjYlMjAhMDQxZSEwNDFlITA0MWUlMjAhMDAyMiEwNDFhITA0MjAhMDQxOCEwNDFmITA0MjIhMDQxZS0hMDQxZiEwNDIwITA0MWUhMDAyMigxKS5jcmwwgdoGCCsGAQUFBwEBBIHNMIHKMEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGdvc3QyMDEyLmNyeXB0b3Byby5ydS9DZXJ0RW5yb2xsL3Jvb3QyMDE4LmNydDA/BggrBgEFBQcwAYYzaHR0cDovL3Rlc3Rnb3N0MjAxMi5jcnlwdG9wcm8ucnUvb2NzcDIwMTJnL29jc3Auc3JmMEEGCCsGAQUFBzABhjVodHRwOi8vdGVzdGdvc3QyMDEyLmNyeXB0b3Byby5ydS9vY3NwMjAxMmdzdC9vY3NwLnNyZjAKBggqhQMHAQEDAgNBAGYBOsMx/WVoCWFqvvuvap9BBRK90J5rF5nijKpFNvVgJklY1J+jYojdzjQ4JxoTEqlJrtOKAJpe1HN4SaHy++oxggN3MIIDcwIBATCCASMwggEKMRgwFgYFKoUDZAESDTEyMzQ1Njc4OTAxMjMxGjAYBggqhQMDgQMBARIMMDAxMjM0NTY3ODkwMS8wLQYDVQQJDCbRg9C7LiDQodGD0YnRkdCy0YHQutC40Lkg0LLQsNC7INC0LiAxODELMAkGA1UEBhMCUlUxGTAXBgNVBAgMENCzLiDQnNC+0YHQutCy0LAxFTATBgNVBAcMDNCc0L7RgdC60LLQsDElMCMGA1UECgwc0J7QntCeICLQmtCg0JjQn9Ci0J4t0J/QoNCeIjE7MDkGA1UEAwwy0KLQtdGB0YLQvtCy0YvQuSDQo9CmINCe0J7QniAi0JrQoNCY0J/QotCeLdCf0KDQniICE3wAASKVemVA9Dx9ad8AAQABIpUwDAYIKoUDBwEBAgIFAKCCAecwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjAxMTIzMDgwNTA4WjAvBgkqhkiG9w0BCQQxIgQgP76Zs7B/Y7Dpz13PEpM6Nne9WIVjAWSO8wa6hXf2Jw4wggF6BgsqhkiG9w0BCRACLzGCAWkwggFlMIIBYTCCAV0wCgYIKoUDBwEBAgIEICjbXNWw8/jpPzNxywhFzksjTvIBSnkm2L8rgIfXG78hMIIBKzCCARKkggEOMIIBCjEYMBYGBSqFA2QBEg0xMjM0NTY3ODkwMTIzMRowGAYIKoUDA4EDAQESDDAwMTIzNDU2Nzg5MDEvMC0GA1UECQwm0YPQuy4g0KHRg9GJ0ZHQstGB0LrQuNC5INCy0LDQuyDQtC4gMTgxCzAJBgNVBAYTAlJVMRkwFwYDVQQIDBDQsy4g0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxJTAjBgNVBAoMHNCe0J7QniAi0JrQoNCY0J/QotCeLdCf0KDQniIxOzA5BgNVBAMMMtCi0LXRgdGC0L7QstGL0Lkg0KPQpiDQntCe0J4gItCa0KDQmNCf0KLQni3Qn9Cg0J4iAhN8AAEilXplQPQ8fWnfAAEAASKVMAwGCCqFAwcBAQEBBQAEQJwoatMpKLQKLHHWnmQurJn9V7FcAyKjHgzG4xaVoLYKWckhZRBviDE1oCl2QnpgzCOHk23XbdiWm4CsZpUAyZ0=";

private const string SignedData = "PFBlcnNvbj48SXNSZkNpdGl6ZW4+dHJ1ZTwvSXNSZkNpdGl6ZW4+PEZpcnN0TmFtZT7QkNC90LTRgNC10Lk8L0ZpcnN0TmFtZT48TGFzdE5hbWU+0J/QsNCy0LvRg9GI0LjQvTwvTGFzdE5hbWU+PE1pZGRsZU5hbWU+0JDQu9C10LrRgdCw0L3QtNGA0L7QstC40Yc8L01pZGRsZU5hbWU+PERhdGVPZkJpcnRoPjE5ODItMDgtMDU8L0RhdGVPZkJpcnRoPjxJbm4+NTI2MzA5ODIyMjQzPC9Jbm4+PFNuaWxzPjEzMzE3MjU3OTQwPC9Tbmlscz48L1BlcnNvbj4=";

Данные и подпись на которых регулярно происходят ошибки из поста.

Соберите пожалуйста максимально маленький консольный проект, на котором детерминировано воспроизводится ошибка на вашей машине, приложите ссылку на архив с ним.

Также приложите подпись, которую проверяете, и файл сертификата к ней.
upd: подпись увидел в сообщении выше.

Сделал демо. Для запуска необходимо будет установить из вашего источника LibCore.Linux.2023.2.14
Сейчас LibCore установлен из нашего локального nuget'а. Стабильно ловим следующее:

фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!() invalid argument(s)!
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!failed: LastError = 0x57
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!() invalid argument(s)!
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!failed: LastError = 0x57
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: pfx_FillPfxContextFromBlob!() asn1D_PFX failed
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!() invalid argument(s)!
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: CryptDestroyKey!failed: LastError = 0x57
фев 16 16:57:05 fr-app-dev-02 dotnet[2291]: pfx_FillPfxContextFromBlob!() asn1D_PFX failed
фев 16 16:58:55 fr-app-dev-02 audit[2369]: ANOM_ABEND auid=1000 uid=0 gid=0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 pid=2369 comm="dotnet" exe="/usr/share/dotnet/dotnet" sig=11 re>
фев 16 16:58:55 fr-app-dev-02 kernel: dotnet[2369]: segfault at 18 ip 00007efda5fb05e6 sp 00007ffefb9567e0 error 4 in libpthread-2.28.so[7efda5fa9000+10000]

CheckSignatureDemo.zip

Локально воспроизвести пока не получается. Все 10к итераций проходят без segfault.

Можете проверить на сборке по ссылке и вашем мини-примере?
https://file.cryptopro.ru/f/l8iLKSI2BDLfjoXdWsuyFV1gqK3NDKGX/LibCore.Linux.2023.2.17.1.nupkg

ошибка с CryptDestroyKey должна уйти, ошибка с Segmentation fault и 1.2.643.7.1.1.2.2 не факт (скорее нет, чем да, но надо смотреть).

На вашем примере воспроизводится тоже спустя ~30 итераций?
На вашей машине подпись тоже не проверяется (т.е. попадаем в catch на каждой итерации, ибо сертификат недоверенный)?

Сегодня обновлю библиотеку и напишу по результату.
На тестовом стенде падение консольки происходит ~300 запросах, на боевом стенде веб приложении ~30
Проверку не проходит сертификат, т.е да, попадаю в catch.
Но на боевом стенде ошибка происходит и при валидной проверке, когда в catch не заходит.

183 номер итерации проверки
malloc(): invalid next->prev_inuse (unsorted)
CryptDestroyKey!() invalid argument(s)! - ушло
Вот это осталось. capi20>pfx_FillPfxContextFromBlob!() asn1D_PFX failed
Будем пробовать делать на Ubuntu, может быть какая-то проблема с RED OS

Спасибо.

pfx_FillPfxContextFromBlob отдельно посмотрим. По результатам отпишусь.
На 183 итерации как и раньше ловите segfault?

Спасибо.

pfx_FillPfxContextFromBlob отдельно посмотрим. По результатам отпишусь. На 183 итерации как и раньше ловите segfault?

Да. В этой части без изменений

Подняли стенд:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
На этом стенде всё работает без каких-либо ошибок. Проблема только под RED OS

Обнаружили утечку памяти при проверке cms подписей - для локализации и устранение понадобится некоторое время.

Также попробуем воспроизвести segfault на RED OS.

Добрый день! Провели проверку на еще на нескольких стендах Redhat-подобных ОС.
На всех подобная ошибка.

Опубликовали новый релиз, где почистили множество проблем при работе с памятью.
https://github.com/CryptoPro/libcore/releases/tag/2023.3.1.1

Часть проблем, увы, ещё осталось, пытаемся локализовать. Возможно потребуется полная переработка X509, дабы исключить плохой код от ms.

На RED OS ещё пока не проверяли.

Проведём тестирование на наших стендах. Отпишу в этой ветке по результату.

Сделали проверку с новой версией библиотеки:
Mar  3 16:27:34 fr-app-dev-02 kernel: dotnet[66739]: segfault at 18 ip 00007f23c1c545e6 sp 00007ffd49b92f60 error 4 in libpthread-2.28.so[7f23c1c4d000+10000]
Mar  3 16:27:34 fr-app-dev-02 kernel: Code: 24 83 c8 02 83 f8 03 74 f4 e9 d1 fd ff ff 66 0f 1f 44 00 00 f3 0f 1e fa 41 57 41 56 41 55 41 54 55 53 48 89 fb 48 83 ec 08 90 <8b> 57 18 64 8b 04 25 d0 02 00 00 39 c2 74 6b 8b 07 89 c1 89 c2 83
Mar  3 16:27:34 fr-app-dev-02 audit: BPF prog-id=103 op=LOAD
Mar  3 16:27:34 fr-app-dev-02 audit: BPF prog-id=104 op=LOAD
Mar  3 16:27:34 fr-app-dev-02 audit: BPF prog-id=105 op=LOAD
К сожалению, проблема не ушла

Добрый день! Коллеги, нет информации по работоспособности библиотеки на ред-хат системах?

Добрый день.

Про проблему помним, но, увы, пока ещё не смотрели.
Как только появится время - попробуем посмотреть.

Ошибку воспроизвели на своём стенде, пробуем разобраться.

Ошибка, судя по всему, вызвана runtime оптимизацией, но не от inline. Выглядит так, что после нескольких итераций рантайм решает перезагрузить IL код для некоторых методов, что ломает исправления.

Исходная ошибка с segmentation fault вызвана пропажей исправления после нескольких итераций, в результате чего openssl пытается воспользоваться хэндлом сертификата из csp как указателем.

В рамках грязного обхода похоже помогает "прокрутить" нужное (т.е. на котором точно воспроизвелась бы ошибка) число итераций вызываемого метода, и только потом вызвать LibCore.Initializer.Initialize();.

Что с этим делать - пока думаем. На других ОС (не CentOs-like) такого поведения не видели.

Спасибо. Попробуем
Т.е фактически ваш код переписывается стандартной реализацией .net после n вызовов?
А если метод инициализации вызывать после каждой ошибки? Это теоретически может помочь?

Да. потому что наш код, в свою очередь, переписывает стандартную реализацию при инициализации.

По поводу повторной инициализации - может сработать. На нашем тестовом примере помогло. Но, возможно, вылезет ещё какая то ошибка позже, ибо механизм проблемы мы пока не осознали.

Так как исходная ошибка - segmentation fault, которая не перехватывается и падает по сигналу 11, можно в рамках эксперимента попробовать вот эту сборку

https://file.cryptopro.ru/f/gQgGkoVlZvxfrLKBSAWACoHNmnOuuJPG/LibCore.Linux.2023.4.20.1.nupkg

Её чуть модифицировали, дабы падала с более приемлемой ошибкой в управляемом коде, которую можно было бы перехватить в catch.

Спасибо! На след неделе попробуем с новым пакетом.

Очень похоже, что вы столкнулись с tired compilation.
https://learn.microsoft.com/en-us/dotnet/core/runtime-config/compilation
Можно отключить через конфиг/переменные окружения.

@maxdm похоже она самая, выставление

    <PropertyGroup>
        <TieredCompilation>false</TieredCompilation>
    </PropertyGroup>

в csproj помогло на нашем примере, спасибо.

@Poisent попробуйте пожалуйста на своём проекте как сможете с релизной (не той, что кидал выше) версией, при отключенной TieredCompilation (можно и через runtimeconfig, как указанно по ссылке выше.

Ок. На след неделе напишу о результатах.

Подскажите пожалуйста, помимо RED OS на каким именно операционных системах удалось воспроизвести ошибку?

Добрый день! CentOS stream 8

 <PropertyGroup>
        <TieredCompilation>false</TieredCompilation>
    </PropertyGroup>
Настройка сработала, больше не падает. Проверяли на редос 7

Оставлю пока открытой, ещё разбираемся в деталях.
ToDo - написать в readme

В старом readme описано, для текущих версий пока не актуально, ибо нет исправлений рантайма. Если когда то появятся - тоже вопрос к актуальности, ибо был изменён движок установки исправлений (TieredCompilation должна отключаться им в рантайме для методов с детурами).