Системный вызов Clone() в Linux

Что происходит, когда я вызываю системный вызов clone, передавая 0 в качестве stack_start? Согласно страницам руководства по клонированию, он должен возвращать -EINVAL, но когда я это делаю, он показывает ошибку SIGSEGV (11).

clone(func,NULL,0,args);

должен вернуть -EINVAL, но с ошибкой SIGSEGV


person LKL    schedule 12.10.2012    source источник


Ответы (1)


Согласно ядру linux есть такая цепочка вызовов:

sys_clone(...stack_start...) -> do_fork

do_fork(...stack_start...) -> copy_process

copy_process(...stack_start...) -> copy_thread

copy_thread(...stack_start...) на X86_32 ИЛИ copy_thread(...stack_start... ) на X86_64

Глядя на copy_thread, я пришел к выводу, что, поскольку эта функция не проверяет правильность stack_start (аргумент sp в коде), поэтому после клонирования у нас есть задача с недопустимым указателем стека, а первая ссылка по нулевому адресу приводит к SIGSEGV.

Я предлагаю вам также взглянуть на оболочку glibc для функции клонирования.

person Ilya Matveychikov    schedule 12.10.2012
comment
Спасибо, Илья Матвейчиков, за ответ, но в ядре перед вызовом sys_clone указатель start_stack проверяется на NULL, и если он NULL, то присваивается какому-то указателю стека (может быть родительскому указателю стека). Следовательно, вызов fork возвращает pid без ошибки сегментации. но когда дело доходит до пользовательского пространства, он пытается вызвать функцию, указанную в клоне, для этого он должен использовать стек, но стек, который выделяется, не принадлежит этому дочернему процессу, и когда он пытается получить доступ к стеку, это нарушение сегмента, поэтому он получает SIGSEGV. - person LKL; 16.10.2012
comment
@LKL: Ой! Правильно, есть оператор if (!newsp) newsp = regs->sp; at sys_clone... - person Ilya Matveychikov; 16.10.2012