[Программирование, Java, Разработка под Android, Rust] Rust — теперь и на платформе Android (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 7 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
10-Апр-2021 17:31

Корректность кода на платформе Android является наиважнейшим аспектом в контексте безопасности, стабильности и качества каждого релиза Android. По-прежнему сложнее всего вытравливаются ошибки, связанные с безопасностью памяти и попадающиеся в коде на С и C++. Google вкладывает огромные усилия и ресурсы в обнаружение, устранение багов такого рода, а также в уменьшение вреда от них, старается, чтобы багов в релизы Android проникало как можно меньше. Тем не менее, несмотря на все эти меры, ошибки, связанные с безопасностью памяти, остаются основным источником проблем со стабильностью. На их долю неизменно приходится ~70% наиболее серьезных уязвимостей Android.Наряду с текущими и планируемыми мероприятиями по улучшению выявления багов, связанных с памятью, Google также наращивает усилия по их предотвращению. Языки, обеспечивающие безопасность памяти – наиболее эффективные и выгодные средства для решения этой задачи. Теперь в рамках проекта Android Open Source Project (AOSP) наряду с языками Java и Kotlin, отличающимися безопасностью памяти, поддерживается и язык Rust, предназначенный для разработки операционной системы как таковой. Системное программированиеУправляемые языки, в частности, Java и Kotlin, лучше всего подходят для разработки приложений под Android. Эти языки проектировались в расчете на удобство использования, портируемость и безопасность. Среда исполнения Android (ART) управляет памятью так, как указал разработчик. В операционной системе Android широко используется Java, что фактически защищает большие участки платформы Android от багов, связанных с памятью. К сожалению, на низких уровнях ОС Android Java и Kotlin бессильны.  
На низких уровнях ОС нужны языки для системного программирования, такие как C, C++ и Rust. При проектировании этих языков приоритет отдавался контролируемости и предсказуемости. Они обеспечивают доступ к низкоуровневым ресурсам системы и железу. Они обходятся минимальными ресурсами, прогнозировать их производительность также сравнительно просто.
При работе с C и C++ разработчик отвечает за управление сроком жизни памяти. К сожалению, при такой работе легко допустить ошибки, особенно при работе со сложными и многопоточными базами кода.Rust предоставляет гарантии по поводу безопасности памяти, так как использует сочетание проверок во время компиляции, чтобы обеспечить соблюдение времени жизни объектов и владение ими, а также проверки во время исполнения и таким образом гарантировать валидность обращений к памяти. Такая безопасность действительно обеспечивается, а производительность остается не меньшей, чем при работе с C и C++.Пределы работы в песочницеЯзыки C и C++ не дают таких же гарантий безопасности, как Rust, и требуют надежной изоляции. Все процессы Android укладываются в песочницу, и мы придерживаемся правила двух, принимая решение, требуется ли для конкретной функциональности дополнительная изоляция и снижение привилегий. Правило двух формулируется просто: при наличии следующих трех вариантов действий, разработчики вправе выбрать лишь два из них.  
В Android это означает, что, если код написан на C/C++ и разбирает потенциально небезопасный ввод, то он должен содержаться в жестко ограниченной песочнице без привилегий. Тогда как следование правилу двух хорошо помогает снижать тяжесть и повышать доступность уязвимостей, связанных с безопасностью, оно сопряжено с некоторыми ограничениями. Работа в песочнице – дорогое удовольствие; для ее обеспечения требуются новые процессы, которые сопряжены с дополнительными накладными расходами и провоцируют задержки, связанные с межпроцессной коммуникацией и дополнительным расходом памяти. Работа в песочнице не позволяет полностью исключить уязвимости в коде, а эффективность такой работы снижается при высокой плотности багов, позволяющей злоумышленникам сцеплять вместе множество уязвимостей сразу. Язык, обеспечивающий безопасность памяти, такой, как Rust, помогает преодолеть эти ограничения двумя способами:
  • Снижает плотность багов в нашем коде, тем самым повышая эффективность применяемой песочницы.
  • Снижает потребность в использовании песочницы, поскольку предоставляет новые возможности, которые более безопасны в работе и одновременно менее требовательны к ресурсам.
Что же насчет всего имеющегося C++?Разумеется, если мы введем новый язык программирования, это никак не поможет нам с исправлением уже имеющихся багов в имеющемся коде на C/C++.
Вышеприведенный анализ возраста багов, связанных с безопасностью памяти (отсчитывается с момента их появления) позволяет судить, почему команда Android делает акцент на новых разработках, а не на переписывании зрелого кода на  C/C++. Большинство багов возникает в новом или недавно измененном коде, причем, возраст около 50% багов составляет менее года. Некоторых может удивить, что сравнительно старые баги с памятью встречаются так редко, но выяснилось, что старый код как раз не требует экстренного вмешательства. Со временем программные баги выявляются и правятся, поэтому ожидается, что код, который поддерживается, но активно не разрабатывается, со временем полностью очистится от багов. При снижении количества и плотности багов повышается как эффективность работы в песочнице, так и эффективность обнаружения багов.Ограничения находимости баговВыявление багов при помощи надежного тестирования, очистки и фаззинга критически важно для повышения качества и корректности любых программ, в том числе, написанных на Rust. Ключевое ограничение, с которым в данном случае сталкиваются наиболее эффективные приемы проверки безопасности памяти – в том, что состояние ошибки должно быть спровоцировано в инструментированном коде, и только так его удастся заметить. Даже в коде, отлично покрытом тестами и фаззингом, множество багов проскальзывает в базу именно потому, что их не удалось спровоцировать.Еще одно ограничение связано с тем, что выявление багов масштабируется быстрее, чем их исправление. В некоторых проектахобнаруженные баги не всегда успевают исправить. Исправление багов – долгий и дорогостоящий процесс.
Каждый из вышеприведенных шагов обходится дорого, а если пропустить хотя бы один из них, то баг останется непропатчен у некоторых или даже у всех пользователей. Что касается сложных базах кода на C/C++, зачастую только считанные специалисты могут разработать и внедрить исправление, причем, даже при затрачивании существенных усилий на исправление багов, внесенные изменения бывают некорректными.Выявление багов проходит наиболее эффективно, когда баги относительно редки, и есть возможность устранять опасные баги с должной безотлагательностью, в качестве приоритетных задач. Чтобы можно было улучшить выявление багов, нужно в первую очередь предотвратить проникновение новых багов в базу кода.Предотвращение прежде всегоВ Rust модернизируется ряд языковых аспектов, что позволяет улучшить корректность кода:
  • Безопасность памяти – обеспечивается благодаря сочетанию проверок во время компиляции и во время выполнения.
  • Конкурентность данных – предотвращает гонку данных. Учитывая, насколько легко при этом становится писать эффективный потокобезопасный код, Rust обрел слоган «Безбоязненная Конкурентность».
  • Более выразительная система типов – помогает предотвратить логические ошибки при программировании (напр., обертки нового типа, варианты перечислений с содержимым).
  • Ссылки и переменные по умолчанию являются неизменяемыми – что помогает разработчику следовать безопасному принципу наименьших привилегий. Программист помечает ссылку или переменную как изменяемые, только если в самом деле намерен сделать их таковыми. Притом, что в C++ есть const, эта возможность обычно используется нечасто и несогласованно. Напротив, компилятор Rust помогает избегать случайных аннотаций об изменяемости, так как выдает предупреждения об изменяемых значениях, которые никогда не меняются.
  • Улучшенная обработка ошибок в стандартных библиотеках – потенциально провальные вызовы обертываются в Result, и поэтому компилятор требует от пользователя проверять возможность провала даже для функций, не возвращающих необходимого значения. Это позволяет защититься от таких багов как уязвимость Rage Against the Cage, возникающая из-за необработанной ошибки. Обеспечивая легкое просачивание ошибок при помощи оператора ? и оптимизируя Result с расчетом на низкие издержки, Rust стимулирует пользователей писать все потенциально провальные функции в одном и том же стиле, благодаря чему все они получают ту же защиту.
  • Инициализация – требует, чтобы все переменные инициализировались перед началом использования. Исторически сложилось, что неинициализированные уязвимости памяти были в Android причиной 3-5% уязвимостей, связанных с безопасностью. В Android 11, чтобы сгладить эту проблему, стала применяться автоматическая инициализация памяти на C/C++. Однако, инициализация в ноль не всегда безопасна, особенно для таких штук, как возвращаемые значения, и в этой области может стать новым источником неправильной обработки ошибок. Rust требует, чтобы любая переменная перед использованием инициализировалась в полноценный член своего типа. Тем самым избегается проблема непреднамеренной инициализации небезопасного значения. Подобно Clang в C/C++, компилятор Rust знает о требовании инициализации и позволяет избежать потенциальных проблем производительности, связанных с двойной инициализацией.
  • Более безопасная обработка целых чисел – Очистка во избежание включена в отладочных сборках Rust по умолчанию, что стимулирует программистов указывать wrapping_add, если действительно предполагается допустить переполнение при расчетах, или saturating_add – если не предполагается. Очистка при переполнении в дальнейшем должна быть включена для всех сборок Android. Кроме того, при всех преобразованиях целочисленных типов применяются явные приведения: разработчик не может сделать случайного приведения в процессе вызова функции при присваивании значения переменной или при попытке выполнять арифметические операции с другими типами.   
Что дальшеВведение нового языка на платформу Android – серьезное предприятие. Существуют такие связки инструментов и зависимости, которые необходимо поддерживать, тестовая инфраструктура и оснащение, которые потребуется обновить. Также придется дополнительно обучить разработчиков. Это проект не на один год. Следите за обновлениями в блоге Google.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Jeff Vander Stoep, Stephen Hines
===========
Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_java, #_razrabotka_pod_android (Разработка под Android), #_rust, #_rust, #_c++, #_java, #_android, #_kompiljatory (компиляторы), #_programmirovanie (программирование), #_bezopasnost_mobilnyh_prilozhenij (безопасность мобильных приложений), [url=https://torrents-local.xyz/search.php?nm=%23_blog_kompanii_izdatelskij_dom_«piter»&to=0&allw=0&o=1&s=0&f%5B%5D=820&f%5B%5D=959&f%5B%5D=958&f%5B%5D=872&f%5B%5D=967&f%5B%5D=954&f%5B%5D=885&f%5B%5D=882&f%5B%5D=863&f%5B%5D=881&f%5B%5D=860&f%5B%5D=884&f%5B%5D=865&f%5B%5D=873&f%5B%5D=861&f%5B%5D=864&f%5B%5D=883&f%5B%5D=957&f%5B%5D=859&f%5B%5D=966&f%5B%5D=956&f%5B%5D=955]#_blog_kompanii_izdatelskij_dom_«piter» (
Блог компании Издательский дом «Питер»
)[/url], #_programmirovanie (
Программирование
)
, #_java, #_razrabotka_pod_android (
Разработка под Android
)
, #_rust
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Сен 04:31
Часовой пояс: UTC + 5