// SPDX-License-Identifier: GPL-2.0-or-later1/*2* eCryptfs: Linux filesystem encryption layer3*4* Copyright (C) 2007 International Business Machines Corp.5* Author(s): Michael A. Halcrow <[email protected]>6*/78#include <linux/fs.h>9#include <linux/pagemap.h>10#include <linux/sched/signal.h>1112#include "ecryptfs_kernel.h"1314/**15* ecryptfs_write_lower16* @ecryptfs_inode: The eCryptfs inode17* @data: Data to write18* @offset: Byte offset in the lower file to which to write the data19* @size: Number of bytes from @data to write at @offset in the lower20* file21*22* Write data to the lower file.23*24* Returns bytes written on success; less than zero on error25*/26int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,27loff_t offset, size_t size)28{29struct file *lower_file;30ssize_t rc;3132lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file;33if (!lower_file)34return -EIO;35rc = kernel_write(lower_file, data, size, &offset);36mark_inode_dirty_sync(ecryptfs_inode);37return rc;38}3940/**41* ecryptfs_write_lower_page_segment42* @ecryptfs_inode: The eCryptfs inode43* @folio_for_lower: The folio containing the data to be written to the44* lower file45* @offset_in_page: The offset in the @folio_for_lower from which to46* start writing the data47* @size: The amount of data from @folio_for_lower to write to the48* lower file49*50* Determines the byte offset in the file for the given page and51* offset within the page, maps the page, and makes the call to write52* the contents of @folio_for_lower to the lower inode.53*54* Returns zero on success; non-zero otherwise55*/56int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,57struct folio *folio_for_lower,58size_t offset_in_page, size_t size)59{60char *virt;61loff_t offset;62int rc;6364offset = (loff_t)folio_for_lower->index * PAGE_SIZE + offset_in_page;65virt = kmap_local_folio(folio_for_lower, 0);66rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);67if (rc > 0)68rc = 0;69kunmap_local(virt);70return rc;71}7273/**74* ecryptfs_write75* @ecryptfs_inode: The eCryptfs file into which to write76* @data: Virtual address where data to write is located77* @offset: Offset in the eCryptfs file at which to begin writing the78* data from @data79* @size: The number of bytes to write from @data80*81* Write an arbitrary amount of data to an arbitrary location in the82* eCryptfs inode page cache. This is done on a page-by-page, and then83* by an extent-by-extent, basis; individual extents are encrypted and84* written to the lower page cache (via VFS writes). This function85* takes care of all the address translation to locations in the lower86* filesystem; it also handles truncate events, writing out zeros87* where necessary.88*89* Returns zero on success; non-zero otherwise90*/91int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,92size_t size)93{94struct ecryptfs_crypt_stat *crypt_stat;95char *ecryptfs_page_virt;96loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode);97loff_t data_offset = 0;98loff_t pos;99int rc = 0;100101crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;102/*103* if we are writing beyond current size, then start pos104* at the current size - we'll fill in zeros from there.105*/106if (offset > ecryptfs_file_size)107pos = ecryptfs_file_size;108else109pos = offset;110while (pos < (offset + size)) {111struct folio *ecryptfs_folio;112pgoff_t ecryptfs_page_idx = (pos >> PAGE_SHIFT);113size_t start_offset_in_page = (pos & ~PAGE_MASK);114size_t num_bytes = (PAGE_SIZE - start_offset_in_page);115loff_t total_remaining_bytes = ((offset + size) - pos);116117if (fatal_signal_pending(current)) {118rc = -EINTR;119break;120}121122if (num_bytes > total_remaining_bytes)123num_bytes = total_remaining_bytes;124if (pos < offset) {125/* remaining zeros to write, up to destination offset */126loff_t total_remaining_zeros = (offset - pos);127128if (num_bytes > total_remaining_zeros)129num_bytes = total_remaining_zeros;130}131ecryptfs_folio = read_mapping_folio(ecryptfs_inode->i_mapping,132ecryptfs_page_idx, NULL);133if (IS_ERR(ecryptfs_folio)) {134rc = PTR_ERR(ecryptfs_folio);135printk(KERN_ERR "%s: Error getting page at "136"index [%ld] from eCryptfs inode "137"mapping; rc = [%d]\n", __func__,138ecryptfs_page_idx, rc);139goto out;140}141folio_lock(ecryptfs_folio);142ecryptfs_page_virt = kmap_local_folio(ecryptfs_folio, 0);143144/*145* pos: where we're now writing, offset: where the request was146* If current pos is before request, we are filling zeros147* If we are at or beyond request, we are writing the *data*148* If we're in a fresh page beyond eof, zero it in either case149*/150if (pos < offset || !start_offset_in_page) {151/* We are extending past the previous end of the file.152* Fill in zero values to the end of the page */153memset(((char *)ecryptfs_page_virt154+ start_offset_in_page), 0,155PAGE_SIZE - start_offset_in_page);156}157158/* pos >= offset, we are now writing the data request */159if (pos >= offset) {160memcpy(((char *)ecryptfs_page_virt161+ start_offset_in_page),162(data + data_offset), num_bytes);163data_offset += num_bytes;164}165kunmap_local(ecryptfs_page_virt);166flush_dcache_folio(ecryptfs_folio);167folio_mark_uptodate(ecryptfs_folio);168folio_unlock(ecryptfs_folio);169if (crypt_stat->flags & ECRYPTFS_ENCRYPTED)170rc = ecryptfs_encrypt_page(ecryptfs_folio);171else172rc = ecryptfs_write_lower_page_segment(ecryptfs_inode,173ecryptfs_folio,174start_offset_in_page,175data_offset);176folio_put(ecryptfs_folio);177if (rc) {178printk(KERN_ERR "%s: Error encrypting "179"page; rc = [%d]\n", __func__, rc);180goto out;181}182pos += num_bytes;183}184if (pos > ecryptfs_file_size) {185i_size_write(ecryptfs_inode, pos);186if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {187int rc2;188189rc2 = ecryptfs_write_inode_size_to_metadata(190ecryptfs_inode);191if (rc2) {192printk(KERN_ERR "Problem with "193"ecryptfs_write_inode_size_to_metadata; "194"rc = [%d]\n", rc2);195if (!rc)196rc = rc2;197goto out;198}199}200}201out:202return rc;203}204205/**206* ecryptfs_read_lower207* @data: The read data is stored here by this function208* @offset: Byte offset in the lower file from which to read the data209* @size: Number of bytes to read from @offset of the lower file and210* store into @data211* @ecryptfs_inode: The eCryptfs inode212*213* Read @size bytes of data at byte offset @offset from the lower214* inode into memory location @data.215*216* Returns bytes read on success; 0 on EOF; less than zero on error217*/218int ecryptfs_read_lower(char *data, loff_t offset, size_t size,219struct inode *ecryptfs_inode)220{221struct file *lower_file;222lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file;223if (!lower_file)224return -EIO;225return kernel_read(lower_file, data, size, &offset);226}227228/**229* ecryptfs_read_lower_page_segment230* @folio_for_ecryptfs: The folio into which data for eCryptfs will be231* written232* @page_index: Page index in @page_for_ecryptfs from which to start233* writing234* @offset_in_page: Offset in @page_for_ecryptfs from which to start235* writing236* @size: The number of bytes to write into @page_for_ecryptfs237* @ecryptfs_inode: The eCryptfs inode238*239* Determines the byte offset in the file for the given page and240* offset within the page, maps the page, and makes the call to read241* the contents of @page_for_ecryptfs from the lower inode.242*243* Returns zero on success; non-zero otherwise244*/245int ecryptfs_read_lower_page_segment(struct folio *folio_for_ecryptfs,246pgoff_t page_index,247size_t offset_in_page, size_t size,248struct inode *ecryptfs_inode)249{250char *virt;251loff_t offset;252int rc;253254offset = (loff_t)page_index * PAGE_SIZE + offset_in_page;255virt = kmap_local_folio(folio_for_ecryptfs, 0);256rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);257if (rc > 0)258rc = 0;259kunmap_local(virt);260flush_dcache_folio(folio_for_ecryptfs);261return rc;262}263264265