Linux за българи: Форуми

Хумор, сатира и забава => Живота, вселената и някакви други глупости => Темата е започната от: gat3way в Sep 19, 2008, 14:45



Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 14:45
Сега въпросът звучи малоумно на пръв поглед, ама си е доста резонен :)

Преди малко бях потресен от това колко е елементарно за реализиране върху x86 платформа, един процес да тръшне цялата операционна система. По един най-брутален начин, който ми разбива  фантазиите за защитения режим.

Разбира се, има немалко начини да се реализира - примерно можеш да malloc-ваш много памет, докато операционната система се тръшне, да хванеш да пишеш глупости в /dev/mem. Форкбомбите не се приемат, защото там дефакто много процеси тръшват машината.

И сега нещо като задача :) За който му идва наум, най-малката програмка, която да тръшва системата. Може да се изпълнява и с root-ски привилегии, няма значение, въпросът е да не е kernel module, т.е да не се изпълнява в ring0, защото там е изключително лесно да тръшнеш машината.

Аз го реализирах с 5-6 реда на С :) Ама няма да кажа как де :)

Нямате право да форк-вате и изпълнявате други процеси. Идеята е машината да забие.

Айде да видим сега какво ще измислите :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 19, 2008, 15:28
Ми аз ползвах cat..
cat fail > /dev/mem :D
Чудя се, какво ще стане от dd if=/dev/root of=/dev/mem :D не ми се забива системата сега...


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 18:36
Ще крашне :)

Иначе това което ме стресна беше това:

...
iopl(3);
asm("cli");
...

Първото set-ва I/O привилегиите, второто изпълнява инструкцията CLI (която забранява прекъсванията).

По принцип CLI би следвало да може да се вика само в ring0 (kernel-mode). Използва се в критични секции от код (чието изпълнение не бива да се прекъсва), където случайно вдигане на прекъсване може да доведе до кофти проблеми. По този начин се забранява включително timer interrupt-a и следователно process scheduling-a не се случва. Дефакто cli превръща хубавата многозадачна система в нещо подобно на ДОС :) Заради което кодът който се изпълнява между cli/sti трябва да се изпълнява максимално бързо и да е стабилен, защото забие ли, отнася го цялата система. И прост пример - например не искаш context switch-а да бъде прекъснат от току-що получен пакет от мрежовата карта, затова докато трае магията, прекъсванията се забраняват с cli после се разрешават с sti.

Дотук добре, ама се оказва че нещата били малко по-различни :)

x86 архитектурата позволявала освен достъп до периферията (in/out), също така изпълняването на cli/sti инструкциите при условие че CPL<=IOPL. CPL не може да се промени, в линукс всички юзърски процеси имат cpl=3, демек работят в ring3.

IOPL....ами това се променя с iopl(). Ако I/O Privilege Level-a ти стане 3....тогава CPL=3, IOPL=3, CPL<=IOPL => имаш право да забраняваш прекъсванията в рамките на твоят процес!!!

Сега остава забавното, защо това е възможно в линукс.

Съществуването на iopl() е оправдано ЕДИНСТВЕНО заради някои определени X сървъри....както и заради особено великите модерни userspace драйвери.

В линукс съществуват само две положения....ring0 (CPL=0) - kernelspace....и ring3 (CPL=3) - userspace. Архитектурата позволява CPL=1 или 2, но линукс не се възползва от това. Доколкото съм чел обаче, уиндоус го прави.

Единственото хубаво нещо е че ядрото не ти позволява да си смениш IOPL ако не си привилегирован потребител (root).


Сега остават два въпроса:

1) Защо има ТОЛКОВА ОГРОМНО желание в линукс да се имплементират userspace драйвери, след като идейно нещата не са изчистени? Според мен може да се измисли един механизъм, в който въпросните драйвери да работят в ring1 и да има някакъв механизъм чрез който обикновен демон работещ в ring3 да ги изпълнява, да следи дали работят и да ги вдига ако паднат. Съответно да има някакъв механизъм чрез който авторизирани такива модули да могат да се зареждат.

2) Защо развиват теории според които юзърспейските драйвери са толкова стабилни и сигурни, след като един проблем в критична секция може отново да доведе до сриване на цялата система е отвъд моите разбирания.


П.П а ето и една миниатурна програма за крашване на линукс системи :)


Примерен код

#include <sys/io.h>
void main() {
iopl(3);
asm("cli");
while (1) {}
}


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: bulg в Sep 19, 2008, 18:38
Цитат (gat3way @ Сеп. 19 2008,14:45)
Аз го реализирах с 5-6 реда на С :) Ама няма да кажа как де :)
....
Айде да видим сега какво ще измислите :)

Mи кажи, де, щом знаеш. Искаш да 'земеш без да дадеш ... ;)

