Clone() системно извикване в linux

Какво се случва, когато извикам системно повикване за клониране, като предам 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, той се присвоява на някакъв указател на стека (може да е указател на родителския стек). Следователно do fork call връща pid без грешка в сегментирането. но когато става въпрос за потребителското пространство, той се опитва да извика функцията, която е посочена в clone, за това трябва да използва стека, но стекът, който е разпределен, не принадлежи на този дъщерен процес и когато се опита да получи достъп до стека, това е нарушение на сегмента, следователно получава SIGSEGV. - person LKL; 16.10.2012
comment
@LKL: Ох! Прав си, има изявление if (!newsp) newsp = regs->sp; на sys_clone... - person Ilya Matveychikov; 16.10.2012