2006-10-11 15:20:50 +07:00
|
|
|
/*
|
2006-10-11 15:20:53 +07:00
|
|
|
* linux/fs/ext4/symlink.c
|
2006-10-11 15:20:50 +07:00
|
|
|
*
|
|
|
|
* Only fast symlinks left here - the rest is done by generic code. AV, 1999
|
|
|
|
*
|
|
|
|
* Copyright (C) 1992, 1993, 1994, 1995
|
|
|
|
* Remy Card (card@masi.ibp.fr)
|
|
|
|
* Laboratoire MASI - Institut Blaise Pascal
|
|
|
|
* Universite Pierre et Marie Curie (Paris VI)
|
|
|
|
*
|
|
|
|
* from
|
|
|
|
*
|
|
|
|
* linux/fs/minix/symlink.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
|
*
|
2006-10-11 15:20:53 +07:00
|
|
|
* ext4 symlink handling code
|
2006-10-11 15:20:50 +07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <linux/namei.h>
|
2008-04-30 05:13:32 +07:00
|
|
|
#include "ext4.h"
|
2006-10-11 15:20:50 +07:00
|
|
|
#include "xattr.h"
|
|
|
|
|
2015-04-16 12:55:00 +07:00
|
|
|
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last
merge window. Also fix a number of long-standing xfstest failures.
(Quota writes failing due to ENOSPC, a race between truncate and
writepage in data=journalled mode that was causing generic/068 to
fail, and other corner cases.)
Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
performance eliminating locking when a buffer is modified more than
once during a transaction (which is very common for allocation
bitmaps, for example), in which case the state of the journalled
buffer head doesn't need to change.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQEcBAABCAAGBQJVi3PeAAoJEPL5WVaVDYGj+I0H/jRPexvyvnGfxiqs1sxIlbSk
cwewFJSsuKsy/pGYdmHvozWZyWGGORc89NrxoNwdbG+axvHbgUWt/3+vF+rzmaek
vX4v9QvCEo4PfpRgzbnYJFhbxGMJtwci887sq1o/UoNXikFYT2kz8rpdf0++eO5W
/GJNRA5ZUY0L0eeloUILAMrBr7KjtkI2oXwOZt5q68jh7B3n3XdNQXyEiQS/28aK
QYcFrqA/e2Fiuk6l5OSGBCP38mySu+x0nBTLT5LFwwrUBnoZvGtdjM6Sj/yADDDn
uP/Zpq56aLzkFRwwItrDaF26BIf2MhIH/WUYs65CraEGxjMaiPuzAudGA/iUVL8=
=1BdR
-----END PGP SIGNATURE-----
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
"A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last
merge window. Also fix a number of long-standing xfstest failures.
(Quota writes failing due to ENOSPC, a race between truncate and
writepage in data=journalled mode that was causing generic/068 to
fail, and other corner cases.)
Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
performance eliminating locking when a buffer is modified more than
once during a transaction (which is very common for allocation
bitmaps, for example), in which case the state of the journalled
buffer head doesn't need to change"
[ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in
the merge resolution, to make it clear that that function is _only_
used for encrypted symlinks. The function doesn't actually work for
non-encrypted symlinks at all, and they use the generic helpers
- Linus ]
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits)
ext4: set lazytime on remount if MS_LAZYTIME is set by mount
ext4: only call ext4_truncate when size <= isize
ext4: make online defrag error reporting consistent
ext4: minor cleanup of ext4_da_reserve_space()
ext4: don't retry file block mapping on bigalloc fs with non-extent file
ext4: prevent ext4_quota_write() from failing due to ENOSPC
ext4: call sync_blockdev() before invalidate_bdev() in put_super()
jbd2: speedup jbd2_journal_dirty_metadata()
jbd2: get rid of open coded allocation retry loop
ext4: improve warning directory handling messages
jbd2: fix ocfs2 corrupt when updating journal superblock fails
ext4: mballoc: avoid 20-argument function call
ext4: wait for existing dio workers in ext4_alloc_file_blocks()
ext4: recalculate journal credits as inode depth changes
jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail()
ext4: use swap() in mext_page_double_lock()
ext4: use swap() in memswap()
ext4: fix race between truncate and __ext4_journalled_writepage()
ext4 crypto: fail the mount if blocksize != pagesize
ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate
...
2015-06-26 04:06:55 +07:00
|
|
|
static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cookie)
|
2015-04-16 12:55:00 +07:00
|
|
|
{
|
|
|
|
struct page *cpage = NULL;
|
|
|
|
char *caddr, *paddr = NULL;
|
|
|
|
struct ext4_str cstr, pstr;
|
2015-04-27 05:48:49 +07:00
|
|
|
struct inode *inode = d_inode(dentry);
|
2015-04-16 12:55:00 +07:00
|
|
|
struct ext4_encrypted_symlink_data *sd;
|
|
|
|
loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
|
|
|
|
int res;
|
|
|
|
u32 plen, max_size = inode->i_sb->s_blocksize;
|
|
|
|
|
2015-06-01 00:34:22 +07:00
|
|
|
res = ext4_get_encryption_info(inode);
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-19 00:17:47 +07:00
|
|
|
if (res)
|
|
|
|
return ERR_PTR(res);
|
2015-04-16 12:55:00 +07:00
|
|
|
|
|
|
|
if (ext4_inode_is_fast_symlink(inode)) {
|
2015-04-27 05:48:49 +07:00
|
|
|
caddr = (char *) EXT4_I(inode)->i_data;
|
|
|
|
max_size = sizeof(EXT4_I(inode)->i_data);
|
2015-04-16 12:55:00 +07:00
|
|
|
} else {
|
|
|
|
cpage = read_mapping_page(inode->i_mapping, 0, NULL);
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-19 00:17:47 +07:00
|
|
|
if (IS_ERR(cpage))
|
2015-05-03 00:32:22 +07:00
|
|
|
return ERR_CAST(cpage);
|
2015-04-16 12:55:00 +07:00
|
|
|
caddr = kmap(cpage);
|
|
|
|
caddr[size] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Symlink is encrypted */
|
|
|
|
sd = (struct ext4_encrypted_symlink_data *)caddr;
|
|
|
|
cstr.name = sd->encrypted_path;
|
|
|
|
cstr.len = le32_to_cpu(sd->len);
|
|
|
|
if ((cstr.len +
|
|
|
|
sizeof(struct ext4_encrypted_symlink_data) - 1) >
|
|
|
|
max_size) {
|
|
|
|
/* Symlink data on the disk is corrupted */
|
|
|
|
res = -EIO;
|
|
|
|
goto errout;
|
|
|
|
}
|
|
|
|
plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ?
|
|
|
|
EXT4_FNAME_CRYPTO_DIGEST_SIZE*2 : cstr.len;
|
|
|
|
paddr = kmalloc(plen + 1, GFP_NOFS);
|
|
|
|
if (!paddr) {
|
|
|
|
res = -ENOMEM;
|
|
|
|
goto errout;
|
|
|
|
}
|
|
|
|
pstr.name = paddr;
|
2015-05-19 00:15:47 +07:00
|
|
|
pstr.len = plen;
|
ext4 crypto: reorganize how we store keys in the inode
This is a pretty massive patch which does a number of different things:
1) The per-inode encryption information is now stored in an allocated
data structure, ext4_crypt_info, instead of directly in the node.
This reduces the size usage of an in-memory inode when it is not
using encryption.
2) We drop the ext4_fname_crypto_ctx entirely, and use the per-inode
encryption structure instead. This remove an unnecessary memory
allocation and free for the fname_crypto_ctx as well as allowing us
to reuse the ctfm in a directory for multiple lookups and file
creations.
3) We also cache the inode's policy information in the ext4_crypt_info
structure so we don't have to continually read it out of the
extended attributes.
4) We now keep the keyring key in the inode's encryption structure
instead of releasing it after we are done using it to derive the
per-inode key. This allows us to test to see if the key has been
revoked; if it has, we prevent the use of the derived key and free
it.
5) When an inode is released (or when the derived key is freed), we
will use memset_explicit() to zero out the derived key, so it's not
left hanging around in memory. This implies that when a user logs
out, it is important to first revoke the key, and then unlink it,
and then finally, to use "echo 3 > /proc/sys/vm/drop_caches" to
release any decrypted pages and dcache entries from the system
caches.
6) All this, and we also shrink the number of lines of code by around
100. :-)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2015-05-19 00:17:47 +07:00
|
|
|
res = _ext4_fname_disk_to_usr(inode, NULL, &cstr, &pstr);
|
2015-04-16 12:55:00 +07:00
|
|
|
if (res < 0)
|
|
|
|
goto errout;
|
|
|
|
/* Null-terminate the name */
|
|
|
|
if (res <= plen)
|
|
|
|
paddr[res] = '\0';
|
|
|
|
if (cpage) {
|
|
|
|
kunmap(cpage);
|
|
|
|
page_cache_release(cpage);
|
|
|
|
}
|
2015-05-03 00:32:22 +07:00
|
|
|
return *cookie = paddr;
|
2015-04-16 12:55:00 +07:00
|
|
|
errout:
|
|
|
|
if (cpage) {
|
|
|
|
kunmap(cpage);
|
|
|
|
page_cache_release(cpage);
|
|
|
|
}
|
|
|
|
kfree(paddr);
|
|
|
|
return ERR_PTR(res);
|
|
|
|
}
|
|
|
|
|
2015-04-28 04:51:30 +07:00
|
|
|
const struct inode_operations ext4_encrypted_symlink_inode_operations = {
|
|
|
|
.readlink = generic_readlink,
|
A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last
merge window. Also fix a number of long-standing xfstest failures.
(Quota writes failing due to ENOSPC, a race between truncate and
writepage in data=journalled mode that was causing generic/068 to
fail, and other corner cases.)
Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
performance eliminating locking when a buffer is modified more than
once during a transaction (which is very common for allocation
bitmaps, for example), in which case the state of the journalled
buffer head doesn't need to change.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQEcBAABCAAGBQJVi3PeAAoJEPL5WVaVDYGj+I0H/jRPexvyvnGfxiqs1sxIlbSk
cwewFJSsuKsy/pGYdmHvozWZyWGGORc89NrxoNwdbG+axvHbgUWt/3+vF+rzmaek
vX4v9QvCEo4PfpRgzbnYJFhbxGMJtwci887sq1o/UoNXikFYT2kz8rpdf0++eO5W
/GJNRA5ZUY0L0eeloUILAMrBr7KjtkI2oXwOZt5q68jh7B3n3XdNQXyEiQS/28aK
QYcFrqA/e2Fiuk6l5OSGBCP38mySu+x0nBTLT5LFwwrUBnoZvGtdjM6Sj/yADDDn
uP/Zpq56aLzkFRwwItrDaF26BIf2MhIH/WUYs65CraEGxjMaiPuzAudGA/iUVL8=
=1BdR
-----END PGP SIGNATURE-----
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
"A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last
merge window. Also fix a number of long-standing xfstest failures.
(Quota writes failing due to ENOSPC, a race between truncate and
writepage in data=journalled mode that was causing generic/068 to
fail, and other corner cases.)
Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
performance eliminating locking when a buffer is modified more than
once during a transaction (which is very common for allocation
bitmaps, for example), in which case the state of the journalled
buffer head doesn't need to change"
[ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in
the merge resolution, to make it clear that that function is _only_
used for encrypted symlinks. The function doesn't actually work for
non-encrypted symlinks at all, and they use the generic helpers
- Linus ]
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits)
ext4: set lazytime on remount if MS_LAZYTIME is set by mount
ext4: only call ext4_truncate when size <= isize
ext4: make online defrag error reporting consistent
ext4: minor cleanup of ext4_da_reserve_space()
ext4: don't retry file block mapping on bigalloc fs with non-extent file
ext4: prevent ext4_quota_write() from failing due to ENOSPC
ext4: call sync_blockdev() before invalidate_bdev() in put_super()
jbd2: speedup jbd2_journal_dirty_metadata()
jbd2: get rid of open coded allocation retry loop
ext4: improve warning directory handling messages
jbd2: fix ocfs2 corrupt when updating journal superblock fails
ext4: mballoc: avoid 20-argument function call
ext4: wait for existing dio workers in ext4_alloc_file_blocks()
ext4: recalculate journal credits as inode depth changes
jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail()
ext4: use swap() in mext_page_double_lock()
ext4: use swap() in memswap()
ext4: fix race between truncate and __ext4_journalled_writepage()
ext4 crypto: fail the mount if blocksize != pagesize
ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate
...
2015-06-26 04:06:55 +07:00
|
|
|
.follow_link = ext4_encrypted_follow_link,
|
2015-04-28 04:51:30 +07:00
|
|
|
.put_link = kfree_put_link,
|
|
|
|
.setattr = ext4_setattr,
|
|
|
|
.setxattr = generic_setxattr,
|
|
|
|
.getxattr = generic_getxattr,
|
|
|
|
.listxattr = ext4_listxattr,
|
|
|
|
.removexattr = generic_removexattr,
|
|
|
|
};
|
2015-04-16 12:55:00 +07:00
|
|
|
#endif
|
|
|
|
|
2007-02-12 15:55:38 +07:00
|
|
|
const struct inode_operations ext4_symlink_inode_operations = {
|
2006-10-11 15:20:50 +07:00
|
|
|
.readlink = generic_readlink,
|
|
|
|
.follow_link = page_follow_link_light,
|
|
|
|
.put_link = page_put_link,
|
2010-05-16 13:00:00 +07:00
|
|
|
.setattr = ext4_setattr,
|
2006-10-11 15:20:50 +07:00
|
|
|
.setxattr = generic_setxattr,
|
|
|
|
.getxattr = generic_getxattr,
|
2006-10-11 15:20:53 +07:00
|
|
|
.listxattr = ext4_listxattr,
|
2006-10-11 15:20:50 +07:00
|
|
|
.removexattr = generic_removexattr,
|
|
|
|
};
|
|
|
|
|
2007-02-12 15:55:38 +07:00
|
|
|
const struct inode_operations ext4_fast_symlink_inode_operations = {
|
2006-10-11 15:20:50 +07:00
|
|
|
.readlink = generic_readlink,
|
2015-05-02 21:13:58 +07:00
|
|
|
.follow_link = simple_follow_link,
|
2010-05-16 13:00:00 +07:00
|
|
|
.setattr = ext4_setattr,
|
2006-10-11 15:20:50 +07:00
|
|
|
.setxattr = generic_setxattr,
|
|
|
|
.getxattr = generic_getxattr,
|
2006-10-11 15:20:53 +07:00
|
|
|
.listxattr = ext4_listxattr,
|
2006-10-11 15:20:50 +07:00
|
|
|
.removexattr = generic_removexattr,
|
|
|
|
};
|