Я искал в 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
systeml (находится здесь 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 *pathname
аргумент для execve(2)
не должен указывать на стековую память. Я думаю, этот вопрос предполагает вариант использования шелл-кода, когда вы создаете путь в стеке пользовательского пространства и передаете на него указатель.)
(Я изучаю сборку, и я застрял в разделе передачи параметров для системных вызовов)
execve
указывает на C-строку с завершением0
/ неявной длиной. Ядро использует какой-тоstrlen
в этой памяти пользовательского пространства, как если бы вы передали егоprintf
. Вы об этом спрашиваете? Вам не нужно знать внутреннее устройство ядра, чтобы просто использовать системные вызовы, такие какexecve
илиopen
, которые принимают строки C по указателю. - person Peter Cordes   schedule 26.12.2019