대답은 파일 시스템에 버그가 없으면 할 수 없다는 것입니다. 그 이유는 다음과 같습니다.
fs/namei.c
called에 정의 된 파일 이름을 바꾸는 시스템 호출이 있습니다 renameat
.
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
시스템 호출이 호출되면 do_path_lookup
이름에 대한 경로 조회 ( )를 수행합니다. 이것을 계속 추적하면 다음과 같은 결과를 얻을 수 link_path_walk
있습니다.
static int link_path_walk(const char *name, struct nameidata *nd)
{
struct path next;
int err;
unsigned int lookup_flags = nd->flags;
while (*name=='/')
name++;
if (!*name)
return 0;
...
이 코드는 모든 파일 시스템에 적용됩니다. 이것은 무엇을 의미합니까? 이는 '/'
전통적인 방법을 사용하여 파일 이름으로 실제 문자가 있는 매개 변수를 전달하려고 하면 원하는대로 수행되지 않음을 의미합니다. 캐릭터를 이스케이프 할 방법이 없습니다. 파일 시스템이 이것을 "지원"한다면 다음 중 하나 때문입니다.
- 유니 코드 문자 또는 슬래시처럼 보이지만 그렇지 않은 것을 사용하십시오 .
- 버그가 있습니다.
당신이 경우 또한, 한 파일 이름에 슬래시 문자를 추가하고 편집 바이트로 이동, 나쁜 일이 일어날 것입니다. 그 이유는 이름으로이 파일을 참조 할 수 없기 때문입니다. :( 언제라도 Linux는 존재하지 않는 디렉토리를 참조한다고 가정 할 것입니다. 'rm *'기술을 사용하면 bash가이를 파일 이름으로 확장하기 때문에 작동하지 않습니다. 심지어 rm -rf
것없는 작업, 간단한 strace를이 일이 후드 (단축) 아래에 이동하는 방법을 알 수 있기 때문에 :
$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0) = 0
unlinkat(3, "out", 0) = 0
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(3) = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...
이러한 호출 unlinkat
은 이름으로 파일을 참조해야하기 때문에 실패합니다.