Linux内核如何知道应该从系统调用路径参数中读取多少字节?

问题描述 投票:0回答:1

我在google中搜索到,我发现Linux内核将结构体用于变量。

#define EMBEDDED_LEVELS 2
struct nameidata {
    struct path path;
    struct qstr last;
    struct path root;
    struct inode    *inode; /* path.dentry.d_inode */
    unsigned int    flags;
    unsigned    seq, m_seq;
    int     last_type;
    unsigned    depth;
    int     total_link_count;
    struct saved {
        struct path link;
        struct delayed_call done;
        const char *name;
        unsigned seq;
    } *stack, internal[EMBEDDED_LEVELS];
    struct filename *name;
    struct nameidata *saved;
    struct inode    *link_inode;
    unsigned    root_seq;
    int     dfd;
} __randomize_layout;

例如,用于execve系统调用(在https://elixir.bootlin.com/linux/latest/source/fs/exec.c中找到)此函数会将文件名指针作为pathName传递给另一个函数,并将nameidata结构名设置为此pathName

static int __do_execve_file(int fd, struct filename *filename,
                struct user_arg_ptr argv,
                struct user_arg_ptr envp,
                int flags, struct file *file)

我的问题是如何计算从堆栈传递给该函数的参数的长度(例如"/bin/sh")?

((编者注:const char *pathnameexecve(2) arg并不have)指向堆栈内存。我认为这个问题是假设您在shellcode用例中在用户上构造路径的,空间堆栈,然后将其传递给指针。)

((我正在学习汇编,并且被卡在系统调用的参数传递部分中)

assembly linux-kernel parameter-passing system-calls abi
1个回答
0
投票

Linux使用零终止的字符串,这是C的标准字符串格式。字符串的结尾由零字节标记,字符串中第一个零字节之后的任何字节都不是字符串的一部分。值得注意的是,这意味着文件名中不能包含零字节。 (出于同样的原因,大多数shellcode不能有零字节,因为它们是为了利用某种字符串缓冲区溢出。)

实际上,内核通常不需要知道文件名的长度,而使用execve(2)之类的函数逐字节比较字符串,停在比较不同的第一个字节或遇到的第一个零字节处。但是,如有必要,可以使用strcmp之类的函数来计算字符串的长度。

© www.soinside.com 2019 - 2024. All rights reserved.