ред.: Ти вече си си каз`aл, докато съм пис`ал :)





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 19, 2008, 19:31
Уфф, за съжаление, работи. Под нормален акаунт прави Segfault, под руут крашва системата :(
Сега ще го тествам на FreeBSD. Не разбирам много от такива I/O библиотеки и неща, тъй че не мога да преценя дали е Linux-only или се появява в други Unix-подобни системи.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 19:34
FreeBSD може да се окаже по-нормална в това отношение и да ти откаже, ама знам ли и аз :) Нямам грам идея там какво ще стане. Иначе доколкото имам идея и там има ring0/ring3, жалко, не са ги измислили да се възползват като хората от възможностите на архитектурата.

Ъъъ в оправдание на линукс, capability тъпотиите имали предвид iopl() следователно предполагам разните security frameworks там може и да го контролират. Нямам selinux вкъщи на десктопа да тествам, но може и с enforcing режима и дефолтското policy да те бие през ръцете, нямам идея.





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 19, 2008, 19:54
FreeBSD се задържа, Segfault и под root и под нормален юзър :)
Иначе някой с федора има ли да го тества (федора имаше selinux)?


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 19:58
Брей, явно там деятелите на микроядрата не са успели да заразят системата с глупостите си за userspace драйвери:)





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 20:11
Хах, имам един debian-ски image дето го гласих за следваща версия на хахорската игра, той със selinux, в enforced режим, там тия работи не стават, освен ако не ги набия да се изпълняват в някой инитскрипт (там е различен контекста де). Много, много забавно. Там има обаче и selinux policy src някакво и със сигурност съм пипал по него, така че не знам дали не се дължи на някоя моя намеса (което доста ме съмнява). Така че с някаква по-голяма вероятност мога да твърдя че selinux-ките дефолтски политики не позволяват такива глупости, стига да не са изтрщяни в permissive режим :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 19, 2008, 21:37
Микроядра? FreeBSD е с монолитно!
Иначе браво на SELinux :p





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 19, 2008, 21:43
Ем то и линукс ядрото е монолитно, ама на ненормалници трудно може да се угоди :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 19, 2008, 22:02
Незнам какво всички нападате микроядрото :)
Но всъщност монолитно е по-добро, спазват се kiss принципите.

Но предлагам да не спорим микроядро срещу монолотно ядро ;)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: kennedy в Sep 20, 2008, 09:17
аз я привеждам в режим на безпомощност с
avidemux файл_8ГБ_НД_формат ....


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: spec1 в Sep 20, 2008, 09:20
Там,където работя,търкаляме един OpenBSD сървър,
доколкото знам, там този номер с iopl(3) ... cli няма как да мине.
   Е ,не бих го пробвал  :)
   Ако някой знае за  проблеми с OpenBSD ,да пише.
  Иначе gat3way е прав, в повечето случай Linux се крашва.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Mitaka в Sep 20, 2008, 09:44
Вторник ще го тествам на SUN-a.
Просто не ми се пуска сега, поради простата причина, че не ми се ходи пак "на бургия" в офиса. А и си нямам идея дали ако забие ОС-а ще забие и ALOM-a, така, че няма да рискувам :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 20, 2008, 12:07
След малко ще го тествам на OpenSolaris :)
Редакция: Пречка! някой знае ли как се компилира на тая тъпотия?? С "cc" не става, нито пък с "gcc".
Редакция 2: pkg install gcc или pkg install cc не работи също :@





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 20, 2008, 13:10
На Solaris сега чета че няма iopl() syscall имплементиран.

Цитат
I am porting a system software from Linux(32) to OpenSolaris-10. During the feasibility study it is found that the following 4 system calls, are not supported on Solaris.

iopl: changes the I/O privilege level of the current process, as specified in level
...


...

Цитат
No equivalent. Solaris deliberately does not allow applications to access
arbitrary device state from userland without the help of a device driver.

That means two things:

a) iopl() isn't ever necessary; I/O access privilege is equivalent to
device access privilege since "all you need" is the ability to open
device nodes directly. The latter is PRIV_SYS_DEVICES, see the
manpages to privileges(5) and ppriv(1) for further information on
how privileges work in Solaris.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 20, 2008, 13:29
Сега ми хрумна малоумната идея, че това ако много се внимава може да се използва от един процес да харчи безумно много процесорно време, хахах. Много по-ефективно от renice. Като забрани прекъсванията, няма да може да се preempt-ва от task scheduler-a. Само ще трябва все пак да ги разрешава иначе ще се срине системата. И лошото е че няма да може да разчита на sleep() по време на това. Но пък така ексклузивно ще си работи на процесора, просто през това време няма кой да го разкара оттам и няма кой да го убие, ахахха. Дори ядрото няма думата. Е, освен ако по някаква причина не се получи NMI някакво де :) Хм, да, и никакви syscalls и примитиви за синхронизация не могат да се използват, никакво четене и писане по дискове и никаква мрежа.





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: runtime в Sep 20, 2008, 19:40
И под ЦентОС не върви :) Системата не се крашва





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 20, 2008, 20:43
CentOS, Fedora (тия, които произлизат от RedHat) явно си имат SELinux :)
И бъди сигурен, че го рънваш под руут.





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: userc131 в Sep 20, 2008, 21:57
това не бих го пробвал на реално желязо:

