Чи можливо зчитувати пам'ять з іншої програми, виділивши весь порожній простір у системі?


26

Теоретично, якби я створив програму, яка виділяла всю невикористану пам'ять в системі, і продовжувала запитувати все більше пам’яті, оскільки інші програми звільняли пам'ять, яка їм більше не потрібна, чи можна було б прочитати нещодавно звільнену пам'ять з інших програм ? Або це якось захищено сучасною операційною системою?

У мене немає практичного застосування для цього, мені просто цікаво. Я усвідомлюю, що з розподілом "всієї доступної пам'яті" в реальному житті є деякі проблеми.

Редагувати: Щоб уточнити, я запитую конкретно про "Вивільнену" пам'ять, не отримуючи доступ до пам'яті, яка зараз виділена іншою програмою.

Відповіді:


23

Ні, тому що хороше ядро ​​стирає вміст пам'яті до того, як воно буде видане, щоб захистити від саме тієї атаки, яку ви пропонуєте.

У системах Unixy пам'ять виділяється процесам шляхом розширення, що називається, перерви в програмі , що є межею практично адресованого простору, який може використовувати процес. Процес повідомляє ядру, що хоче розширити свій адресний простір, і ядро ​​дозволить йому, якщо пам'ять доступна або виклик не вдасться, якщо ні. (Назва brk()системного виклику походить від цієї концепції.)

На практиці великі блоки звільненої пам’яті часто не стикаються з перервою в програмі, що і потрібно для процесу повернення пам’яті до ядра шляхом зменшення перерви в програмі. Це, звичайно, все залежить від впровадження вашої системи malloc()та free(). Якщо у вас є джерела, вони підкажуть, повертається чи ні пам'ять.

Немає жодних наслідків для безпеки для malloc()ініціалізації пам’яті, оскільки все, що було отримано через brk(), було вичищено, і все, що раніше free()d було б записане тим самим процесом.


19

Так, теоретично можна прочитати звільнену пам'ять іншого процесу. Це стало джерелом ряду атак ескалації привілеїв ще за той час. Через це операційні системи в даний час ефективно нулюють пам'ять, якщо вона раніше була виділена іншим процесом. Причина, коли ви не завжди бачите нульову пам'ять, полягає в тому, що ефективніше не нульову пам'ять, якщо вона раніше була розподілена тим самим процесом. ОС намагається повернути сторінки пам’яті до того самого процесу, якщо це можливо.


1
"Так, але ні" - це "ні". @Blrfl має право.
Росс Паттерсон

4
@RossPatterson: Щодо теоретичної точки зору, Карл насправді має рацію, ніж я. Практична реальність полягає в тому, що основні ОС багато років тому закрили цю діру.
Blrfl

@Blrfl Зрозумів. Але "роки тому" це було наприкінці 1960-х, коли вперше були запроваджені системи підкачки та віртуальна пам'ять. Безумовно, до часу Multics, VM / 370 та OS / VS. Відсутні помилки, це не вдалося в пам'яті більшості практикуючих програмістів.
Росс Паттерсон

The reason you don't always see zeroed out memory is because it is more efficient not to zero out the memory if it was previously allocated by the same process Я бачу тут деяку непослідовність. Ви мали на увазі "той самий виконуваний файл"? Як перевіряється, чи не нульове значення - шляхом диска?
jakub.g

1
Я думаю, що мені чогось не вистачає. Чому тоді, коли я компілюю і запускаю якусь програму C ++ з, скажімо, неініціалізованими цілими числами, вони не дорівнюють 0, коли я читаю ці змінні?
jakub.g

2

Тут задіяно кілька шарів, які впливають на відповідь.

Якщо ви припускаєте сучасну операційну систему віртуальної пам'яті, ви не зможете побачити залишки даних інших процесів на сторінках, які ви виділяєте.

Коли процес спочатку завантажується, таблиця сторінок завантажується, і потенційно кадри реальної пам'яті виділяються на ці сторінки. Як мінімум, таблиця сторінок або її додаткова таблиця міститимуть карту всієї пам'яті, яку процес може виділити. Тут також встановлюється початковий перерва у процесі, згаданий вище.

Хоча malloc (), якщо процес дозволений, може призвести до зміни перерви процесу, додавши більше сторінок до таблиці процесів (додаткової сторінки), щоб задовольнити запит, місце, де один процес може "отримати інший", обробляє дані. нижній реальний шар пам'яті.

