---
name: "F_GET_SEALS"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/F_GET_SEALS"
---

# F\_GET\_SEALS(2const)

get/add file seals

## NAME

F\_GET\_SEALS, F\_ADD\_SEALS - get/add file seals

## LIBRARY

Standard C library (*libc*, *-lc*)

## SYNOPSIS

```
#include <fcntl.h>
```

**int fcntl(int** *fd***, F\_ADD\_SEALS, int** *arg***);** **int fcntl(int** *fd***, F\_GET\_SEALS);**

## DESCRIPTION

File seals limit the set of allowed operations on a given file. For each seal that is set on a file, a specific set of operations will fail with **EPERM** on this file from now on. The file is said to be sealed. The default set of seals depends on the type of the underlying file and filesystem. For an overview of file sealing, a discussion of its purpose, and some code examples, see [**memfd\_create**(2)](/memfd_create/2.md).

Currently, file seals can be applied only to a file descriptor returned by [**memfd\_create**(2)](/memfd_create/2.md) (if the **MFD\_ALLOW\_SEALING** was employed). On other filesystems, all **fcntl**() operations that operate on seals will return **EINVAL**.

Seals are a property of an inode. Thus, all open file descriptors referring to the same inode share the same set of seals. Furthermore, seals can never be removed, only added.

- **F\_ADD\_SEALS**

  Add the seals given in the bit-mask argument *arg* to the set of seals of the inode referred to by the file descriptor *fd*. Seals cannot be removed again. Once this call succeeds, the seals are enforced by the kernel immediately. If the current set of seals includes **F\_SEAL\_SEAL** (see below), then this call will be rejected with **EPERM**. Adding a seal that is already set is a no-op, in case **F\_SEAL\_SEAL** is not set already. In order to place a seal, the file descriptor *fd* must be writable.

- **F\_GET\_SEALS**

  Return (as the function result) the current set of seals of the inode referred to by *fd*. If no seals are set, 0 is returned. If the file does not support sealing, -1 is returned and *errno* is set to **EINVAL**.

The following seals are available:

- **F\_SEAL\_SEAL**

  If this seal is set, any further call to **fcntl**() with **F\_ADD\_SEALS** fails with the error **EPERM**. Therefore, this seal prevents any modifications to the set of seals itself. If the initial set of seals of a file includes **F\_SEAL\_SEAL**, then this effectively causes the set of seals to be constant and locked.

- **F\_SEAL\_SHRINK**

  If this seal is set, the file in question cannot be reduced in size. This affects [**open**(2)](/open/2.md) with the **O\_TRUNC** flag as well as [**truncate**(2)](/truncate/2.md) and [**ftruncate**(2)](/ftruncate/2.md). Those calls fail with **EPERM** if you try to shrink the file in question. Increasing the file size is still possible.

- **F\_SEAL\_GROW**

  If this seal is set, the size of the file in question cannot be increased. This affects [**write**(2)](/write/2.md) beyond the end of the file, [**truncate**(2)](/truncate/2.md), [**ftruncate**(2)](/ftruncate/2.md), and [**fallocate**(2)](/fallocate/2.md). These calls fail with **EPERM** if you use them to increase the file size. If you keep the size or shrink it, those calls still work as expected.

- **F\_SEAL\_WRITE**

  If this seal is set, you cannot modify the contents of the file. Note that shrinking or growing the size of the file is still possible and allowed. Thus, this seal is normally used in combination with one of the other seals. This seal affects [**write**(2)](/write/2.md) and [**fallocate**(2)](/fallocate/2.md) (only in combination with the **FALLOC\_FL\_PUNCH\_HOLE** flag). Those calls fail with **EPERM** if this seal is set. Furthermore, trying to create new shared, writable memory-mappings via [**mmap**(2)](/mmap/2.md) will also fail with **EPERM**.

-

  Using the **F\_ADD\_SEALS** operation to set the **F\_SEAL\_WRITE** seal fails with **EBUSY** if any writable, shared mapping exists. Such mappings must be unmapped before you can add this seal. Furthermore, if there are any asynchronous I/O operations ([**io\_submit**(2)](/io_submit/2.md)) pending on the file, all outstanding writes will be discarded.

- **F\_SEAL\_FUTURE\_WRITE** (since Linux 5.1)

  The effect of this seal is similar to **F\_SEAL\_WRITE**, but the contents of the file can still be modified via shared writable mappings that were created prior to the seal being set. Any attempt to create a new writable mapping on the file via [**mmap**(2)](/mmap/2.md) will fail with **EPERM**. Likewise, an attempt to write to the file via [**write**(2)](/write/2.md) will fail with **EPERM**.

-

  Using this seal, one process can create a memory buffer that it can continue to modify while sharing that buffer on a "read-only" basis with other processes.

- **F\_SEAL\_EXEC** (since Linux 6.3)

  If this seal is set, the execute mode bits of the file cannot be modified. Attempting to change the execute mode bits via [**fchmod**(2)](/fchmod/2.md) or similar will fail with **EPERM**. This results in a memfd that is either permanently executable or permanently not executable.

-

  Adding this seal implicitly adds **F\_SEAL\_GROW**, **F\_SEAL\_SHRINK**, **F\_SEAL\_WRITE**, and **F\_SEAL\_FUTURE\_WRITE**. This ensures that the executable code is not writeable. All the pre-requisites to add the implied seals must be met to successfully add **F\_SEAL\_EXEC**.

## RETURN VALUE

- **F\_GET\_SEALS**

  A bit mask identifying the seals that have been set for the inode referred to by *fd*.

- **F\_ADD\_SEALS**

  Zero.

On error, -1 is returned, and *errno* is set to indicate the error.

## ERRORS

See [**fcntl**(2)](/fcntl/2.md).

- **EBUSY**

  *op* is **F\_ADD\_SEALS**, *arg* includes **F\_SEAL\_WRITE**, and there exists a writable, shared mapping on the file referred to by *fd*.

- **EINVAL**

  *op* is **F\_ADD\_SEALS** and *arg* includes an unrecognized sealing bit.

- **EINVAL**

  The filesystem containing the inode referred to by *fd* does not support sealing.

- **EPERM**

  *op* was **F\_ADD\_SEALS**, but *fd* was not open for writing or the current set of seals on the file already includes **F\_SEAL\_SEAL**.

## STANDARDS

Linux.

## HISTORY

Linux 3.17.

## SEE ALSO

[**fcntl**(2)](/fcntl/2.md)