Примерен код

find /proc/bus -type f -perm /u+w -exec dd if=/dev/urandom of={} bs=1M count=40 \;


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 20, 2008, 22:53
Хахаха... изглежда доста забавно :D Но мисля, че не спазваш правилата, защото ползваш два процеса: dd и find
От това има много фън ефект: dd if=/dev/urandom of=/dev/fb0 :D Но не става на всички системи, не съм запознат много с тия фреймбуфери тъй че не мога да кажа защо.





Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: ieti в Sep 23, 2008, 15:36
Ето какво се е появило на 17-ти в milw0rm -->  linux/x86 iopl(3); asm("cli"); while(1){} 12 bytes Прилича доста на кода на gat3way.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 23, 2008, 15:59
Да, оттам го видях.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: ieti в Sep 23, 2008, 20:14
Аз си помислих че те са го взели от тук :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 26, 2008, 13:37
А интересно ми е да видя как се появява force-нат panic, ако ще да е и от kernel ring :)


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 26, 2008, 16:00
cmn_err(CE_PANIC,"umri!\n");

panic("UMRI!\n");

Оттам е доста лесно.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 26, 2008, 17:03
Примерен код

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int KernelPanic(void) {
    panic("bla");
    return 0;
}

static void wtf(void) {
    printk(KERN_INFO "You're suposed to panic!");
}

module_init( KernelPanic );
module_exit( wtf );

MODULE_DESCRIPTION( "Panic" );

Това е един модул...
Впечатлих се от това как не се отразяват panic-ите на системата: просто всичко забива. Съобщенията се пускат на tty1 и не се забелязват ако си под X. Аз пък си мислех, че те прехвърля на конзола и показва panic-a. Много е шибано така!


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: tarator в Sep 26, 2008, 17:35
Ivshti,

Доста код трябва да успее да се изпълни за да се превключи от графичен в текстов режим. Когато ядрото се е панирало не е ясно какво още работи и колко дълго ще продължи да работи.

Който следи за паникс, така или иначе обикновено го прави на серийната конзола.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 26, 2008, 19:15
Много сървъри имат т.нар "NMI" бутон или опция в management board-a която предизвиква NMI. Има съответно техен си proprietary модул, който инсталира handler за това прекъсване и позволява записването на crashdump-a примерно върху flash памет когато то се извика. Тъй като NMI прекъсванията не могат да се маскират (демек да се забраняват с cli), това позволява дъмп-а да се събере дори ако ядрото се е крашнало брутално много. Тази флаш памет съответно се носи при производителя и там големите инженерни глави го анализират.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 29, 2008, 18:04
Хм, днеска реших да изтествам тая тъпотия на RHEL понеже съм на едни курсове за RHCE сертификация и работните станции са с тази дистрибуция. Убедих се, че selinux е в enforcing режим....крашна. Явно дефолтските полиси-та не го ловят това с контекста с който аз си работя в конзолата де. Забавно. Очаквах друг резултат, но както и да е.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: Ivshti в Sep 29, 2008, 18:27
Между другото някой знае ли нещо като SELinux, но по-просто устроено?


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: gat3way в Sep 29, 2008, 18:56
Има много разработки. Ако става въпрос само за файловата система, донякъде extended ACLs вършат работа (man setfacl/getfacl).

systrace прави нещо подобно що се отнася до всички syscalls викани от процесите, пак има полисита и т.н.

RSBAC доколкото знам е правено със сходна идея, но никога не съм имал вземане-даване с него.


Титла: Възможно ли е процес да тръшне цялата система
Публикувано от: NaDa в Sep 29, 2008, 23:07
Не сте сами. Grsecurity kernel + PaX изгърмя като за норматив.


Титла: Re: Възможно ли е процес да тръшне цялата система
Публикувано от: ray в Oct 30, 2008, 11:09
Здравейте,

Тествах с RSBAC - системата блокира.
PS: може обаче да се направи така че нов код да не може да се инсталира и/или стартира.
Румен


Титла: Re: Възможно ли е процес да тръшне цялата система
Публикувано от: netgraph в Oct 30, 2008, 16:34
*БСД _не_ са защитени срещу такъв тип код, просто трябва да се модифицира малко (пример надолу). Нормално е да умират :) Единствено OpenBSD по default няма да умре тъй като му трябва securelevel <=0, а той по default е 1.
NetBSD/FreeBSD си умират по default, това го тествах.
А ето кодовете за NetBSD (и за OpenBSD е същия) и за FreeBSD (малко по различен).

Код:
NetBSD
compile: gcc -li386 bla.c -o bla
bla.c:
#include <sys/types.h>
#include <machine/sysarch.h>

int main()
{
  i386_iopl(3);
  asm("cli");
  while(1) {};
}

Код:
FreeBSD
compile: gcc bla.c -o bla
bla.c:
#include <fcntl.h>

int main()
{
  open("/dev/io", O_RDONLY);
  asm("cli");
  while(1) {};
}

Regards.