В обох цих сценаріях сучасна операційна система, яка використовує пейджинг попиту або лінивий розподіл, ще не виділяє фізичну пам'ять (кадри). Операційна система просто "записує" про те, яка віртуальна пам'ять для цього процесу вважається дійсною. Фактична пам'ять присвоюється лише за потреби.

Фізична пам'ять або кадри виділяються під час процесу, коли віртуальна сторінка реалізована і відображена в таблицю сторінки процесів. Тут існує потенціал експозиції даних. Це відбувається під час помилки сторінки. Експозиція полягає в тому, що попередній процес, можливо, використовував той самий кадр, і його дані були або залишені, або замінені, щоб звільнити місце для поточного запиту фізичної пам'яті. Операційна система повинна бути обережною, щоб переконатися, що дані запитуючих процесів належним чином замінені або кадр очищений (нульовий) перед тим, як відновити процес. Це також згадується вище як "стара, але вирішена" проблема.

Це робить дещо неактуальним, чи пам'ять інших процесів була "звільнена" чи ні. Інші процеси "звільненої" пам'яті все ще знаходяться на сторінках, призначених для цього процесу, і, як правило, не знімаються, поки процес не закінчиться, оскільки вони будуть просто замінені, коли пам'ять знизиться або їх інакше буде виселено. malloc () та free () керують віртуальною пам'яттю, призначеною для процесу на рівні (користувач).

У вашому запитанні ваш процес продовжує вимагати все більшої кількості пам'яті, теоретично витісняючи з пам'яті всі інші процеси. Насправді існують стратегії розподілу кадрів - глобальні та локальні - які також можуть впливати на відповідь. Цілком ймовірно, що процес витіснить власні сторінки з пам'яті, перш ніж йому буде дозволено перевиконати операційну систему та всі інші процеси. Хоча це виходить за рамки вашого початкового питання.

Все це суперечки в такій системі, як MS-DOS. MS-DOS (та інші, простіші системи) не використовують віртуальну пам'ять (самостійно), і ви можете легко підштовхувати та продавати інші дані "обробляти".

Деякі хороші посилання, які можуть бути простішими для розуміння, ніж вихідний код Linux, - це хороша навчальна книга з операційними системами, Концепції операційних систем Silberscatz, Gavin і Gange, або Дизайн операційних систем Ендрю Таненбаума. Також щось на кшталт Nachos від Berkeley або Pintos зі Стенфорда - це невеликі операційні системи, побудовані для навчання та мають у собі ці самі ідеї.


0

Я спробував це на Ubuntu 16.04 місяців тому. Як зазначає 0xACE, сучасна ОС виділяє віртуальну сторінку, повністю нульову, як тільки ви викликаєте malloc (). Але якщо ви нічого не запишете у виділений буфер, він не буде відображатися у фізичну пам'ять (тобто принцип копіювання при записі), таким чином ви завжди будете читати нулі з "неініціалізованого" блоку. Можливо, є якась вбудована ОС, складена з опцією "CONFIG_MMAP_ALLOW_UNITIALIZED" для кращої продуктивності, у цьому випадку ви можете отримати те, про що ви хотіли.


-1

Ні, це не дозволить іншій програмі читати пам'ять чужого завдяки магії пейджингу . Таким чином, загальне використання пам'яті може перевищити фізичний таран, завантаживши його частини на жорсткий диск.

Крім того, максимальна пам'ять, яку може виділити процес, довільно обмежена ОС (до 4 гігів для 32-бітної архітектури), після чого наступний allocвиклик поверне помилку з пам'яті.


Чи не існують конкретні API для платформи, які можуть це обійти? Я, чесно кажучи, не знаю, але мене не здивувало (наприклад, Linux дозволяє запобігти переміщенню сторінки з фізичної пам'яті через ОС mlock).

Якщо оперативної пам’яті є 4 ГБ, а підкачка обмежена на 8 ГБ, що робити, якщо програма вимагає 12 ГБ (на x64)?
Арсеній Муренко

тоді системні виклики повинні повернути помилку, коли залишиться занадто мало вільної пам’яті, або комп'ютер просто заглушиться, коли не залишиться…
грохот freak

4
Він не питає про читання пам’яті чужому, а скоріше читає їх ЗВІЙНУЮ пам'ять. Цей розділ оперативної пам'яті наразі вільний, і .... я не думаю ... що схеми пейджингового сповіщення знімають пам'ять після звільнення. Таким чином програма виділила б блок пам'яті та проаналізувала неініціалізовані дані, які вже є.
Філіп

@philip правильно, я прошу конкретно про звільнену пам'ять.
ConditionRacer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.