我正在尝试使用原始克隆系统调用来避免将 pid 0 代码重构为函数。Linux 要求堆栈为 16 字节,此外,libc 保留 16 位可能用于存储 ptid 和 ctid。下面的代码创建一个对齐的堆栈,然后从子级退出。在等待 libc 包装器克隆的子级之后,我使用相同的缓冲区使用了原始系统调用,但每次程序在使用原始系统调用时都会出现段错误。附加的是 strace 的输出,除非我忽略了任何东西,否则系统调用参数两次都相同。 至少还有一个问题 原始克隆系统 调用 SO 其中 OP 似乎有类似的困难,不幸的是,接受的答案使用 libc 克隆包装器而不是系统调用。
#define _GNU_SOURCE
#include <sched.h>
#include <stdalign.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <syscall.h>
#include <signal.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
int test(void*c)
{
quick_exit(0);
}
int main(void)
{
alignas (16) unsigned char stack[4096] = {0};
printf("Top of stack %pn", stack+sizeof(stack));
printf("Top of stack minus 16 %pn", stack+sizeof(stack)-16);
pid_t pid = clone(test, stack+sizeof(stack), CLONE_VM|SIGCHLD, 0, 0, 0, 0);
wait(NULL);
memset(stack, 0, sizeof stack);
pid = syscall(SYS_clone, CLONE_VM|SIGCHLD, stack+sizeof(stack)-16);
if (pid == 0)
quick_exit(0);
wait(NULL);
quick_exit(0);
}
跟踪输出:
clockley@ubuntu:~$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 57 vars */]) = 0
brk(NULL) = 0x55b1e58ee000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70303a0000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/tls/x86_64", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/tls", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/x86_64", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/opt/google/chrome/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/lib/tls/x86_64", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/lib/tls", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/lib/x86_64", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/opt/google/chrome/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/google/chrome/lib", 0x7ffcc0e2e400) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=171231, ...}) = 0
mmap(NULL, 171231, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7030376000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF2113 3 >