fs/crypto/hooks.c
Source file repositories/reference/linux-study-clean/fs/crypto/hooks.c
File Facts
- System
- Linux kernel
- Corpus path
fs/crypto/hooks.c- Extension
.c- Size
- 15485 bytes
- Lines
- 474
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hfscrypt_private.h
Detected Declarations
function directoryfunction __fscrypt_prepare_linkfunction __fscrypt_prepare_renamefunction __fscrypt_prepare_lookupfunction fscrypt_prepare_lookup_partialfunction __fscrypt_prepare_readdirfunction __fscrypt_prepare_setattrfunction fscrypt_prepare_setflagsfunction fscrypt_prepare_symlinkfunction __fscrypt_encrypt_symlinkfunction fscrypt_get_symlinkfunction fscrypt_symlink_getattrexport fscrypt_file_openexport __fscrypt_prepare_linkexport __fscrypt_prepare_renameexport __fscrypt_prepare_lookupexport fscrypt_prepare_lookup_partialexport __fscrypt_prepare_readdirexport __fscrypt_prepare_setattrexport fscrypt_prepare_symlinkexport __fscrypt_encrypt_symlinkexport fscrypt_get_symlinkexport fscrypt_symlink_getattr
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* fs/crypto/hooks.c
*
* Encryption hooks for higher-level filesystem operations.
*/
#include <linux/export.h>
#include "fscrypt_private.h"
/**
* fscrypt_file_open() - prepare to open a possibly-encrypted regular file
* @inode: the inode being opened
* @filp: the struct file being set up
*
* Currently, an encrypted regular file can only be opened if its encryption key
* is available; access to the raw encrypted contents is not supported.
* Therefore, we first set up the inode's encryption key (if not already done)
* and return an error if it's unavailable.
*
* We also verify that if the parent directory (from the path via which the file
* is being opened) is encrypted, then the inode being opened uses the same
* encryption policy. This is needed as part of the enforcement that all files
* in an encrypted directory tree use the same encryption policy, as a
* protection against certain types of offline attacks. Note that this check is
* needed even when opening an *unencrypted* file, since it's forbidden to have
* an unencrypted file in an encrypted directory.
*
* Return: 0 on success, -ENOKEY if the key is missing, or another -errno code
*/
int fscrypt_file_open(struct inode *inode, struct file *filp)
{
int err;
struct dentry *dentry, *dentry_parent;
struct inode *inode_parent;
err = fscrypt_require_key(inode);
if (err)
return err;
dentry = file_dentry(filp);
/*
* Getting a reference to the parent dentry is needed for the actual
* encryption policy comparison, but it's expensive on multi-core
* systems. Since this function runs on unencrypted files too, start
* with a lightweight RCU-mode check for the parent directory being
* unencrypted (in which case it's fine for the child to be either
* unencrypted, or encrypted with any policy). Only continue on to the
* full policy check if the parent directory is actually encrypted.
*/
rcu_read_lock();
dentry_parent = READ_ONCE(dentry->d_parent);
inode_parent = d_inode_rcu(dentry_parent);
if (inode_parent != NULL && !IS_ENCRYPTED(inode_parent)) {
rcu_read_unlock();
return 0;
}
rcu_read_unlock();
dentry_parent = dget_parent(dentry);
if (!fscrypt_has_permitted_context(d_inode(dentry_parent), inode)) {
fscrypt_warn(inode,
"Inconsistent encryption context (parent directory: %llu)",
d_inode(dentry_parent)->i_ino);
err = -EPERM;
}
dput(dentry_parent);
return err;
}
EXPORT_SYMBOL_GPL(fscrypt_file_open);
int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
struct dentry *dentry)
{
if (fscrypt_is_nokey_name(dentry))
return -ENOKEY;
/*
* We don't need to separately check that the directory inode's key is
* available, as it's implied by the dentry not being a no-key name.
*/
if (!fscrypt_has_permitted_context(dir, inode))
return -EXDEV;
return 0;
}
EXPORT_SYMBOL_GPL(__fscrypt_prepare_link);
Annotation
- Immediate include surface: `linux/export.h`, `fscrypt_private.h`.
- Detected declarations: `function directory`, `function __fscrypt_prepare_link`, `function __fscrypt_prepare_rename`, `function __fscrypt_prepare_lookup`, `function fscrypt_prepare_lookup_partial`, `function __fscrypt_prepare_readdir`, `function __fscrypt_prepare_setattr`, `function fscrypt_prepare_setflags`, `function fscrypt_prepare_symlink`, `function __fscrypt_encrypt_symlink`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.