что такое буфера в раст
Чего не стоит делать в Rust, если начали играть в 2021 году
Rust – это необычный симулятор выживания, который привлек к себе внимание огромное количество геймеров. При этом новички часто думают, что в этом проекте нет ничего сложного, и уже с самого начала делают все то, что и в других играх с элементами выживания.
К сожалению, Rust не отличается особым гостеприимством по отношению к новым игрокам, поэтому стартовать бывает довольно сложно. Перед вами подборка главных ошибок, которые делают новички, решившие поиграть в Rust в 2021 году.
Одному будет тяжело
Rust – далеко не самая лучшая многопользовательская игра для одного человека. Здесь есть несколько этапов развития, и добраться до каждого из них можно только за счет продолжительного гринда. Если играть в команде со своими друзьями, то вы гораздо быстрее достигните цели, чем в одиночку.
Также стоит отметить, что 99% других игроков не дадут вам мирно существовать в виртуальном мире игры. Вам постоянно придется отбиваться от обезумивших «дикарей», которые захотят отобрать ваши вещи и ресурсы. Естественно, ни у одного новичка не получится защитить себя от оравы более опытных игроков, поэтому лучше изначально залетать в Rust хотя бы с парой друзей.
Никому нельзя верить
Этот пункт частично противоречит предыдущему, но при этом он еще более важен. Прежде всего вам стоит забыть о том, что взаимодействие с другими игроками в многопользовательских проектах – это норма. Rust вообще не та игра, где нужно объединяться с незнакомыми людьми, чтобы вместе получить больше лута или ресурсов. Здесь вы можете рассчитывать только на себя, и если начнете доверять первому встречному игроку, то очень скоро поймете, почему этого нельзя делать. Особенно это касается товарищей с хорошей экипировкой, которых вы встретите на своем пути.
Дело в том, что в Rust каждый играет сам за себя, а опытные игроки очень часто обманывают новичков самыми разными способами. Незнакомец, который предложит побегать с ним по виртуальному миру и при этом будет носить броню заметно лучше вашей, скорей всего грифер. Это такой игрок, который при первой же удобной возможности просто вас убьет и заберет все вещи. Так что, начиная играть в Rust, никому не доверяйте!
Курс юного строителя
Если вы вдруг не знали, то в Rust есть строительство, и здесь оно играет довольно важную роль. При этом данная механика имеет ряд особенностей, которые придется изучить в самом начале знакомства с игрой, иначе ваши архитектурные «шедевры» будут попросту разваливаться, а вы впустую потратите ценные ресурсы.
Прежде всего стоит отметить, что у каждого строительного блока есть мягкая и твердая сторона. Во время строительства блок всегда нужно устанавливать таким образом, чтобы твердая сторона находилась снаружи будущего здания. Если не соблюдать это правило и размещать материалы как попало, то вашу постройку сможет развалить первый попавшийся игрок, причем с помощью обычного топора или кирки. Согласитесь, будет не очень приятно наблюдать за тем, как несколько часов ваших трудов кто-то разбирает по кирпичикам за считаные минуты.
Все вещи в одном месте
Огромное количество игроков в Rust вообще не уделяют время крафту. Они считают, что гораздо проще украсть готовые предметы у других пользователей, чем стоять у станка и пытаться что-то сделать. Именно поэтому в этой игре противопоказано хранить все свои вещи в одном месте.
Ни в коем случае не размещайте абсолютно все запасы на единственной базе, да еще и в конкретном помещении. В таком случае после случайного налета кучки любителей халявы вы потеряете абсолютно все. Конечно, вряд ли у новичка хватит ресурсов, чтобы построить себе 4-5 домов и правильно распределить по ним ценные предметы, но хотя бы попробуйте сделать что-то подобное. Неплохим решением будет на территории одной базы построить несколько «нычек» и распределить по ним ресурсы и предметы.
Не забывайте про аптечки
Если вы решите, что аптечки вам не нужны и со своим крутым автоматом вы сможете одолеть кого угодно, то Rust очень быстро вас разочарует. Здесь очень просто погибнуть, и иногда вы даже не будете понимать, почему это вообще произошло. В результате игрок, у которого было полно аптечек, просто завалит вас рандомной палкой и заберет тот самый крутой автомат.
Поставьте себе домофон
Если же вы не можете сделать кодовый замок или уже поставили везде обычные двери, то не делайте ключ. Пускай доступ к зданию будет только у вас. Отсутствие ключа гарантировано защитит ваши владения, даже если вы внезапно погибнете.
Не используйте факел
Дело в том, что свет от факела моментально привлечет к вам внимание других игроков. Часть из них будет гриферами, которые быстро прибегут на ваш «сигнал» и просто убьют. На этом ваш многообещающий забег в Rust просто закончится и придется начинать все сначала. Первое время лучше бегайте без факела и пытайтесь ориентироваться на карте с помощью своего зрения.
Вы всегда в опасности
Многие новички ошибочно думают, что после того, как они построят себе укрытие и обзаведутся хоть какой-то экипировкой, можно просто расслабиться и наслаждаться игровым процессом Rust. Этот проект не об этом, вы всегда будете под прицелом у других игроков! Причем если у вас вдруг все слишком хорошо и на это обратят внимание остальные пользователи игровой сессии, то очень скоро вас ждет набег незваных гостей.
Перестрелка – не самая лучшая идея
Некоторые новички в Rust почему-то считают, что это экшен-шутер, в котором прямо-таки необходимо ввязываться в перестрелки и каждую минуту показывать, кто здесь круче. На самом деле проект про выживание, и я вам гарантирую, что ваша беготня с автоматом закончится очень быстро, если вы вдруг решите, что можете держать всю карту в страхе.
Вот такие советы мы решили дать новичкам, которые только надумали залететь в Rust! Делая все эти вещи, вы гарантировано проживете в виртуальном мире игры чуточку дольше и при этом гораздо лучше узнаете все тонкости проекта. Главное, не забывайте всегда быть начеку, здесь нет зоны комфорта.
Как правильно строить дом новичку в игре Rust
На какой бы вы сервер не зашли, вы всегда будете сталкиваться с такой проблемой, как «рейд». Рейд – это неизбежная ситуация, с которой приходится сталкиваться каждому игроку в игре Rust. Но, если опытные игроки анализируют свои ошибки в постройке, то новички сразу же пытаются покинуть сервер, чтобы «начать с нуля». На самом деле это далеко не правильная позиция, и сейчас я вам детально расскажу, почему я так считаю.
Я начну с нуля на другом сервере и построю крутой дом в игре Rust…
Тебя зарейдили? Ты решил сразу же ливнуть на другой сервер? И? Какой смысл, дружище? Построишь ты опять «коробку», и тебя вновь зарейдят! Хотя ты мог извлечь урок из того рейда, который был на прошлом сервере. Какой? Посмотри на свой дом, и ответь на несколько вопросов:
А теперь посмотри на свой дом, и сам себе ответь на вопрос – вот если бы ты уже знал, что будут рейдить здесь, то, как бы укрепил свой дом? Опа! А тут и решение – сделать так-то и так-то… Если ты уже спалил всю планировку дома, то не советую тебе застраивать этот же дом. Лучше построить другой, пусть и поменьше, но зато более эффективный. Ты уже будешь знать, чем тебя зарейдили, с каких сторон подошли, какие способы рейда использовали. Парень, ты на своих собственных ошибках будешь учиться правильно строить. На самом деле в расте мало построить большую коробку…
Большая коробка или маленький антирейд дом?
Я заметил, что на большинстве серверов, да и большая часть игроков строит большие дома, в основном квадратные коробки. Добраться до лута можно через 3-4 стены. Такие дома не эффективны, зато отнимают у вас много ресурсов. Сейчас на скриншоте ниже я вам покажу примеры «неправильных» и «правильных» домов. Настоятельно советую вам до конца дочитать материал, чтобы построить хороший домик и уже в первые дни игры не потерять его.
Вот как НЕ НАДО строить дома! Это НЕПРАВИЛЬНЫЙ дом в игре Rust
Увидели? На скриншоте выше мы вам показали обычную «КОРОБКУ», которая поддается рейдерству на «раз-два». Причем ломать такие дома можно как с боков, так и сверху, подстроившись к дому. А теперь ниже посмотрите на пример маленького «антирейд» дома, который построен ПРАВИЛЬНО!
Вот так НАДО строить дома. Это ПРАВИЛЬНЫЙ дом в игре Rust!
Самая нужная и надежная вещь в постройке дома – это буферки. Кто не в курсе, буферки –это буферные зоны, которые, чаще всего, не используются, и просто создают дополнительные комнаты и пространства вокруг дома. Один из самых популярных способов выставления буферных зон – это треугольный фундамент и последующее наращивание стен. То есть, вы строите определенный дом, и вокруг его начинаете обустраивать треугольниками, создавая дополнительные стены.
Соответственно, сами понимаете, что вы создаете дополнительную преграду для человека, который собирается рейдить ваш дом. Чем больше у вас буферных зон, тем больше придется потратить рейдеру С4 и ракет. Специально для вас мы создали отдельный раздел схем для игры rust, в котором можно найти просто огромное количество схем антирейдовых домов на все случаи жизни: для соло игроков, для пары игроков, для клана. Все схемы открываются через программу Fortify, которая стоит копейки и привязана к сервису Steam. Обязательно зайдите в этот раздел и посмотрите схемы, которые мы вам предлагаем.
Какой дом строить на сервере в игре Rust?
Все зависит от того, на каком сервере вы играете. Если это классический сервер, то в одиночку построить большой дом у вас не получится. Максимум, на что вы способны – дом 4 на 4 в несколько этажей. Причем вы затратите большое количество времени и усилий. Если же вы играете в команде, то даже на классическом сервере Rust можно построить большой дом с буферными зонами и антирейдом.
Если вы играете на серверах с умножением ресурсов, например, x2-x5, или даже x10, то здесь уже нужно строить большой дом. Благо, для этого у вас все есть, особенно, если вы играете в клане. Но в любом случае мы настоятельно вам рекомендуем строить антирейдовые дома с буферными зонами.
Как правильно поставить шкафы в игре Rust
Построить дом – это одно дело, а вот расставить в нем все ящики и шкафы – это другое, причем не менее важное, чем сам процесс стройки.
Шкаф – это элемент, который блокирует постройку для тех пользователей, которые в нем не авторизованы. То есть, в его радиусе действия смогут строить только те, кто в нем авторизован.
И так, как же правильно расставлять шкафы? Самый простой способ – один шкаф ставится посередине дома. Если вы только начали строить домик, то ставите шкаф и наращиваете стены и этажи.
Как только у вас появится 3, 4 и более этажа, убираете шкаф внизу, и сначала ставите шкаф вверху, тоже посередине дома, а потом через один этаж ставите еще по шкафу. Запомните, что в Rust можно ставить шкафы через один этаж. Даже если рейдер ворвется на первый этаж, сломает стены и авторизуется в вашем шкафу, он не сможет пройти дальше, потому что у вас на 3м этаже отдельный шкаф.
Важно! Обязательно закрывайте шкафы стенами! И не дверями, а стенами! Один раз авторизовались, и замуровали его намертво.
Только обязательно впишите туда всех своих друзей и соклановцев, кто с вами живет. На классике стены и любые строительные элементы можно ремувнуть в течении нескольких минут, если вдруг нужно будет вписать кого-то или поменять расположение. На модифицированных же серверах есть команда /remove, которая позволит вам в любой момент киянкой сломать любые объекты, если ранее вы их ставили.
Правильная расстановка шкафов вокруг дома в игре Rust
Поставить шкафы в доме – это одно! А вот защитить территорию вокруг – это уже другое дело. Вам необходимо взять лист постройки и отойти от дома на такое расстояние, чтобы Building привилегия от шкафа внутри дома исчезла. Как только исчезнет – можете ставить треугольный фундамент, на него шкаф, авторизоваться в нем и все замуровывать. Обязательно Все апгрейдите хотя бы до каменного, чтобы никто не сломал.
Так вам нужно сделать вокруг всего своего дома. Если он у вас прямоугольный, то обычно хватает 4 шкафа вокруг дома по всем направлениям, то есть: сзади дома, спереди дома, слева и справа. Если же дом круглый, то приходится ставить больше шкафов. Обычно где-то 6-8 штук.
Зачем ставить шкафы вокруг дома в Rust? Это делается для того, чтобы к вам не смогли подстроиться другие игроки и прыгнуть на крышу с большой вышки. Обычно это происходит так: игрок построил дом с буферками вокруг дома, но совсем забыл про крышу. Рейдеры подстраиваются с вышкой около дома максимально близко, прыгают на крышу дома и долбят в середину. Несколько этажей вниз – и вот она уже лутовая, шкафы, открытые комнаты и многие другие интересные помещения! Чтобы защитить свой дом – обязательно ставьте вокруг шкафы, и замуровывайте их примерно так же, как на скриншоте ниже.
В этих буферках (треугольниках» стоят шкафы. И они зашиты! Никто не сможет подстроиться к дому
На скриншоте выше показан пример шкафов, которые стоят вокруг дома. Все они закрыты в металлических треугольниках, что обеспечивает защиту вашему дому и блокирует «подстройку» и рейд через крышу. Ниже на скриншоте показаны «усиленные» закупоренные шкафы вокруг дома.
Пример «укрепленной» буферки с шкафами. Так делать можно, когда есть лишние ресурсы.
Как правильно ставить стены в игре Rust
Как же правильно ставить стены? Во-первых, запомните, что стены ставятся внутренней стороной к вам. То есть, стоите вы с листом постройки и ставите стенку. Сторона, которая повернута к вам – это внутренняя сторона, и она ломается быстрее, чем внешняя.
Поэтому когда строите дом – стойте внутри дома, и стройте стены. Если вы стоите за домом и ставите стены, то сразу поворачивайте их.
Как повернуть стенку в Rust? Для этого нажмите на стене, которую нужно повернуть киянкой, и выберите пункт «Повернуть».
Как отличить сторону стены? У внешней стороны поверхность более грубая, чем у внутренней стороны. Это очень хорошо видно на примере каменных стенок. У внешней стороны она темноватая, а у внутренней – светлая, белая. Так вот, белая сторона ломается быстрее, и если вы ее поставите неправильно, то вам быстро выдолбят стены и залезут в дом.
Пример внешней и внутренней стороны стенки каменной в игре Rust
Какие двери лучше ставить в доме в Rust
Одна из распространенных ошибок игроков – это входные двери! Очень часто они ставят деревянные или железные.
Деревянные двери можно вынести патронами, огнеметом, продолбить кирками и топорами. Причем времени на это уйдет очень мало! Как только появится возможность, меняйте дверь и ставьте кодовый замок! Не ключ, а кодовый замок.
Совет! Если все-таки используете ключи, то всегда оставляйте одну копию дома в ящике. Может быть так, что вас «сожрет» медведь или убьют далеко от дома. Вам нужно будет быстро выбежать, а вы не сможете, так как у вас нет ключа. А на его создание может и не быть ресурсов. Вот так проблемка, не правда ли?
Железные двери можно вынести с 4х бобовых С4 или с разрывных патронов. Скрафтить разрывных патронов или бобовых С4 – не проблема!
Поэтому, как только соберете шестеренки для арморной двери, сразу же ставьте ее. Не обязательно по всему дому, но на вход точно. Так вы уже отсеете половину рейдеров, которые в первые дни после вайпа бегают с бобовыми С4 и рейдят небольшие дома.
Как правильно ставить окна в игре Rust
Еще одна наболевшая тема для новичков, которые только начали играть в Rust Experimental. Очень часто вас выносят, потому что вы ставите окна на 1,2 этажах. На первый этаж может зайти любой игрок через окошко, даже если там стоят ставни.
На второй этаж рейдера может подсадить «дружок», и он все равно попадет к вам в дом. Как вылезти – они уж точно придумают.
Если уж вы решили делать окна, то обязательно ставьте решетки и ставни с внутренней стороны дома, чтобы их нельзя было просто так открыть и «спалить» планировку вашего дома. Наиболее оптимальный вариант – установка окошек на верних этажах, начиная с третьего. Рекомендую вам поставить за окном стены, чтобы игроки с улицы не смогли увидеть планировку вашего дома.
Совет! Обязательно смотрите, чтобы не было уступов и гор около вашего дома и окон, иначе можно оттуда подпрыгнуть и залезть в окно.
Это далеко не все, но основные советы для новичков, которые только начали играть в Rust Experimental. Читайте наши другие гайды, следите за обновлениями, и мы научим вас играть «красиво» в Rust и выбиться в топ!
Бесстрашная защита. Безопасность памяти в Rust
В прошлом году Mozilla выпустила Quantum CSS для Firefox, который стал кульминацией восьми лет разработки Rust — безопасного для памяти языка системного программирования. Потребовалось более года, чтобы переписать основной компонент браузера на Rust.
До сих пор все основные браузерные движки написаны на C++, в основном по соображениям эффективности. Но с большой производительностью приходит большая ответственность: программисты C++ должны вручную управлять памятью, что открывает ящик Пандоры уязвимостей. Rust не только устраняет такие ошибки, но его методы также предотвращают гонки данных, позволяя программистам более эффективно внедрять параллельный код.
Что такое безопасность памяти
Когда мы говорим о создании безопасных приложений, то часто упоминаем безопасность памяти. Неофициально мы имеем в виду, что ни в каком состоянии программа не может получить доступ к недействительной памяти. Причины нарушений безопасности:
Подобные нарушения могут привести к неожиданному сбою или изменению предполагаемого поведения программы. Потенциальные последствия: утечка информации, выполнение произвольного кода и удалённое выполнение кода.
Управление памятью
Управление памятью имеет решающее значение для производительности и безопасности приложений. В этом разделе рассмотрим базовую модель памяти. Одно из ключевых понятий — указатели. Это переменные, в которых хранятся адреса памяти. Если мы перейдём по этому адресу, то увидим там некоторые данные. Поэтому мы говорим, что указатель является ссылкой на эти данные (или указывает на них). Так же, как домашний адрес говорит людям, где вас найти, адрес памяти показывает программе, где найти данные.
Всё в программе находится по определенным адресам памяти, включая инструкции кода. Неправильное использование указателей может привести к серьёзным уязвимостям, включая утечку информации и выполнение произвольного кода.
Выделение/освобождение
Когда мы создаём переменную, то программа должна выделить достаточно места в памяти для хранения данных этой переменной. Поскольку у каждого процесса ограниченный объём памяти, конечно, нужен способ освобождения ресурсов. Когда память освобождается, то становится доступной для хранения новых данных, но старые данные живут там до тех пор, пока ячейка не будет перезаписана.
Буферы
Буфер — это непрерывная область памяти, в которой хранится несколько экземпляров одного типа данных. Например, фраза «Мой кот — бэтмен» сохранится в 16-байтовый буфер. Буферы определяются начальным адресом и длиной. Чтобы не повредить данные в соседней памяти, важно убедиться, что мы не читаем и не записываем за пределы буфера.
Поток управления
Программы состоят из подпрограмм, которые выполняются в определённом порядке. В конце подпрограммы компьютер переходит к сохранённому указателю на следующую часть кода (который называется адресом возврата). При переходе на адрес возврата происходит одна из трех вещей:
Как языки обеспечивают безопасность памяти
Все языки программирования принадлежат разным частям спектра. С одной стороны спектра — такие языки, как C/C++. Они эффективны, но требуют ручного управления памятью. С другой стороны — интерпретируемые языки с автоматическим управлением памятью (например, подсчёт ссылок и сборка мусора (GC)), но они расплачиваются производительностью. Даже языки с хорошо оптимизированной сборкой мусора не могут сравниться по производительности с языками без GC.
Ручное управление памятью
Некоторые языки (например, C) требуют от программистов вручную управлять памятью: когда и сколько выделять памяти, когда её освобождать. Это даёт программисту полный контроль над тем, как программа использует ресурсы, обеспечивая быстрый и эффективный код. Но такой подход подвержен ошибкам, особенно в сложных кодовых базах.
Ошибки, которые легко сделать:
Подходящая инструкция по безопасности для тех, кто управляет памятью вручную
Умные указатели
Умные указатели снабжены дополнительной информацией, чтобы предотвратить неправильное управление памятью. Они используются для автоматического управления памятью и проверки границ. В отличие от обычного указателя, умный указатель способен самоуничтожиться и не будет ждать, пока программист удалит его вручную.
Есть разные варианты такой конструкции, которая обёртывает исходный указатель в несколько полезных абстракций. Некоторые умные указатели подсчитывают ссылки на каждый объект, а другие реализуют политику определения контекста (scoping policy) для ограничения времени жизни указателя определёнными условиями.
При подсчёте ссылок ресурсы освобождаются при удалении последней ссылки на объект. Базовые реализации подсчёта ссылок страдают от низкой производительности, повышенного потребления памяти и их трудно использовать в многопоточных средах. Если объекты ссылаются друг на друга (циклические ссылки), то подсчёт ссылок для каждого объекта никогда не достигнет нуля, так что требуются более сложные методы.
Сборка мусора
В некоторых языках (например, Java, Go, Python) реализована сборка мусора. Часть среды выполнения, которая называется сборщиком мусора (GC), отслеживает переменные и определяет недоступные ресурсы в графе ссылок между объектами. Как только объект становится недоступен, GC освобождает базовую память для повторного использования в будущем. Любое выделение и освобождение памяти происходит без явной команды программиста.
Хотя GC гарантирует, что память всегда используется корректно, он освобождает память не самым эффективным способом — иногда последнее использование объекта происходит гораздо раньше, чем сборщик мусора освободит память. Издержки производительности бывают непомерно высоки для критически важных приложений: чтобы избежать падения производительности, приходится использовать иногда в 5 раз больше памяти.
Владение
В Rust для обеспечения высокой производительности и безопасности памяти используется концепция владения (ownership). Более формально, это пример аффинной типизации. Весь код Rust следует определённым правилам, которые позволяют компилятору управлять памятью без потери времени выполнения:
Когда переменная выходит за пределы области видимости, Rust освобождает эту память. В следующем примере переменные s1 и s2 выходят за пределы области, обе пытаются освободить одну и ту же память, что приводит к ошибке double-free. Чтобы предотвратить это, при переносе значения из переменной предыдущий владелец становится недействительным. Если затем программист попытается использовать недопустимую переменную, компилятор отклонит код. Этого можно избежать, создав глубокую копию данных или используя ссылки.
Другой набор правил borrow checker’а относится к времени жизни переменных. Rust запрещает использование неинициализированных переменных и висячих указателей на несуществующие объекты. Если скомпилировать код из примера ниже, r будет ссылаться на память, которая освобождается, когда x выходит за пределы области видимости: возникает висячий указатель. Компилятор отслеживает все области и проверяет допустимость всех переносов, иногда требуя от программиста явного указания времени жизни переменной.
Модель владения обеспечивает прочную основу для корректного доступа к памяти, предотвращая неопределённое поведение.
Уязвимости памяти
Основные последствия уязвимой памяти:
В лучшем случае при ошибке памяти приложение аварийно завершит работу. В худшем случае злоумышленник получит контроль над программой через уязвимость (что может привести к дальнейшим атакам).
Злоупотребления освобождённой памятью (use-after-free, double free)
Этот подкласс уязвимостей возникает, когда какой-либо ресурс освобождён, но на его адрес по-прежнему сохранилась ссылка. Это мощный хакерский метод, который может привести к доступу за пределы диапазона, утечке информации, выполнению кода и многому другому.
Языки со сборкой мусора и подсчётом ссылок предотвращают использование недопустимых указателей, уничтожая только недоступные объекты (что может привести к снижению производительности), а языки с ручным управлением подвержены этой уязвимости (особенно в сложных кодовых базах). Инструмент borrow checker в Rust не позволяет уничтожать объекты, пока на него существуют ссылки, так что эти баги устраняются на этапе компиляции.
Неинициализированные переменные
Если переменная используется до инициализации, то в этой памяти могут быть любые данные, включая случайный мусор или ранее отброшенные данные, что приводит к утечке информации (их иногда называют недействительными указателями). Чтобы предотвратить эти проблемы, в языках с управлением памятью часто используется процедура автоматической инициализации после выделения памяти.
Как и в C, большинство переменных в Rust изначально не инициализированы. Но в отличие от C вы не можете их прочитать до инициализации. Следующий код не скомпилируется:
Пример 3: Использование неинициализированной переменной
Нулевые указатели
Когда приложение разыменовывает указатель, который оказывается нулевым, обычно он просто обращается к мусору и вызывает сбой. В некоторых случаях эти уязвимости могут привести к выполнению произвольного кода (1, 2, 3). В Rust есть два типа указателей: ссылки и необработанные указатели (raw pointers). Ссылки безопасны, а вот необработанные указатели могут стать проблемой.
Rust предотвращает разыменование нулевого указателя двумя способами:
Что делать, если нельзя избежать указателей, допускающих нулевое значение (например, при взаимодействии с кодом на другом языке)? Попытайтесь изолировать ущерб. Разыменование необработанных указателей должно происходить в изолированном unsafe-блоке. В нём ослаблены правила Rust и разрешены некоторые операции, которые могут вызвать неопределённое поведение (например, разыменование необработанного указателя).
— Всё, чего касается borrow chekcer… а что насчёт вон того тёмного места?
— Это unsafe-блок. Никогда не ходи туда, Симба
Переполнение буфера
Мы обсудили уязвимости, которых можно избежать, ограничив доступ к неопределённой памяти. Но проблема в том, что переполнение буфера неправильно обращается не к неопределённой, а к легально выделенной памяти. Как и баг use-after-free, такой доступ может стать проблемой, потому что обращается к освобождённой памяти, где по-прежнему содержится конфиденциальная информация, которая уже не должна существовать.
Переполнение буфера просто означает доступ за пределы области (out-of-bounds). Из-за того, как буферы хранятся в памяти, они часто приводят к утечке информации, которая может содержать конфиденциальные данные, в том числе пароли. В более серьёзных случаях возможны уязвимости ACE/RCE путём перезаписи указателя инструкции.
Пример 4: Переполнение буфера (код C)
Простейшая защита от переполнения буфера — всегда при доступе к элементам требовать проверки границ, но это приводит к снижению производительности.
Что делает Rust? Встроенные типы буферов в стандартной библиотеке требуют проверки границ для любого случайного доступа, но также предоставляют интерфейсы API итератора, чтобы ускорить последовательные обращения. Это гарантирует, что чтение и запись за пределами границ для этих типов невозможны. Rust продвигает шаблоны, которые требуют проверки границ только в тех местах, где почти наверняка придётся вручную размещать их в C/C++.
Безопасность памяти — только полдела
Нарушения безопасности приводят к уязвимостям, таким как утечка данных и удалённое выполнение кода. Существуют разные способы защитить память, в том числе умные указатели и сборка мусора. Вы даже можете формально доказать безопасность памяти. Хотя некоторые языки смирились с падением производительности ради безопасности памяти, концепция владения в Rust обеспечивает безопасность и минимизирует накладные расходы.
К сожалению, ошибки памяти — это лишь часть истории, когда мы говорим о написании безопасного кода. В следующей статье рассмотрим потокобезопасность и атаки на параллельный код.