Man page - memfd_create(2)

Packages contains this manual

Available languages:

en fr ja ru

Manual

MEMFD_CREATE

名 前
書 式
説 明
返 り 値
エ ラ ー
バ ー ジ ョ ン
準 拠
注 意
file sealing

プ ロ グ ラ ム の ソ ー ス : t_memfd_create.c
プ ロ グ ラ ム の ソ ー ス : t_get_seals.c
関 連 項 目
こ の 文 書 に つ い て

名 前

memfd_create - 無 名 フ ァ イ ル (anonymous file) を 作 成 す る

書 式

#define _GNU_SOURCE /* feature_test_macros(7) 参 照 */
#include <sys/mman.h>

int memfd_create(const char * name , unsigned int flags );

説 明

memfd_create () は 、 無 名 フ ァ イ ル (anonymous file) を 作 成 し 、 そ の フ ァ イ ル を 参 照 す る フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 こ の フ ァ イ ル は 通 常 の フ ァ イ ル と 同 様 に 振 る 舞 い 、 変 更 、 切 り 詰 め (truncate)、 メ モ リ ー マ ッ プ な ど を 行 う こ と が で き る 。 し か し 、 通 常 の フ ァ イ ル と は 違 い 、 こ の フ ァ イ ル は RAM 上 に 置 か れ 、 格 納 さ れ る ス ト レ ー ジ は 揮 発 性 で あ る 。 こ の フ ァ イ ル へ の 参 照 が す べ て な く な る と 、 フ ァ イ ル は 自 動 的 に 解 放 さ れ る 。 こ の フ ァ イ ル が 置 か れ る ペ ー ジ に は 無 名 メ モ リ ー (anonymous memory) が 使 用 さ れ る 。 し た が っ て 、 memfd_create () で 作 成 さ れ た フ ァ イ ル は 、 他 の 無 名 メ モ リ ー の 割 り 当 て ( MAP_ANONYMOUS フ ラ グ 付 き の mmap (2) を 使 っ て 割 り 当 て ら れ た 無 名 メ モ リ ー な ど ) と 同 じ 動 作 を す る 。

フ ァ イ ル の 初 期 サ イ ズ は 0 に 設 定 さ れ る 。 呼 び 出 し の 後 に 、 ftruncate (2) を 使 っ て フ ァ イ ル サ イ ズ を 設 定 す べ き で あ る (代 わ り に 、 write (2) や 同 様 の 関 数 を 呼 び 出 し て フ ァ イ ル に デ ー タ を 書 き 込 む こ と も で き る )。

name に 指 定 さ れ た 名 前 は フ ァ イ ル 名 と し て 使 用 さ れ 、 デ ィ レ ク ト リ /proc/self/fd/ で 対 応 す る シ ン ボ リ ッ ク リ ン ク の リ ン ク 先 と し て 表 示 さ れ る 。 表 示 さ れ る 名 前 の 前 に は 常 に memfd: が 付 き 、 こ の 名 前 は デ バ ッ グ 用 途 と し て の み 機 能 す る 。 名 前 は フ ァ イ ル デ ィ ス ク リ プ タ ー の 動 作 に は 影 響 せ ず 、 複 数 の フ ァ イ ル が 同 じ 名 前 を 持 っ て も 副 作 用 は な い 。

以 下 の 値 を ビ ッ ト 論 理 和 で flags に 指 定 し て 、 memfd_create () の 動 作 を 変 更 で き る 。
MFD_CLOEXEC

新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー に close-on-exec ( FD_CLOEXEC ) フ ラ グ を セ ッ ト す る 。 こ れ が 有 用 な 理 由 に つ い て は open (2) の O_CLOEXEC フ ラ グ の 説 明 を 参 照 の こ と 。

MFD_ALLOW_SEALING

こ の フ ァ イ ル に 対 し て sealing 操 作 を 許 可 す る 。 fcntl (2) の F_ADD_SEALS F_GET_SEALS 操 作 の 議 論 を 参 照 。 下 記 の 「 注 意 」 も 参 照 。 初 期 の seal 集 合 は 空 と な る 。 こ の フ ラ グ を 指 定 し な か っ た 場 合 、 初 期 の seal 集 合 は F_SEAL_SEAL と な り 、 こ れ は こ の フ ァ イ ル に は 他 の seal を セ ッ ト で き な い こ と と い う こ と で あ る 。

MFD_HUGETLB (Linux 4.14 以 降 )

