Как определить, есть ли у процесса привилегии root в сетевом расширении ядра?

Я пишу фильтр сокетов kext, и я хотел бы игнорировать любые соединения, сделанные с правами root. До OS X Lion следующий код работал безупречно:

static boolean_t is_root() {
    proc_t p = proc_self();
    boolean_t isRoot = proc_suser(p);
    proc_rele(p);
    return isRoot;
}

Но теперь с Lion и Mountain Lion функция is_root() всегда возвращает true. В Snow Leopard это сработало, как я и предполагал.

Вот пример того, как я тестировал функцию внутри обработчика событий фильтра сокета:

int debugPid = proc_selfpid();
if (is_root()) {
    printf("%u (root)\n", debugPid);
} else {
    printf("%u (user)\n", debugPid);
}

Но вывод всегда говорит «root», например:

2012-11-15 3:48:00.000 PM kernel[0]: 29879 (root)

Где приложение, осуществляющее соединение, — Twitter (подтверждено через PID). Twitter работает с правами обычного пользователя, а не root.

Есть ли лучший/правильный способ определить, имеет ли процесс, стоящий за подключением к сокету, права root?


person jjs    schedule 15.11.2012    source источник


Ответы (1)


Согласно bsd/sys/proc.h (ссылка):

/* this routine returns error if the process is not one with super user privileges */
int proc_suser(proc_t p);

Таким образом, возврат 0 означает, что процесс имеет привилегии root или ненулевые в противном случае.

Ты хочешь:

static boolean_t is_root() {
    proc_t p = proc_self();
    int error = proc_suser(p);
    proc_rele(p);
    return error == 0;
}
person trojanfoe    schedule 15.11.2012
comment
Спасибо. Не знаю, как я неправильно это понял. Также я мог бы поклясться, что код работал, когда у меня был установлен Snow Leopard. - person jjs; 15.11.2012
comment
Функции proc_xxx() несовместимы, например, proc_exiting() возвращает логическое значение (1/0). - person trojanfoe; 15.11.2012