본문 바로가기

openat2() :: 경로 해석 조건을 제한하면서 파일 열기

2026.03.01 16:33:14 360

    • 글자 크기

C 언어에서 외부에서 받은 경로를 열 때 상위 디렉터리로 빠져나가거나 심볼릭 링크를 따라가는 것까지 제한하려면 openat2()를 볼 만하다.

작게 실행해 보기

#define _GNU_SOURCE
#include <fcntl.h>
#include <linux/openat2.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>

int main(void) {
    struct open_how how = {0};
    how.flags = O_RDONLY;
    int fd = syscall(SYS_openat2, AT_FDCWD, "/dev/null", &how, sizeof(how));
    if (fd < 0) {
        perror("openat2");
        return 1;
    }
    printf("fd=%d\n", fd);
    close(fd);
    return 0;
}

최소 예제는 경로 제한 없이 읽기만 한다. how.resolve에 RESOLVE_* 조건을 추가하는 것이 일반 open()과 비교할 핵심 차이다. 오래된 커널이면 지원 오류가 난다.

반환값과 주의점

성공하면 파일 디스크립터, 실패하면 -1이고 errno가 설정된다. 오래된 커널에서는 ENOSYS로 실패할 수 있다.

open_how 구조체를 0으로 초기화하고 flags와 resolve를 채운다. 예를 들어 RESOLVE_BENEATH는 지정한 디렉터리 밖으로 벗어나는 경로 해석을 막는다. glibc 전용 함수가 없어 syscall()로 부른다.

예제 실행 방법
gcc -std=c11 -Wall -Wextra example.c -lm -o example
./example

참고: openat2 — Linux man-pages

전자기기 쪽으로 문외한 저희 부모님과 지인을 보고 컴퓨터 쪽에 지식이 없는 분들도 쉽게 프로그램을 이용할 수 있도록 하자는 생각으로 포스팅을 하고 있으며 유익한 정보를 최대한 많이 담아두는 것이 저의 궁극적인 목표입니다.
creat() :: 파일을 새로 만들거나 내용을 비우고 열기 openat() :: 디렉터리 디스크립터를 기준으로 파일 열기

답글 달기

전화번호 또는 이메일을 남겨두시면 댓글이 달렸을경우 알려드립니다.
사진 및 파일 첨부

여기에 파일을 끌어 놓거나 왼쪽의 버튼을 클릭하세요.

파일 용량 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )

번호 제목 날짜
41 fdatasync() :: 파일 데이터를 중심으로 저장 장치에 동기화하기 2026.03.09
40 fsync() :: 파일 데이터와 메타데이터를 저장 장치에 반영하기 2026.03.09
39 readahead() :: 필요해질 파일 데이터를 미리 읽도록 요청하기 2026.03.09
38 vmsplice() :: 사용자 버퍼를 파이프에 연결하기 2026.03.08
37 tee() :: 파이프 데이터를 소비하지 않고 다른 파이프로 복제하기 2026.03.08
36 malloc() :: 동적 메모리 할당하기 2026.03.08
35 splice() :: 파이프와 파일 사이 데이터를 커널에서 이동하기 2026.03.08
34 free() :: 할당한 메모리 반환하기 2026.03.08
33 copy_file_range() :: 커널 안에서 파일 구간 복사하기 2026.03.07
32 sendfile() :: 파일 데이터를 커널 안에서 다른 디스크립터로 보내기 2026.03.07
31 lseek() :: 열린 파일의 현재 오프셋 이동하기 2026.03.07
30 pwritev2() :: 플래그를 지정한 위치 기반 벡터 쓰기 2026.03.07
29 preadv2() :: 플래그를 지정한 위치 기반 벡터 읽기 2026.03.07
28 pwritev() :: 여러 버퍼를 지정 위치에 기록하기 2026.03.06
27 preadv() :: 지정 위치의 데이터를 여러 버퍼로 읽기 2026.03.06
26 writev() :: 여러 버퍼를 한 번에 모아서 쓰기 2026.03.06
25 readv() :: 여러 버퍼로 한 번에 분산해서 읽기 2026.03.06
24 pwrite() :: 파일 오프셋을 바꾸지 않고 지정 위치 쓰기 2026.03.05
23 pread() :: 파일 오프셋을 바꾸지 않고 지정 위치 읽기 2026.03.05
22 write() :: 파일 디스크립터에 바이트 쓰기 2026.03.05
21 read() :: 파일 디스크립터에서 바이트 읽기 2026.03.05
20 freopen() :: FILE 스트림을 다른 파일에 다시 연결하기 2026.03.05
19 fclose() :: FILE 스트림을 닫고 버퍼 기록하기 2026.03.04
18 fdopen() :: 기존 디스크립터를 FILE 스트림으로 감싸기 2026.03.04
17 fileno() :: FILE 스트림에서 파일 디스크립터 얻기 2026.03.04
16 lockf() :: 파일의 바이트 범위에 잠금 걸기 2026.03.04
15 flock() :: 열린 파일에 공유 또는 배타 잠금 설정하기 2026.03.04
14 fcntl() :: 파일 디스크립터 플래그와 잠금 제어하기 2026.03.03
13 sendto() :: UDP 목적지를 지정해서 보내기 2026.03.03
12 recv() :: 연결된 소켓에서 데이터 받기 2026.03.03
11 dup3() :: close-on-exec 플래그와 함께 디스크립터 복제하기 2026.03.03
10 send() :: 연결된 소켓으로 데이터 보내기 2026.03.02
9 recvfrom() :: UDP 데이터와 보낸 주소 함께 받기 2026.03.02
8 dup2() :: 지정한 번호로 파일 디스크립터 복제하기 2026.03.02
7 dup() :: 기존 파일 디스크립터 복제하기 2026.03.02
6 close_range() :: 디스크립터 범위를 한 번에 닫기 2026.03.02
5 close() :: 열린 파일 디스크립터 닫기 2026.03.01
4 creat() :: 파일을 새로 만들거나 내용을 비우고 열기 2026.03.01
openat2() :: 경로 해석 조건을 제한하면서 파일 열기 2026.03.01
2 openat() :: 디렉터리 디스크립터를 기준으로 파일 열기 2026.03.01
1 open() :: 경로를 열어 파일 디스크립터 얻기 2026.03.01

게시글 URL이 복사되었습니다.

비회원이 작성한 게시글은 댓글 작성마다 닉네임이 변경되므로 동일인임을 알 수 있도록 IP 주소 배열 2번째까지 공개합니다.

SKT, KT, LG U+ : 각 통신사 사용자가 남긴 댓글입니다.

Personal : 와이파이나 랜선에 직접 연결된 사용자가 남긴 댓글입니다.

회원만 다운로드가 가능합니다.
확인을 누르면 회원가입 페이지로 이동합니다.

회원이라면 로그인 후 다시 시도해 보세요.
확인을 누르면 회원가입 페이지로 이동합니다.

글을 모두 읽을때까지 소요되는 추정 시간 입니다.

업로드/다운로드 속도는 서버의 네트워크 트래픽 정보 입니다.
개별 사용자의 속도와는 관련이 없습니다.

콕 찔렀습니다!

PC가 이미 켜져 있습니다.

알 수 없는 오류가 발생했습니다.

PC에 전원 ON 명령을 요청했습니다.

PC 전원이 켜졌습니다.