The anonymous file will be created in the hugetlbfs filesystem using huge pages. See the Linux kernel source file Documentation/admin-guide/mm/hugetlbpage.rst for more information about hugetlbfs. Specifying both MFD_HUGETLB and MFD_ALLOW_SEALING in flags is supported since Linux 4.16.

MFD_HUGE_2MB , MFD_HUGE_1GB , ...

Used in conjunction with MFD_HUGETLB to select alternative hugetlb page sizes (respectively, 2 MB, 1 GB, ...) on systems that support multiple hugetlb page sizes. Definitions for known huge page sizes are included in the header file <linux/memfd.h>.

For details on encoding huge page sizes not included in the header file, see the discussion of the similarly named constants in mmap (2).

flags の 未 使 用 の ビ ッ ト は 0 で な け れ ば な ら な い 。

返 り 値 と し て memfd_create () は 、 作 成 し た フ ァ イ ル を 参 照 す る の に 使 用 で き る 新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 こ の フ ァ イ ル デ ィ ス ク リ プ タ ー は 読 み 書 き 両 用 ( O_RDWR ) で オ ー プ ン さ れ 、 O_LARGEFILE が こ の フ ァ イ ル デ ィ ス ク リ プ タ ー に セ ッ ト さ れ る 。

fork (2) と execve (2) に 関 し て は 、 memfd_create () で 作 成 し た フ ァ イ ル デ ィ ス ク リ プ タ ー に つ い て も 通 常 の 動 作 が 適 用 さ れ る 。 フ ァ イ ル デ ィ ス ク リ プ タ ー の コ ピ ー は fork (2) で 生 成 さ れ る 子 プ ロ セ ス に 継 承 さ れ 、 同 じ フ ァ イ ル を 参 照 す る 。 close-on-exec フ ラ グ が セ ッ ト さ れ て い な い 限 り 、 execve (2) の 前 後 で フ ァ イ ル デ ィ ス ク リ プ タ ー は 保 持 さ れ る 。

返 り 値

成 功 の 場 合 、 memfd_create () は 新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 エ ラ ー の 場 合 、 -1 を 返 し 、 errno に エ ラ ー を 示 す 値 を 設 定 す る 。

エ ラ ー

EFAULT

name の ア ド レ ス が 無 効 な メ モ リ ー を 指 し て い る 。

EINVAL

flags included unknown bits.

EINVAL

name was too long. (The limit is 249 bytes, excluding the terminating null byte.)

EINVAL

Both MFD_HUGETLB and MFD_ALLOW_SEALING were specified in flags .

EMFILE

オ ー プ ン さ れ て い る フ ァ イ ル デ ィ ス ク リ プ タ ー 数 の プ ロ セ ス 単 位 の 上 限 に 達 し た 。

ENFILE

シ ス テ ム 全 体 で オ ー プ ン さ れ て い る フ ァ イ ル の 総 数 が 上 限 に 達 し た 。

ENOMEM

新 し い 無 名 フ ァ イ ル を 作 成 す る の に 十 分 な メ モ リ ー が な か っ た 。

バ ー ジ ョ ン

memfd_create () シ ス テ ム コ ー ル は Linux 3.17 で 登 場 し た 。 glibc で の サ ポ ー ト は glibc バ ー ジ ョ ン 2.27 で 追 加 さ れ た 。

準 拠

memfd_create () シ ス テ ム コ ー ル は Linux 固 有 で あ る 。

注 意

memfd_create () シ ス テ ム コ ー ル は 、 手 動 で tmpfs (5) フ ァ イ ル シ ス テ ム を マ ウ ン ト し て 、 そ の フ ァ イ ル シ ス テ ム に フ ァ イ ル を オ ー プ ン す る と い う 操 作 の 、 簡 単 な 代 替 手 段 を 提 供 し て い る 。 memfd_create () の 主 な 目 的 は 、 fcntl (2) が 提 供 す る file-sealing API で 使 用 で き る 、 フ ァ イ ル と そ れ に 関 連 付 け ら れ る フ ァ イ ル デ ィ ス ク リ プ タ ー を 作 成 す る こ と で あ る 。

