From 040bf9a717885d3646dcd5b4062dc3a4877ec421 Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Wed, 3 Apr 2024 19:33:52 +0100 Subject: Squashfs: remove deprecated strncpy by not copying the string Squashfs copied the passed string (name) into a temporary buffer to ensure it was NUL-terminated. This however is completely unnecessary as the string is already NUL-terminated. So remove the deprecated strncpy() by completely removing the string copy. The background behind this unnecessary string copy is that it dates back to the days when Squashfs was an out of kernel patch. The code deliberately did not assume the string was NUL-terminated in case in future this changed (due to kernel changes). This would mean the out of tree patches would be broken but still compile OK. Link: https://lkml.kernel.org/r/20240403183352.391308-1-phillip@squashfs.org.uk Signed-off-by: Phillip Lougher Reviewed-by: Kees Cook Reviewed-by: Justin Stitt Signed-off-by: Andrew Morton --- fs/squashfs/namei.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c index 11e4539b9eae..65aae7e2a859 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c @@ -62,27 +62,21 @@ */ static int get_dir_index_using_name(struct super_block *sb, u64 *next_block, int *next_offset, u64 index_start, - int index_offset, int i_count, const char *name, - int len) + int index_offset, int i_count, const char *name) { struct squashfs_sb_info *msblk = sb->s_fs_info; int i, length = 0, err; unsigned int size; struct squashfs_dir_index *index; - char *str; TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); - index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN * 2 + 2, GFP_KERNEL); + index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); if (index == NULL) { ERROR("Failed to allocate squashfs_dir_index\n"); goto out; } - str = &index->name[SQUASHFS_NAME_LEN + 1]; - strncpy(str, name, len); - str[len] = '\0'; - for (i = 0; i < i_count; i++) { err = squashfs_read_metadata(sb, index, &index_start, &index_offset, sizeof(*index)); @@ -101,7 +95,7 @@ static int get_dir_index_using_name(struct super_block *sb, index->name[size] = '\0'; - if (strcmp(index->name, str) > 0) + if (strcmp(index->name, name) > 0) break; length = le32_to_cpu(index->index); @@ -153,7 +147,7 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, length = get_dir_index_using_name(dir->i_sb, &block, &offset, squashfs_i(dir)->dir_idx_start, squashfs_i(dir)->dir_idx_offset, - squashfs_i(dir)->dir_idx_cnt, name, len); + squashfs_i(dir)->dir_idx_cnt, name); while (length < i_size_read(dir)) { /* -- cgit v1.2.3 From 675f02e5e65651553c945a464e4f7630859f2032 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Sat, 20 Apr 2024 03:50:17 +0100 Subject: squashfs: convert squashfs_symlink_read_folio to use folio APIs Remove use of page APIs, return the errno instead of 0, switch from kmap_atomic to kmap_local and use folio_end_read() to unify the two exit paths. Link: https://lkml.kernel.org/r/20240420025029.2166544-23-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) Tested-by: Phillip Lougher Reviewed-by: Phillip Lougher Signed-off-by: Andrew Morton --- fs/squashfs/symlink.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index 2bf977a52c2c..6ef735bd841a 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c @@ -32,20 +32,19 @@ static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - struct inode *inode = page->mapping->host; + struct inode *inode = folio->mapping->host; struct super_block *sb = inode->i_sb; struct squashfs_sb_info *msblk = sb->s_fs_info; - int index = page->index << PAGE_SHIFT; + int index = folio_pos(folio); u64 block = squashfs_i(inode)->start; int offset = squashfs_i(inode)->offset; int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE); - int bytes, copied; + int bytes, copied, error; void *pageaddr; struct squashfs_cache_entry *entry; TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " - "%llx, offset %x\n", page->index, block, offset); + "%llx, offset %x\n", folio->index, block, offset); /* * Skip index bytes into symlink metadata. @@ -57,14 +56,15 @@ static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) ERROR("Unable to read symlink [%llx:%x]\n", squashfs_i(inode)->start, squashfs_i(inode)->offset); - goto error_out; + error = bytes; + goto out; } } /* * Read length bytes from symlink metadata. Squashfs_read_metadata * is not used here because it can sleep and we want to use - * kmap_atomic to map the page. Instead call the underlying + * kmap_local to map the folio. Instead call the underlying * squashfs_cache_get routine. As length bytes may overlap metadata * blocks, we may need to call squashfs_cache_get multiple times. */ @@ -75,29 +75,26 @@ static int squashfs_symlink_read_folio(struct file *file, struct folio *folio) squashfs_i(inode)->start, squashfs_i(inode)->offset); squashfs_cache_put(entry); - goto error_out; + error = entry->error; + goto out; } - pageaddr = kmap_atomic(page); + pageaddr = kmap_local_folio(folio, 0); copied = squashfs_copy_data(pageaddr + bytes, entry, offset, length - bytes); if (copied == length - bytes) memset(pageaddr + length, 0, PAGE_SIZE - length); else block = entry->next_index; - kunmap_atomic(pageaddr); + kunmap_local(pageaddr); squashfs_cache_put(entry); } - flush_dcache_page(page); - SetPageUptodate(page); - unlock_page(page); - return 0; - -error_out: - SetPageError(page); - unlock_page(page); - return 0; + flush_dcache_folio(folio); + error = 0; +out: + folio_end_read(folio, error == 0); + return error; } -- cgit v1.2.3 From bbf45b7e68555569489ab2428dd9c23960cdc9bf Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Sat, 20 Apr 2024 03:50:18 +0100 Subject: squashfs: remove calls to set the folio error flag Nobody checks the error flag on squashfs folios, so stop setting it. Link: https://lkml.kernel.org/r/20240420025029.2166544-24-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) Tested-by: Phillip Lougher Reviewed-by: Phillip Lougher Signed-off-by: Andrew Morton --- fs/squashfs/file.c | 6 +----- fs/squashfs/file_direct.c | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c index e8df6430444b..a8c1e7f9a609 100644 --- a/fs/squashfs/file.c +++ b/fs/squashfs/file.c @@ -375,8 +375,6 @@ void squashfs_fill_page(struct page *page, struct squashfs_cache_entry *buffer, flush_dcache_page(page); if (copied == avail) SetPageUptodate(page); - else - SetPageError(page); } /* Copy data into page cache */ @@ -471,7 +469,7 @@ static int squashfs_read_folio(struct file *file, struct folio *folio) res = read_blocklist(inode, index, &block); if (res < 0) - goto error_out; + goto out; if (res == 0) res = squashfs_readpage_sparse(page, expected); @@ -483,8 +481,6 @@ static int squashfs_read_folio(struct file *file, struct folio *folio) if (!res) return 0; -error_out: - SetPageError(page); out: pageaddr = kmap_atomic(page); memset(pageaddr, 0, PAGE_SIZE); diff --git a/fs/squashfs/file_direct.c b/fs/squashfs/file_direct.c index 763a3f7a75f6..2a689ce71de9 100644 --- a/fs/squashfs/file_direct.c +++ b/fs/squashfs/file_direct.c @@ -106,14 +106,13 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize, return 0; mark_errored: - /* Decompression failed, mark pages as errored. Target_page is + /* Decompression failed. Target_page is * dealt with by the caller */ for (i = 0; i < pages; i++) { if (page[i] == NULL || page[i] == target_page) continue; flush_dcache_page(page[i]); - SetPageError(page[i]); unlock_page(page[i]); put_page(page[i]); } -- cgit v1.2.3