[Linux Kernel] modprobe_path가 안 되는 경우..?

dandb3·2024년 8월 12일
0

linux kernel

목록 보기
16/21

modprobe_path가 항상 동작하는 것이 아니다.
컴파일 타임에 modprobe가 동작하는 방식이 바뀔 수 있다.

우선 modprobe 동작 시 호출되는 함수를 볼 필요가 있다.

call_modprobe()

static int call_modprobe(char *module_name, int wait)
{
	struct subprocess_info *info;
	static char *envp[] = {
		"HOME=/",
		"TERM=linux",
		"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
		NULL
	};

	char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL);
	if (!argv)
		goto out;

	module_name = kstrdup(module_name, GFP_KERNEL);
	if (!module_name)
		goto free_argv;

	argv[0] = modprobe_path;
	argv[1] = "-q";
	argv[2] = "--";
	argv[3] = module_name;	/* check free_modprobe_argv() */
	argv[4] = NULL;

	info = call_usermodehelper_setup(modprobe_path, argv, envp, GFP_KERNEL,
					 NULL, free_modprobe_argv, NULL);
	if (!info)
		goto free_module_name;

	return call_usermodehelper_exec(info, wait | UMH_KILLABLE);

free_module_name:
	kfree(module_name);
free_argv:
	kfree(argv);
out:
	return -ENOMEM;
}

여러 argv, envp의 설정을 마치고 call_usermodehelper_setup()을 호출한다.
이 때 첫 번째 인자로 modprobe_path가 전달되고, 이것이 우리가 아는 그 modprobe_path 변수이다.

call_usermodehelper_setup()

struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv,
		char **envp, gfp_t gfp_mask,
		int (*init)(struct subprocess_info *info, struct cred *new),
		void (*cleanup)(struct subprocess_info *info),
		void *data)
{
	struct subprocess_info *sub_info;
	sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask);
	if (!sub_info)
		goto out;

	INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);

#ifdef CONFIG_STATIC_USERMODEHELPER
	sub_info->path = CONFIG_STATIC_USERMODEHELPER_PATH;
#else
	sub_info->path = path;
#endif
	sub_info->argv = argv;
	sub_info->envp = envp;

	sub_info->cleanup = cleanup;
	sub_info->init = init;
	sub_info->data = data;
  out:
	return sub_info;
}

잘 보면 CONFIG_STATIC_USERMODEHELPER가 정의된 경우에는 CONFIG_STATIC_USERMODEHELPER_PATH, 그렇지 않은 경우에는 인자로 들어온 path가 경로로 저장된다.

CONFIG_STATIC_USERMODEHELPER_PATH는 정해진 경로가 저장된 주소값이다. 즉, 더 이상 modprobe_path를 수정해서 exploit하는 방법은 불가능하다.

하지만 실제 modprobe_path값은 메모리 상으로 존재하긴 한다. 의미는 없지만.

애초에 컴파일 타임에 차이가 발생하는 것이기 때문에 CONFIG_STATIC_USERMODEHELPER가 define 되었는지 아닌지는 call_usermodehelper_setup() 함수의 어셈블리 코드를 보고 확인해도 된다.

Reference

profile
공부 내용 저장소

0개의 댓글

관련 채용 정보