memfd_create () シ ス テ ム コ ー ル は 、 file sealing な し で も 用 途 が あ る (こ れ が 明 示 的 に MFD_ALLOW_SEALING フ ラ グ が 要 求 さ れ な い 限 り 、 file-sealing が 無 効 に な る 理 由 で あ る )。 特 に 、 フ ァ イ ル シ ス テ ム に 実 際 に フ ァ イ ル を 残 す 意 図 が な い 場 合 、 tmp に フ ァ イ ル を 作 成 し た り open (2) O_TMPFILE を 使 っ た り す る 際 の 代 替 手 段 と し て 使 用 で き る 。

file sealing

file sealing が な い 場 合 、 共 有 メ モ リ ー 経 由 で 通 信 す る プ ロ セ ス は 、 互 い に 信 頼 す る か 、 信 頼 し て い な い 相 手 が 共 有 メ モ リ ー 領 域 を 問 題 が あ る 方 法 で 操 作 す る 可 能 性 に 対 処 す る た め の 対 策 を 講 じ な け れ ば な ら な い 。 例 え ば 、 信 頼 し て い な い 相 手 は 、 い つ で も 共 有 メ モ リ ー の 内 容 を 変 更 し た り 、 共 有 メ モ リ ー 領 域 を 縮 小 し た り す る 可 能 性 が あ る 。 前 者 の 場 合 は 、 ロ ー カ ル プ ロ セ ス で は 、 デ ー タ の 確 認 時 点 と 使 用 時 点 の 競 合 条 件 の 問 題 が 起 こ り 得 る (通 常 は こ の 問 題 へ の 対 処 は 共 有 メ モ リ ー 領 域 か ら デ ー タ を こ ぴ ー し て か ら デ ー タ を 確 認 、 使 用 す る こ と で あ る )。 後 者 の 場 合 は 、 ロ ー カ ル プ ロ セ ス で は 、 共 有 メ モ リ ー 領 域 の 存 在 し な く な っ た 場 所 に ア ク セ ス し よ う と し た 際 に シ グ ナ ル SIGBUS が 発 生 す る 可 能 性 が あ る (こ の 可 能 性 に 対 処 す る に は シ グ ナ ル SIGBUS に 対 し て ハ ン ド ラ ー を 使 用 す る 必 要 が あ る )。

信 頼 し て い な い 相 手 へ の 対 処 に よ り 、 共 有 メ モ リ ー を 利 用 す る コ ー ド に 余 計 な 複 雑 性 が 増 す こ と に な る 。 メ モ リ ー sealing に よ り 余 計 な 複 雑 性 を な く す こ と が で き る 。 相 手 が 望 ま な い 方 法 で 共 有 メ モ リ ー を 変 更 で き な い こ と を 知 っ て い る こ と で 、 プ ロ セ ス は 安 全 に 動 作 で き る よ う に な る 。

sealing 機 構 の 使 い 方 の 例 は 以 下 の と お り で あ る 。

1.

最 初 の プ ロ セ ス は memfd_create () を 使 っ て tmpfs (5) フ ァ イ ル を 作 成 す る 。 memfd_create () は こ れ 以 降 の ス テ ッ プ で 使 用 す る フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。

2.

最 初 の プ ロ セ ス は ftruncate (2) を 使 っ て 直 前 の ス テ ッ プ で 作 成 し た フ ァ イ ル の サ イ ズ を 変 更 し 、 mmap (2) を 使 っ て そ の フ ァ イ ル を マ ッ ピ ン グ し 、 共 有 メ モ リ ー に 所 望 の デ ー タ を 配 置 す る 。

3.

The first process uses the fcntl (2) F_ADD_SEALS operation to place one or more seals on the file, in order to restrict further modifications on the file. (If placing the seal F_SEAL_WRITE , then it will be necessary to first unmap the shared writable mapping created in the previous step. Otherwise, behavior similar to F_SEAL_WRITE can be achieved by using F_SEAL_FUTURE_WRITE , which will prevent future writes via mmap (2) and write (2) from succeeding while keeping existing shared writable mappings).

4.

二 つ 目 の プ ロ セ ス は tmpfs (5) フ ァ イ ル の フ ァ イ ル デ ィ ス ク リ プ タ ー を 入 手 し 、 そ の フ ァ イ ル を マ ッ プ す る 。 以 下 に 示 す 方 法 を 使 用 す る こ と が で き る 。

*

memfd_create () を 呼 び 出 し た プ ロ セ ス は 、 得 ら れ た フ ァ イ ル デ ィ ス ク リ プ タ ー を 二 つ 目 の プ ロ セ ス に UNIX ド メ イ ン ソ ケ ッ ト 経 由 で 渡 す こ と が で き る ( unix (7) と cmsg (3) を 参 照 )。 そ れ か ら 、 二 つ 目 の プ ロ セ ス は mmap (2) を 使 っ て フ ァ イ ル を マ ッ プ す る 。

