Отстраняване на грешки в програма setuid / Отказано разрешение със setuid

Това всъщност е въпрос от три части, който ще обясня по-долу, но въпросите са:

  • Използвайки gdb, как мога да стартирам част от програма с root права, а останалата част с нормални?
  • Защо бих получил „отказано разрешение“ с помощта на mkstemp за създаване на файл в /tmp в програма setuid (за root)?
  • Защо "sudo program_name" ще работи по различен начин от просто ./program_name със setuid към root?

Имам C програма, работеща на Linux (множество дистрибуции), която обикновено се изпълнява от потребител с нормални привилегии, но някои части от програмата трябва да работят с root права. За това използвах флага set-UID и това работи добре, що се отнася до него.

Сега обаче бих искал да отстраня грешки в програмата с нормални потребителски права и открих, че имам уловка-22. Току-що добавих функция за създаване на временен файл (/tmp/my_name-XXXXXX) и тази функция се извиква от много точки в програмата. По някаква причина тази функция издава следното съобщение, когато работи:

sh: /tmp/my_name-hhnNuM: Permission denied

(разбира се, действителното име варира.) И все пак, програмата е в състояние да изпълни необработена функция на сокет, която аз абсолютно знам, че не може да се направи от потребители, различни от root. (Ако премахна флага setuid, програмата се проваля мизерно.)

Ако стартирам тази програма чрез gdb без sudo, тя умира при необработения сокет (тъй като gdb очевидно не - или вероятно не може - да уважава флага setuid в програмата). Ако го стартирам под "sudo gdb", тогава всичко работи добре. Ако го стартирам като "sudo ./my_name, всичко работи добре.

Ето изхода ls -l за тази програма:

-rwsr-xr-x 1 root root 48222 Jun 23 08:14 my_name

И така, моите въпроси, без определен ред:

  • (Как) мога да стартирам различни части на програма с различен ефективен UID под gdb?
  • Защо "sudo ./program" е различен от "./program", когато ./program има set-uid на root?
  • Защо mkstemp ще се провали, когато се извика от нормален потребител в програма setuid (за root)?

person Dennis    schedule 23.06.2012    source източник


Отговори (1)


1 Единственият начин за правилно отстраняване на грешки в приложението setuid под gdb е да стартирате gdb като root. Най-разумният начин да направите това за setuid приложение е да се прикачите към приложението, след като започне. Бърз трик за това е да добавите ред в приложението setuid:

kill(getpid(), SIGSTOP);

Това го кара да спре в този момент, след което прикачвате gdb, като използвате:

sudo gdb <application> <pid>

След това сте прикрепени към приложението и можете да го отстранявате както обикновено.

2 sudo променя правилата, тъй като позволява различни елементи от средата на текущия потребител да бъдат експортирани в средата на root потребителя. Това зависи изцяло от текущата конфигурация на sudo и може да ви остави с много различна среда от setuid приложение, поради което трябва да разчитате на трикове като спиране на приложението и след това прикачване към него по време на изпълнение.

Освен това може да има логика в приложението за откриване дали работи в setuid среда, което всъщност не е така, когато се изпълнява под sudo - не забравяйте, че sudo настройва всички полета за id на процеса (реален uid, ефективен uid и запазен uid) на едно и също стойност, която setuid няма (истинският uid все още е този на оригиналния повикващ). Можете да използвате getresuid() извикване за определяне на състоянието на трите променливи.

3 Работата е там, че съобщението Permission Denied има префикс sh:; това изглежда означава, че се изпълнява друг подпроцес, който се опитва да получи достъп до файла. След като извикате mkstemp, може да искате да разхлабите разрешението за четене на файла, така че подпроцесът да може да чете файла.

person Petesh    schedule 23.06.2012
comment
Чудесен! mkstemp() се използва за създаване на имейл съобщение, а след това sendmail трябваше да прочете файла и да го изпрати. Не ми беше хрумвало, че, разбира се, процесът на sendmail не приема правата на своя родител. (На платформата, за която обикновено програмирам: AS/400 / iSeries / System i, такова приемане е естествено. Това е моето извинение и се придържам към него!) Благодаря! И благодаря за напомнянето как да отстранявате грешки в работещ процес! - person Dennis; 24.06.2012