进程:execve加载流程

本文深入剖析了Linux内核如何通过execve函数加载可执行文件。从do_execve到do_execveat_common,再到bprm_execve,详细阐述了加载过程中涉及的权限检查、参数验证、内存布局、安全上下文、审计结构填充等关键步骤。同时,介绍了cred结构、nameidata结构等核心数据结构的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

续上一篇<<ELF:加载过程>>中分析elf解析器、解析器填充等内容后,本章分析elf可执行程序加载过程。

目录


1. 源码流程

1.1 execve

2. 源码结构

3. 部分结构定义

4. 扩展函数


内容


1. 源码流程

1.1 execve

  execve函数用于装载一个可执行文件以进程为单位加载到内存中,execve在内核空间中的调用可以追溯到kernel_execve -> run_init_process函数,而用户空间通过SYSCALL_DEFINE3(execve…)->do_execve进入函数:

static int do_execve(struct filename *filename,
        const char __user *const __user *__argv,
        const char __user *const __user *__envp)
{
        struct user_arg_ptr argv = { .ptr.native = __argv };
        struct user_arg_ptr envp = { .ptr.native = __envp };
        return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
        // #define AT_FDCWD   -100   用于指示openat应使用当前工作目录(./)
}
||
\/
static int do_execveat_common(int fd, struct filename *filename,
                              struct user_arg_ptr argv,
                              struct user_arg_ptr envp,
                              int flags)
{
        struct linux_binprm *bprm;
        int retval;
		...
		if ((current->flags & PF_NPROC_EXCEEDED) &&
            is_ucounts_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) {
        // 如果已经超过用户最大进程数量 并且 用户的某个(计数中的)命名空间大于最大值,返回错误
        // #define PF_NPROC_EXCEEDED       0x00001000  超出最大进程数
                retval = -EAGAIN;
                goto out_ret;
        }

		current->flags &= ~PF_NPROC_EXCEEDED; // 去掉用户进程数量状态标志

		bprm = alloc_bprm(fd, filename);  // 分配bprm
		// 用于保存可执行文件相关信息
		// 可执行文件路径,执行参数,环境变量等等

		retval = count(argv, MAX_ARG_STRINGS);
		// 检查参数是否有效,参数数量是否大于最大值,并捕获异常信号、KILL信号等等
		// #define MAX_ARG_STRINGS 0x7FFFFFFF
        if (retval == 0)
                pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n",
                             current->comm, bprm->filename);

		bprm->argc = retval;

        retval = count(envp, MAX_ARG_STRINGS); // 环境变量检查

		retval = bprm_stack_limits(bprm); // 检查栈是否超出限制

		/* 从内核复制和参数/环境字符串到进程堆栈 */
		retval = copy_string_kernel(bprm->filename, bprm);

		bprm->exec = bprm->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坤昱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值