*

二 つ 目 の プ ロ セ ス を fork (2) を 使 っ て 作 成 す る 。 そ う す る と 、 自 動 的 に フ ァ イ ル デ ィ ス ク リ プ タ ー と マ ッ ピ ン グ が 継 承 さ れ る 。 (こ の 方 法 と 次 の 方 法 で は 、 二 つ の プ ロ セ ス 間 で 自 然 な 信 頼 関 係 が 存 在 す る こ と に な る 。 な ぜ な ら 、 二 つ の プ ロ セ ス は 同 じ ユ ー ザ ー ID。 の 元 で 実 行 さ れ て い る か ら で あ る 。 し た が っ て 、 file sealing は 通 常 は 不 要 で あ ろ う 。 )

*

二 つ 目 の プ ロ セ ス は /proc/<pid>/fd/<fd> を オ ー プ ン す る 。 <pid> は 最 初 の プ ロ セ ス ( memfd_create () を 呼 び 出 し た プ ロ セ ス ) の PID で 、 <fd> は 最 初 の プ ロ セ ス で の memfd_create () の 呼 び 出 し で 返 さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー 番 号 で あ る 。 そ れ か ら こ の フ ァ イ ル を mmap (2) を 使 っ て マ ッ ピ ン グ す る 。

5.

二 つ 目 の プ ロ セ ス は fcntl (2) の F_GET_SEALS 操 作 を 使 っ て 、 そ の フ ァ イ ル に 適 用 さ れ て い る seal の ビ ッ ト マ ス ク を 取 得 す る 。 こ の ビ ッ ト マ ス ク を 調 べ て 、 フ ァ イ ル の 変 更 に 関 し て ど の よ う な 制 限 が 適 用 さ れ て い る か を 知 る こ と が で き る 。 ( F_SEAL_SEAL seal が そ れ ま で に 適 用 さ れ て い な い 限 り は ) 必 要 で あ れ ば 、 二 つ 目 の プ ロ セ ス は さ ら に seal を 設 定 し て 追 加 の 制 限 を か け る こ と が で き る 。

以 下 で は memfd_create () と file sealing API の 使 用 例 を 示 す サ ン プ ル プ ロ グ ラ ム を 2 つ と り あ げ る 。

最 初 の プ ロ グ ラ ム t_memfd_create.c は 、 memfd_create () を 使 っ て tmpfs (5) フ ァ イ ル を 作 成 し 、 そ の フ ァ イ ル の サ イ ズ を 設 定 し 、 メ モ リ ー に マ ッ ピ ン グ し 、 要 求 さ れ た 場 合 に は そ の フ ァ イ ル に seal を 設 定 す る 。 こ の プ ロ グ ラ ム は 最 大 で 3 つ の コ マ ン ド ラ イ ン 引 数 を 取 り 、 最 初 の 2 つ は 必 須 で あ る 。 最 初 の 引 数 は フ ァ イ ル に 関 連 付 け ら れ る 名 前 で 、 2 番 目 の 引 数 は フ ァ イ ル に 設 定 さ れ る サ イ ズ で あ る 。 省 略 可 能 な 3 番 目 の 引 数 は 、 こ の フ ァ イ ル に 設 定 す る seal を 指 定 す る 文 字 列 で あ る 。

2 つ め の プ ロ グ ラ ム t_get_seals.c を 使 う と 、 memfd_create () を 使 っ て 作 成 さ れ た 既 存 の フ ァ イ ル を オ ー プ ン し 、 そ の フ ァ イ ル に 適 用 さ れ て い る seal の 集 合 を 調 査 で き る 。

以 下 の シ ェ ル の セ ッ シ ョ ン は こ れ ら の プ ロ グ ラ ム の 使 用 例 を 示 し た も の で あ る 。 ま ず tmpfs (5) フ ァ イ ル を 作 成 し 、 そ の フ ァ イ ル に seal を い く つ か 設 定 し て い る 。

$ ./t_memfd_create my_memfd_file 4096 sw &
[1] 11775
PID: 11775; fd: 3; /proc/11775/fd/3

こ の 時 点 で は 、 t_memfd_create プ ロ グ ラ ム は バ ッ ク グ ラ ウ ン ド で 動 作 し 続 け る 。 も う 一 つ の プ ロ グ ラ ム か ら 、 memfd_create () が オ ー プ ン し た フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 応 す る /proc/[pid]/fd フ ァ イ ル を オ ー プ ン す る こ と で 、 memfd_create () で 作 成 さ れ た フ ァ イ ル の フ ァ イ ル デ ィ ス ク リ プ タ ー を 取 得 で き る 。 そ の パ ス 名 を 使 っ て 、 /proc/[pid]/fd シ ン ボ リ ッ ク リ ン ク の 内 容 を 調 査 し 、 t_get_seals プ ロ グ ラ ム を 使 っ て そ の フ ァ イ ル に 設 定 さ れ て い る seal を 見 る こ と が で き る 。

$ readlink /proc/11775/fd/3
/memfd:my_memfd_file (deleted)
$ ./t_get_seals /proc/11775/fd/3
Existing seals: WRITE SHRINK

プ ロ グ ラ ム の ソ ー ス : t_memfd_create.c

#define _GNU_SOURCE
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)

int
main(int argc, char *argv[])
{
int fd;
unsigned int seals;
char *addr;
char *name, *seals_arg;
ssize_t len;

if (argc < 3) {
fprintf(stderr, "%s name size [seals]\n", argv[0]);
fprintf(stderr, "\t'seals' can contain any of the "
"following characters:\n");
fprintf(stderr, "\t\tg - F_SEAL_GROW\n");
fprintf(stderr, "\t\ts - F_SEAL_SHRINK\n");
fprintf(stderr, "\t\tw - F_SEAL_WRITE\n");
fprintf(stderr, "\t\tW - F_SEAL_FUTURE_WRITE\n");
fprintf(stderr, "\t\tS - F_SEAL_SEAL\n");
exit(EXIT_FAILURE);
}

name = argv[1];
len = atoi(argv[2]);
seals_arg = argv[3];

/* Create an anonymous file in tmpfs; allow seals to be
placed on the file */

fd = memfd_create(name, MFD_ALLOW_SEALING);
if (fd == -1)
errExit("memfd_create");

/* Size the file as specified on the command line */

if (ftruncate(fd, len) == -1)
errExit("truncate");

printf("PID: %jd; fd: %d; /proc/%jd/fd/%d\n",
(intmax_t) getpid(), fd, (intmax_t) getpid(), fd);

/* Code to map the file and populate the mapping with data
omitted */

/* If a 'seals' command-line argument was supplied, set some
seals on the file */

if (seals_arg != NULL) {
seals = 0;

if (strchr(seals_arg, 'g') != NULL)
seals |= F_SEAL_GROW;
if (strchr(seals_arg, 's') != NULL)
seals |= F_SEAL_SHRINK;
if (strchr(seals_arg, 'w') != NULL)
seals |= F_SEAL_WRITE;
if (strchr(seals_arg, 'W') != NULL)
seals |= F_SEAL_FUTURE_WRITE;
if (strchr(seals_arg, 'S') != NULL)
seals |= F_SEAL_SEAL;

if (fcntl(fd, F_ADD_SEALS, seals) == -1)
errExit("fcntl");
}

/* Keep running, so that the file created by memfd_create()
continues to exist */

pause();

exit(EXIT_SUCCESS);
}

プ ロ グ ラ ム の ソ ー ス : t_get_seals.c

#define _GNU_SOURCE
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)

int
main(int argc, char *argv[])
{
int fd;
unsigned int seals;

if (argc != 2) {
fprintf(stderr, "%s /proc/PID/fd/FD\n", argv[0]);
exit(EXIT_FAILURE);
}

fd = open(argv[1], O_RDWR);
if (fd == -1)
errExit("open");

seals = fcntl(fd, F_GET_SEALS);
if (seals == -1)
errExit("fcntl");

printf("Existing seals:");
if (seals & F_SEAL_SEAL)
printf(" SEAL");
if (seals & F_SEAL_GROW)
printf(" GROW");
if (seals & F_SEAL_WRITE)
printf(" WRITE");
if (seals & F_SEAL_FUTURE_WRITE)
printf(" FUTURE_WRITE");
if (seals & F_SEAL_SHRINK)
printf(" SHRINK");
printf("\n");

/* Code to map the file and access the contents of the
resulting mapping omitted */

exit(EXIT_SUCCESS);
}

関 連 項 目

fcntl (2), ftruncate (2), mmap (2), shmget (2), shm_open (3)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。