2016-12-16 13:02:56 +03:00
/*
* Copyright ( C ) 2011 Novell Inc .
* Copyright ( C ) 2016 Red Hat , Inc .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation .
*/
# include <linux/fs.h>
2017-02-02 19:54:15 +03:00
# include <linux/cred.h>
2017-11-01 11:13:51 +03:00
# include <linux/ctype.h>
2016-12-16 13:02:56 +03:00
# include <linux/namei.h>
# include <linux/xattr.h>
2016-12-16 13:02:56 +03:00
# include <linux/ratelimit.h>
2017-04-30 14:46:31 +03:00
# include <linux/mount.h>
# include <linux/exportfs.h>
2016-12-16 13:02:56 +03:00
# include "overlayfs.h"
2016-12-16 13:02:56 +03:00
struct ovl_lookup_data {
struct qstr name ;
bool is_dir ;
bool opaque ;
bool stop ;
bool last ;
2016-12-16 13:02:56 +03:00
char * redirect ;
2016-12-16 13:02:56 +03:00
} ;
2016-12-16 13:02:56 +03:00
2016-12-16 13:02:56 +03:00
static int ovl_check_redirect ( struct dentry * dentry , struct ovl_lookup_data * d ,
size_t prelen , const char * post )
{
int res ;
char * s , * next , * buf = NULL ;
res = vfs_getxattr ( dentry , OVL_XATTR_REDIRECT , NULL , 0 ) ;
if ( res < 0 ) {
if ( res = = - ENODATA | | res = = - EOPNOTSUPP )
return 0 ;
goto fail ;
}
2017-09-14 02:28:29 +03:00
buf = kzalloc ( prelen + res + strlen ( post ) + 1 , GFP_KERNEL ) ;
2016-12-16 13:02:56 +03:00
if ( ! buf )
return - ENOMEM ;
if ( res = = 0 )
goto invalid ;
res = vfs_getxattr ( dentry , OVL_XATTR_REDIRECT , buf , res ) ;
if ( res < 0 )
goto fail ;
if ( res = = 0 )
goto invalid ;
if ( buf [ 0 ] = = ' / ' ) {
for ( s = buf ; * s + + = = ' / ' ; s = next ) {
next = strchrnul ( s , ' / ' ) ;
if ( s = = next )
goto invalid ;
}
} else {
if ( strchr ( buf , ' / ' ) ! = NULL )
goto invalid ;
memmove ( buf + prelen , buf , res ) ;
memcpy ( buf , d - > name . name , prelen ) ;
}
strcat ( buf , post ) ;
kfree ( d - > redirect ) ;
d - > redirect = buf ;
d - > name . name = d - > redirect ;
d - > name . len = strlen ( d - > redirect ) ;
return 0 ;
err_free :
kfree ( buf ) ;
return 0 ;
fail :
pr_warn_ratelimited ( " overlayfs: failed to get redirect (%i) \n " , res ) ;
goto err_free ;
invalid :
pr_warn_ratelimited ( " overlayfs: invalid redirect (%s) \n " , buf ) ;
goto err_free ;
}
2017-04-30 14:46:31 +03:00
static int ovl_acceptable ( void * ctx , struct dentry * dentry )
{
2018-01-11 12:33:24 +03:00
/*
* A non - dir origin may be disconnected , which is fine , because
* we only need it for its unique inode number .
*/
if ( ! d_is_dir ( dentry ) )
return 1 ;
/* Don't decode a deleted empty directory */
if ( d_unhashed ( dentry ) )
return 0 ;
/* Check if directory belongs to the layer we are decoding from */
return is_subdir ( dentry , ( ( struct vfsmount * ) ctx ) - > mnt_root ) ;
2017-04-30 14:46:31 +03:00
}
2017-10-24 15:12:15 +03:00
/*
* Check validity of an overlay file handle buffer .
*
* Return 0 for a valid file handle .
* Return - ENODATA for " origin unknown " .
* Return < 0 for an invalid file handle .
*/
2018-01-19 02:03:23 +03:00
int ovl_check_fh_len ( struct ovl_fh * fh , int fh_len )
2017-10-24 15:12:15 +03:00
{
if ( fh_len < sizeof ( struct ovl_fh ) | | fh_len < fh - > len )
return - EINVAL ;
if ( fh - > magic ! = OVL_FH_MAGIC )
return - EINVAL ;
/* Treat larger version and unknown flags as "origin unknown" */
if ( fh - > version > OVL_FH_VERSION | | fh - > flags & ~ OVL_FH_FLAG_ALL )
return - ENODATA ;
/* Treat endianness mismatch as "origin unknown" */
if ( ! ( fh - > flags & OVL_FH_FLAG_ANY_ENDIAN ) & &
( fh - > flags & OVL_FH_FLAG_BIG_ENDIAN ) ! = OVL_FH_FLAG_CPU_ENDIAN )
return - ENODATA ;
return 0 ;
}
2018-01-11 09:25:32 +03:00
static struct ovl_fh * ovl_get_fh ( struct dentry * dentry , const char * name )
2017-04-30 14:46:31 +03:00
{
2017-10-24 15:12:15 +03:00
int res , err ;
2017-04-30 14:46:31 +03:00
struct ovl_fh * fh = NULL ;
2018-01-11 09:25:32 +03:00
res = vfs_getxattr ( dentry , name , NULL , 0 ) ;
2017-04-30 14:46:31 +03:00
if ( res < 0 ) {
if ( res = = - ENODATA | | res = = - EOPNOTSUPP )
return NULL ;
goto fail ;
}
/* Zero size value means "copied up but origin unknown" */
if ( res = = 0 )
return NULL ;
2017-10-24 15:12:15 +03:00
fh = kzalloc ( res , GFP_KERNEL ) ;
2017-04-30 14:46:31 +03:00
if ( ! fh )
return ERR_PTR ( - ENOMEM ) ;
2018-01-11 09:25:32 +03:00
res = vfs_getxattr ( dentry , name , fh , res ) ;
2017-04-30 14:46:31 +03:00
if ( res < 0 )
goto fail ;
2017-10-24 15:12:15 +03:00
err = ovl_check_fh_len ( fh , res ) ;
if ( err < 0 ) {
if ( err = = - ENODATA )
goto out ;
2017-04-30 14:46:31 +03:00
goto invalid ;
2017-10-24 15:12:15 +03:00
}
2017-04-30 14:46:31 +03:00
2017-06-21 15:28:37 +03:00
return fh ;
out :
kfree ( fh ) ;
return NULL ;
fail :
pr_warn_ratelimited ( " overlayfs: failed to get origin (%i) \n " , res ) ;
goto out ;
invalid :
pr_warn_ratelimited ( " overlayfs: invalid origin (%*phN) \n " , res , fh ) ;
goto out ;
}
2018-01-19 02:03:23 +03:00
struct dentry * ovl_decode_fh ( struct ovl_fh * fh , struct vfsmount * mnt )
2017-06-21 15:28:37 +03:00
{
2018-01-11 12:33:24 +03:00
struct dentry * real ;
2017-06-21 15:28:37 +03:00
int bytes ;
2017-04-30 14:46:31 +03:00
/*
* Make sure that the stored uuid matches the uuid of the lower
* layer where file handle will be decoded .
*/
2017-05-10 16:06:33 +03:00
if ( ! uuid_equal ( & fh - > uuid , & mnt - > mnt_sb - > s_uuid ) )
2017-10-24 15:12:15 +03:00
return NULL ;
2017-04-30 14:46:31 +03:00
2017-06-21 15:28:37 +03:00
bytes = ( fh - > len - offsetof ( struct ovl_fh , fid ) ) ;
2018-01-11 12:33:24 +03:00
real = exportfs_decode_fh ( mnt , ( struct fid * ) fh - > fid ,
bytes > > 2 , ( int ) fh - > type ,
ovl_acceptable , mnt ) ;
if ( IS_ERR ( real ) ) {
/*
* Treat stale file handle to lower file as " origin unknown " .
* upper file handle could become stale when upper file is
* unlinked and this information is needed to handle stale
* index entries correctly .
*/
if ( real = = ERR_PTR ( - ESTALE ) & &
! ( fh - > flags & OVL_FH_FLAG_PATH_UPPER ) )
real = NULL ;
return real ;
2017-04-30 14:46:31 +03:00
}
2018-01-11 12:33:24 +03:00
if ( ovl_dentry_weird ( real ) ) {
dput ( real ) ;
2017-10-24 15:12:15 +03:00
return NULL ;
}
2017-04-30 14:46:31 +03:00
2018-01-11 12:33:24 +03:00
return real ;
2017-04-30 14:46:31 +03:00
}
2017-05-11 16:42:26 +03:00
static bool ovl_is_opaquedir ( struct dentry * dentry )
{
return ovl_check_dir_xattr ( dentry , OVL_XATTR_OPAQUE ) ;
}
2016-12-16 13:02:56 +03:00
static int ovl_lookup_single ( struct dentry * base , struct ovl_lookup_data * d ,
const char * name , unsigned int namelen ,
2016-12-16 13:02:56 +03:00
size_t prelen , const char * post ,
2016-12-16 13:02:56 +03:00
struct dentry * * ret )
{
struct dentry * this ;
int err ;
this = lookup_one_len_unlocked ( name , base , namelen ) ;
if ( IS_ERR ( this ) ) {
err = PTR_ERR ( this ) ;
this = NULL ;
if ( err = = - ENOENT | | err = = - ENAMETOOLONG )
goto out ;
goto out_err ;
}
if ( ! this - > d_inode )
goto put_and_out ;
if ( ovl_dentry_weird ( this ) ) {
/* Don't support traversing automounts and other weirdness */
err = - EREMOTE ;
goto out_err ;
}
if ( ovl_is_whiteout ( this ) ) {
d - > stop = d - > opaque = true ;
goto put_and_out ;
}
if ( ! d_can_lookup ( this ) ) {
d - > stop = true ;
if ( d - > is_dir )
goto put_and_out ;
goto out ;
}
d - > is_dir = true ;
if ( ! d - > last & & ovl_is_opaquedir ( this ) ) {
d - > stop = d - > opaque = true ;
goto out ;
}
2016-12-16 13:02:56 +03:00
err = ovl_check_redirect ( this , d , prelen , post ) ;
if ( err )
goto out_err ;
2016-12-16 13:02:56 +03:00
out :
* ret = this ;
return 0 ;
put_and_out :
dput ( this ) ;
this = NULL ;
goto out ;
out_err :
dput ( this ) ;
return err ;
}
static int ovl_lookup_layer ( struct dentry * base , struct ovl_lookup_data * d ,
struct dentry * * ret )
{
2017-01-18 17:19:54 +03:00
/* Counting down from the end, since the prefix can change */
size_t rem = d - > name . len - 1 ;
2016-12-16 13:02:56 +03:00
struct dentry * dentry = NULL ;
int err ;
2017-01-18 17:19:54 +03:00
if ( d - > name . name [ 0 ] ! = ' / ' )
2016-12-16 13:02:56 +03:00
return ovl_lookup_single ( base , d , d - > name . name , d - > name . len ,
0 , " " , ret ) ;
2017-01-18 17:19:54 +03:00
while ( ! IS_ERR_OR_NULL ( base ) & & d_can_lookup ( base ) ) {
const char * s = d - > name . name + d - > name . len - rem ;
2016-12-16 13:02:56 +03:00
const char * next = strchrnul ( s , ' / ' ) ;
2017-01-18 17:19:54 +03:00
size_t thislen = next - s ;
bool end = ! next [ 0 ] ;
2016-12-16 13:02:56 +03:00
2017-01-18 17:19:54 +03:00
/* Verify we did not go off the rails */
if ( WARN_ON ( s [ - 1 ] ! = ' / ' ) )
2016-12-16 13:02:56 +03:00
return - EIO ;
2017-01-18 17:19:54 +03:00
err = ovl_lookup_single ( base , d , s , thislen ,
d - > name . len - rem , next , & base ) ;
2016-12-16 13:02:56 +03:00
dput ( dentry ) ;
if ( err )
return err ;
dentry = base ;
2017-01-18 17:19:54 +03:00
if ( end )
break ;
rem - = thislen + 1 ;
if ( WARN_ON ( rem > = d - > name . len ) )
return - EIO ;
2016-12-16 13:02:56 +03:00
}
* ret = dentry ;
return 0 ;
2016-12-16 13:02:56 +03:00
}
2017-04-30 14:46:31 +03:00
2018-01-19 22:33:44 +03:00
int ovl_check_origin_fh ( struct ovl_fs * ofs , struct ovl_fh * fh ,
struct dentry * upperdentry , struct ovl_path * * stackp )
2017-04-30 14:46:31 +03:00
{
2017-06-21 15:28:34 +03:00
struct dentry * origin = NULL ;
int i ;
2017-04-30 14:46:31 +03:00
2017-12-12 23:40:46 +03:00
for ( i = 0 ; i < ofs - > numlower ; i + + ) {
origin = ovl_decode_fh ( fh , ofs - > lower_layers [ i ] . mnt ) ;
2017-06-21 15:28:34 +03:00
if ( origin )
break ;
}
if ( ! origin )
2017-10-24 15:12:15 +03:00
return - ESTALE ;
else if ( IS_ERR ( origin ) )
return PTR_ERR ( origin ) ;
2018-01-19 22:33:44 +03:00
if ( upperdentry & & ! ovl_is_whiteout ( upperdentry ) & &
2017-10-24 15:12:15 +03:00
( ( d_inode ( origin ) - > i_mode ^ d_inode ( upperdentry ) - > i_mode ) & S_IFMT ) )
goto invalid ;
2017-04-30 14:46:31 +03:00
2017-06-21 15:28:42 +03:00
if ( ! * stackp )
2017-07-24 09:57:54 +03:00
* stackp = kmalloc ( sizeof ( struct ovl_path ) , GFP_KERNEL ) ;
2017-04-30 14:46:31 +03:00
if ( ! * stackp ) {
dput ( origin ) ;
return - ENOMEM ;
}
2017-12-12 23:40:46 +03:00
* * stackp = ( struct ovl_path ) {
. dentry = origin ,
. layer = & ofs - > lower_layers [ i ]
} ;
2017-04-30 14:46:31 +03:00
return 0 ;
2017-10-24 15:12:15 +03:00
invalid :
pr_warn_ratelimited ( " overlayfs: invalid origin (%pd2, ftype=%x, origin ftype=%x). \n " ,
upperdentry , d_inode ( upperdentry ) - > i_mode & S_IFMT ,
d_inode ( origin ) - > i_mode & S_IFMT ) ;
dput ( origin ) ;
return - EIO ;
}
2017-12-12 23:40:46 +03:00
static int ovl_check_origin ( struct ovl_fs * ofs , struct dentry * upperdentry ,
2017-10-24 15:12:15 +03:00
struct ovl_path * * stackp , unsigned int * ctrp )
{
2018-01-11 09:25:32 +03:00
struct ovl_fh * fh = ovl_get_fh ( upperdentry , OVL_XATTR_ORIGIN ) ;
2017-10-24 15:12:15 +03:00
int err ;
if ( IS_ERR_OR_NULL ( fh ) )
return PTR_ERR ( fh ) ;
2017-12-12 23:40:46 +03:00
err = ovl_check_origin_fh ( ofs , fh , upperdentry , stackp ) ;
2017-10-24 15:12:15 +03:00
kfree ( fh ) ;
if ( err ) {
if ( err = = - ESTALE )
return 0 ;
return err ;
}
if ( WARN_ON ( * ctrp ) )
return - EIO ;
* ctrp = 1 ;
return 0 ;
2017-04-30 14:46:31 +03:00
}
2017-06-21 15:28:37 +03:00
/*
2018-01-11 09:25:32 +03:00
* Verify that @ fh matches the file handle stored in xattr @ name .
2017-06-21 15:28:37 +03:00
* Return 0 on match , - ESTALE on mismatch , < 0 on error .
*/
2018-01-11 09:25:32 +03:00
static int ovl_verify_fh ( struct dentry * dentry , const char * name ,
const struct ovl_fh * fh )
2017-06-21 15:28:37 +03:00
{
2018-01-11 09:25:32 +03:00
struct ovl_fh * ofh = ovl_get_fh ( dentry , name ) ;
2017-06-21 15:28:37 +03:00
int err = 0 ;
if ( ! ofh )
return - ENODATA ;
if ( IS_ERR ( ofh ) )
return PTR_ERR ( ofh ) ;
if ( fh - > len ! = ofh - > len | | memcmp ( fh , ofh , fh - > len ) )
err = - ESTALE ;
kfree ( ofh ) ;
return err ;
}
/*
2018-01-11 09:25:32 +03:00
* Verify that @ real dentry matches the file handle stored in xattr @ name .
2017-06-21 15:28:37 +03:00
*
2018-01-11 09:25:32 +03:00
* If @ set is true and there is no stored file handle , encode @ real and store
* file handle in xattr @ name .
2017-06-21 15:28:37 +03:00
*
2018-01-11 09:25:32 +03:00
* Return 0 on match , - ESTALE on mismatch , - ENODATA on no xattr , < 0 on error .
2017-06-21 15:28:37 +03:00
*/
2018-01-11 09:25:32 +03:00
int ovl_verify_set_fh ( struct dentry * dentry , const char * name ,
struct dentry * real , bool is_upper , bool set )
2017-06-21 15:28:37 +03:00
{
struct inode * inode ;
struct ovl_fh * fh ;
int err ;
2018-01-11 09:25:32 +03:00
fh = ovl_encode_fh ( real , is_upper ) ;
2017-06-21 15:28:37 +03:00
err = PTR_ERR ( fh ) ;
if ( IS_ERR ( fh ) )
goto fail ;
2018-01-11 09:25:32 +03:00
err = ovl_verify_fh ( dentry , name , fh ) ;
2017-06-21 15:28:37 +03:00
if ( set & & err = = - ENODATA )
2018-01-11 09:25:32 +03:00
err = ovl_do_setxattr ( dentry , name , fh , fh - > len , 0 ) ;
2017-06-21 15:28:37 +03:00
if ( err )
goto fail ;
out :
kfree ( fh ) ;
return err ;
fail :
2018-01-11 09:25:32 +03:00
inode = d_inode ( real ) ;
pr_warn_ratelimited ( " overlayfs: failed to verify %s (%pd2, ino=%lu, err=%i) \n " ,
is_upper ? " upper " : " origin " , real ,
inode ? inode - > i_ino : 0 , err ) ;
2017-06-21 15:28:37 +03:00
goto out ;
}
2018-01-11 12:33:24 +03:00
/* Get upper dentry from index */
2017-12-24 19:42:16 +03:00
struct dentry * ovl_index_upper ( struct ovl_fs * ofs , struct dentry * index )
2018-01-11 12:33:24 +03:00
{
struct ovl_fh * fh ;
struct dentry * upper ;
if ( ! d_is_dir ( index ) )
return dget ( index ) ;
fh = ovl_get_fh ( index , OVL_XATTR_UPPER ) ;
if ( IS_ERR_OR_NULL ( fh ) )
return ERR_CAST ( fh ) ;
upper = ovl_decode_fh ( fh , ofs - > upper_mnt ) ;
kfree ( fh ) ;
if ( IS_ERR_OR_NULL ( upper ) )
return upper ? : ERR_PTR ( - ESTALE ) ;
if ( ! d_is_dir ( upper ) ) {
pr_warn_ratelimited ( " overlayfs: invalid index upper (%pd2, upper=%pd2). \n " ,
index , upper ) ;
dput ( upper ) ;
return ERR_PTR ( - EIO ) ;
}
return upper ;
}
2017-11-01 11:13:51 +03:00
/* Is this a leftover from create/whiteout of directory index entry? */
static bool ovl_is_temp_index ( struct dentry * index )
{
return index - > d_name . name [ 0 ] = = ' # ' ;
}
2017-06-21 15:28:42 +03:00
/*
* Verify that an index entry name matches the origin file handle stored in
* OVL_XATTR_ORIGIN and that origin file handle can be decoded to lower path .
* Return 0 on match , - ESTALE on mismatch or stale origin , < 0 on error .
*/
2017-12-12 23:40:46 +03:00
int ovl_verify_index ( struct ovl_fs * ofs , struct dentry * index )
2017-06-21 15:28:42 +03:00
{
struct ovl_fh * fh = NULL ;
size_t len ;
2017-07-24 09:57:54 +03:00
struct ovl_path origin = { } ;
struct ovl_path * stack = & origin ;
2018-01-11 12:33:24 +03:00
struct dentry * upper = NULL ;
2017-06-21 15:28:42 +03:00
int err ;
if ( ! d_inode ( index ) )
return 0 ;
2017-11-01 11:13:51 +03:00
/* Cleanup leftover from index create/cleanup attempt */
err = - ESTALE ;
if ( ovl_is_temp_index ( index ) )
goto fail ;
2017-10-24 12:24:11 +03:00
err = - EINVAL ;
2017-06-21 15:28:42 +03:00
if ( index - > d_name . len < sizeof ( struct ovl_fh ) * 2 )
goto fail ;
err = - ENOMEM ;
len = index - > d_name . len / 2 ;
2017-09-14 02:28:29 +03:00
fh = kzalloc ( len , GFP_KERNEL ) ;
2017-06-21 15:28:42 +03:00
if ( ! fh )
goto fail ;
err = - EINVAL ;
2017-10-24 15:12:15 +03:00
if ( hex2bin ( ( u8 * ) fh , index - > d_name . name , len ) )
goto fail ;
err = ovl_check_fh_len ( fh , len ) ;
if ( err )
2017-06-21 15:28:42 +03:00
goto fail ;
2018-01-11 12:03:13 +03:00
/*
* Whiteout index entries are used as an indication that an exported
* overlay file handle should be treated as stale ( i . e . after unlink
* of the overlay inode ) . These entries contain no origin xattr .
*/
if ( ovl_is_whiteout ( index ) )
goto out ;
2018-01-11 12:33:24 +03:00
/*
* Verifying directory index entries are not stale is expensive , so
* only verify stale dir index if NFS export is enabled .
*/
if ( d_is_dir ( index ) & & ! ofs - > config . nfs_export )
goto out ;
/*
* Directory index entries should have ' upper ' xattr pointing to the
* real upper dir . Non - dir index entries are hardlinks to the upper
* real inode . For non - dir index , we can read the copy up origin xattr
* directly from the index dentry , but for dir index we first need to
* decode the upper directory .
*/
upper = ovl_index_upper ( ofs , index ) ;
if ( IS_ERR_OR_NULL ( upper ) ) {
err = PTR_ERR ( upper ) ;
2018-01-11 16:33:51 +03:00
/*
* Directory index entries with no ' upper ' xattr need to be
* removed . When dir index entry has a stale ' upper ' xattr ,
* we assume that upper dir was removed and we treat the dir
* index as orphan entry that needs to be whited out .
*/
if ( err = = - ESTALE )
goto orphan ;
else if ( ! err )
2018-01-11 12:33:24 +03:00
err = - ESTALE ;
2017-06-21 15:28:42 +03:00
goto fail ;
2018-01-11 12:33:24 +03:00
}
2017-06-21 15:28:42 +03:00
2018-01-11 12:33:24 +03:00
err = ovl_verify_fh ( upper , OVL_XATTR_ORIGIN , fh ) ;
dput ( upper ) ;
2017-06-21 15:28:42 +03:00
if ( err )
goto fail ;
2018-01-11 12:33:24 +03:00
/* Check if non-dir index is orphan and don't warn before cleaning it */
if ( ! d_is_dir ( index ) & & d_inode ( index ) - > i_nlink = = 1 ) {
err = ovl_check_origin_fh ( ofs , fh , index , & stack ) ;
if ( err )
goto fail ;
if ( ovl_get_nlink ( origin . dentry , index , 0 ) = = 0 )
2018-01-11 16:33:51 +03:00
goto orphan ;
2018-01-11 12:33:24 +03:00
}
2017-06-21 13:46:12 +03:00
2017-06-21 15:28:42 +03:00
out :
2018-01-11 12:33:24 +03:00
dput ( origin . dentry ) ;
2017-06-21 15:28:42 +03:00
kfree ( fh ) ;
return err ;
fail :
2017-07-18 21:07:42 +03:00
pr_warn_ratelimited ( " overlayfs: failed to verify index (%pd2, ftype=%x, err=%i) \n " ,
index , d_inode ( index ) - > i_mode & S_IFMT , err ) ;
2017-06-21 15:28:42 +03:00
goto out ;
2018-01-11 16:33:51 +03:00
orphan :
pr_warn_ratelimited ( " overlayfs: orphan index entry (%pd2, ftype=%x, nlink=%u) \n " ,
index , d_inode ( index ) - > i_mode & S_IFMT ,
d_inode ( index ) - > i_nlink ) ;
err = - ENOENT ;
goto out ;
2017-06-21 15:28:42 +03:00
}
2017-12-28 21:23:05 +03:00
static int ovl_get_index_name_fh ( struct ovl_fh * fh , struct qstr * name )
{
char * n , * s ;
n = kzalloc ( fh - > len * 2 , GFP_KERNEL ) ;
if ( ! n )
return - ENOMEM ;
s = bin2hex ( n , fh , fh - > len ) ;
* name = ( struct qstr ) QSTR_INIT ( n , s - n ) ;
return 0 ;
}
2017-06-21 15:28:41 +03:00
/*
* Lookup in indexdir for the index entry of a lower real inode or a copy up
* origin inode . The index entry name is the hex representation of the lower
* inode file handle .
*
* If the index dentry in negative , then either no lower aliases have been
* copied up yet , or aliases have been copied up in older kernels and are
* not indexed .
*
* If the index dentry for a copy up origin inode is positive , but points
* to an inode different than the upper inode , then either the upper inode
* has been copied up and not indexed or it was indexed , but since then
* index dir was cleared . Either way , that index cannot be used to indentify
* the overlay inode .
*/
int ovl_get_index_name ( struct dentry * origin , struct qstr * name )
{
struct ovl_fh * fh ;
2017-12-28 21:23:05 +03:00
int err ;
2017-06-21 15:28:41 +03:00
fh = ovl_encode_fh ( origin , false ) ;
if ( IS_ERR ( fh ) )
return PTR_ERR ( fh ) ;
2017-12-28 21:23:05 +03:00
err = ovl_get_index_name_fh ( fh , name ) ;
2017-06-21 15:28:41 +03:00
2017-12-28 21:23:05 +03:00
kfree ( fh ) ;
2017-06-21 15:28:41 +03:00
return err ;
2017-12-28 21:23:05 +03:00
}
/* Lookup index by file handle for NFS export */
struct dentry * ovl_get_index_fh ( struct ovl_fs * ofs , struct ovl_fh * fh )
{
struct dentry * index ;
struct qstr name ;
int err ;
err = ovl_get_index_name_fh ( fh , & name ) ;
if ( err )
return ERR_PTR ( err ) ;
index = lookup_one_len_unlocked ( name . name , ofs - > indexdir , name . len ) ;
kfree ( name . name ) ;
if ( IS_ERR ( index ) ) {
if ( PTR_ERR ( index ) = = - ENOENT )
index = NULL ;
return index ;
}
if ( d_is_negative ( index ) )
err = 0 ;
else if ( ovl_is_whiteout ( index ) )
err = - ESTALE ;
else if ( ovl_dentry_weird ( index ) )
err = - EIO ;
else
return index ;
2017-06-21 15:28:41 +03:00
2017-12-28 21:23:05 +03:00
dput ( index ) ;
return ERR_PTR ( err ) ;
2017-06-21 15:28:41 +03:00
}
static struct dentry * ovl_lookup_index ( struct dentry * dentry ,
struct dentry * upper ,
struct dentry * origin )
{
struct ovl_fs * ofs = dentry - > d_sb - > s_fs_info ;
struct dentry * index ;
struct inode * inode ;
struct qstr name ;
2018-01-11 11:47:03 +03:00
bool is_dir = d_is_dir ( origin ) ;
2017-06-21 15:28:41 +03:00
int err ;
err = ovl_get_index_name ( origin , & name ) ;
if ( err )
return ERR_PTR ( err ) ;
index = lookup_one_len_unlocked ( name . name , ofs - > indexdir , name . len ) ;
if ( IS_ERR ( index ) ) {
2017-09-24 13:01:35 +03:00
err = PTR_ERR ( index ) ;
2017-10-20 17:19:06 +03:00
if ( err = = - ENOENT ) {
index = NULL ;
goto out ;
}
2017-06-21 15:28:41 +03:00
pr_warn_ratelimited ( " overlayfs: failed inode index lookup (ino=%lu, key=%*s, err=%i); \n "
" overlayfs: mount with '-o index=off' to disable inodes index. \n " ,
d_inode ( origin ) - > i_ino , name . len , name . name ,
err ) ;
goto out ;
}
2017-07-18 21:07:43 +03:00
inode = d_inode ( index ) ;
2017-06-21 15:28:41 +03:00
if ( d_is_negative ( index ) ) {
2017-10-12 19:03:04 +03:00
goto out_dput ;
2017-07-18 21:07:43 +03:00
} else if ( ovl_dentry_weird ( index ) | | ovl_is_whiteout ( index ) | |
( ( inode - > i_mode ^ d_inode ( origin ) - > i_mode ) & S_IFMT ) ) {
/*
* Index should always be of the same file type as origin
* except for the case of a whiteout index . A whiteout
* index should only exist if all lower aliases have been
* unlinked , which means that finding a lower origin on lookup
* whose index is a whiteout should be treated as an error .
*/
pr_warn_ratelimited ( " overlayfs: bad index found (index=%pd2, ftype=%x, origin ftype=%x). \n " ,
index , d_inode ( index ) - > i_mode & S_IFMT ,
d_inode ( origin ) - > i_mode & S_IFMT ) ;
2017-06-21 15:28:41 +03:00
goto fail ;
2018-01-11 11:47:03 +03:00
} else if ( is_dir ) {
if ( ! upper ) {
pr_warn_ratelimited ( " overlayfs: suspected uncovered redirected dir found (origin=%pd2, index=%pd2). \n " ,
origin , index ) ;
goto fail ;
}
2017-06-21 15:28:41 +03:00
2018-01-11 11:47:03 +03:00
/* Verify that dir index 'upper' xattr points to upper dir */
err = ovl_verify_upper ( index , upper , false ) ;
if ( err ) {
if ( err = = - ESTALE ) {
pr_warn_ratelimited ( " overlayfs: suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2). \n " ,
upper , origin , index ) ;
}
goto fail ;
}
} else if ( upper & & d_inode ( upper ) ! = inode ) {
goto out_dput ;
}
2017-06-21 15:28:41 +03:00
out :
kfree ( name . name ) ;
return index ;
2017-10-12 19:03:04 +03:00
out_dput :
dput ( index ) ;
index = NULL ;
goto out ;
2017-06-21 15:28:41 +03:00
fail :
dput ( index ) ;
index = ERR_PTR ( - EIO ) ;
goto out ;
}
2016-12-16 13:02:56 +03:00
/*
* Returns next layer in stack starting from top .
* Returns - 1 if this is the last layer .
*/
int ovl_path_next ( int idx , struct dentry * dentry , struct path * path )
{
struct ovl_entry * oe = dentry - > d_fsdata ;
BUG_ON ( idx < 0 ) ;
if ( idx = = 0 ) {
ovl_path_upper ( dentry , path ) ;
if ( path - > dentry )
return oe - > numlower ? 1 : - 1 ;
idx + + ;
}
BUG_ON ( idx > oe - > numlower ) ;
2017-07-24 09:57:54 +03:00
path - > dentry = oe - > lowerstack [ idx - 1 ] . dentry ;
path - > mnt = oe - > lowerstack [ idx - 1 ] . layer - > mnt ;
2016-12-16 13:02:56 +03:00
return ( idx < oe - > numlower ) ? idx + 1 : - 1 ;
}
2018-01-03 20:34:45 +03:00
/* Fix missing 'origin' xattr */
static int ovl_fix_origin ( struct dentry * dentry , struct dentry * lower ,
struct dentry * upper )
{
int err ;
if ( ovl_check_origin_xattr ( upper ) )
return 0 ;
err = ovl_want_write ( dentry ) ;
if ( err )
return err ;
err = ovl_set_origin ( dentry , lower , upper ) ;
if ( ! err )
err = ovl_set_impure ( dentry - > d_parent , upper - > d_parent ) ;
ovl_drop_write ( dentry ) ;
return err ;
}
2016-12-16 13:02:56 +03:00
struct dentry * ovl_lookup ( struct inode * dir , struct dentry * dentry ,
unsigned int flags )
{
struct ovl_entry * oe ;
const struct cred * old_cred ;
2016-12-16 13:02:56 +03:00
struct ovl_fs * ofs = dentry - > d_sb - > s_fs_info ;
2016-12-16 13:02:56 +03:00
struct ovl_entry * poe = dentry - > d_parent - > d_fsdata ;
2017-04-26 23:40:52 +03:00
struct ovl_entry * roe = dentry - > d_sb - > s_root - > d_fsdata ;
2017-07-24 09:57:54 +03:00
struct ovl_path * stack = NULL ;
2016-12-16 13:02:56 +03:00
struct dentry * upperdir , * upperdentry = NULL ;
2018-01-11 11:47:03 +03:00
struct dentry * origin = NULL ;
2017-06-21 15:28:41 +03:00
struct dentry * index = NULL ;
2016-12-16 13:02:56 +03:00
unsigned int ctr = 0 ;
struct inode * inode = NULL ;
bool upperopaque = false ;
2016-12-16 13:02:56 +03:00
char * upperredirect = NULL ;
2016-12-16 13:02:56 +03:00
struct dentry * this ;
unsigned int i ;
int err ;
2016-12-16 13:02:56 +03:00
struct ovl_lookup_data d = {
. name = dentry - > d_name ,
. is_dir = false ,
. opaque = false ,
. stop = false ,
. last = ! poe - > numlower ,
2016-12-16 13:02:56 +03:00
. redirect = NULL ,
2016-12-16 13:02:56 +03:00
} ;
2016-12-16 13:02:56 +03:00
2016-12-16 13:02:56 +03:00
if ( dentry - > d_name . len > ofs - > namelen )
return ERR_PTR ( - ENAMETOOLONG ) ;
2016-12-16 13:02:56 +03:00
old_cred = ovl_override_creds ( dentry - > d_sb ) ;
2017-07-04 23:03:16 +03:00
upperdir = ovl_dentry_upper ( dentry - > d_parent ) ;
2016-12-16 13:02:56 +03:00
if ( upperdir ) {
2016-12-16 13:02:56 +03:00
err = ovl_lookup_layer ( upperdir , & d , & upperdentry ) ;
if ( err )
2016-12-16 13:02:56 +03:00
goto out ;
2016-12-16 13:02:56 +03:00
if ( upperdentry & & unlikely ( ovl_dentry_remote ( upperdentry ) ) ) {
dput ( upperdentry ) ;
err = - EREMOTE ;
goto out ;
2016-12-16 13:02:56 +03:00
}
2017-04-30 14:46:31 +03:00
if ( upperdentry & & ! d . is_dir ) {
BUG_ON ( ! d . stop | | d . redirect ) ;
2017-06-21 15:28:34 +03:00
/*
* Lookup copy up origin by decoding origin file handle .
* We may get a disconnected dentry , which is fine ,
* because we only need to hold the origin inode in
* cache and use its inode number . We may even get a
* connected dentry , that is not under any of the lower
* layers root . That is also fine for using it ' s inode
* number - it ' s the same as if we held a reference
* to a dentry in lower layer that was moved under us .
*/
2017-12-12 23:40:46 +03:00
err = ovl_check_origin ( ofs , upperdentry , & stack , & ctr ) ;
2017-04-30 14:46:31 +03:00
if ( err )
2017-11-01 22:37:22 +03:00
goto out_put_upper ;
2017-04-30 14:46:31 +03:00
}
2016-12-16 13:02:56 +03:00
if ( d . redirect ) {
2017-09-22 23:45:18 +03:00
err = - ENOMEM ;
2016-12-16 13:02:56 +03:00
upperredirect = kstrdup ( d . redirect , GFP_KERNEL ) ;
if ( ! upperredirect )
goto out_put_upper ;
if ( d . redirect [ 0 ] = = ' / ' )
2017-04-26 23:40:52 +03:00
poe = roe ;
2016-12-16 13:02:56 +03:00
}
2016-12-16 13:02:56 +03:00
upperopaque = d . opaque ;
2016-12-16 13:02:56 +03:00
}
2016-12-16 13:02:56 +03:00
if ( ! d . stop & & poe - > numlower ) {
2016-12-16 13:02:56 +03:00
err = - ENOMEM ;
2017-07-24 09:57:54 +03:00
stack = kcalloc ( ofs - > numlower , sizeof ( struct ovl_path ) ,
2017-09-14 02:28:29 +03:00
GFP_KERNEL ) ;
2016-12-16 13:02:56 +03:00
if ( ! stack )
goto out_put_upper ;
}
2016-12-16 13:02:56 +03:00
for ( i = 0 ; ! d . stop & & i < poe - > numlower ; i + + ) {
2017-07-24 09:57:54 +03:00
struct ovl_path lower = poe - > lowerstack [ i ] ;
2016-12-16 13:02:56 +03:00
2016-12-16 13:02:56 +03:00
d . last = i = = poe - > numlower - 1 ;
2017-07-24 09:57:54 +03:00
err = ovl_lookup_layer ( lower . dentry , & d , & this ) ;
2016-12-16 13:02:56 +03:00
if ( err )
2016-12-16 13:02:56 +03:00
goto out_put ;
2016-12-16 13:02:56 +03:00
2016-12-16 13:02:56 +03:00
if ( ! this )
continue ;
2018-01-03 20:34:45 +03:00
/*
* If no origin fh is stored in upper of a merge dir , store fh
* of lower dir and set upper parent " impure " .
*/
if ( upperdentry & & ! ctr & & ! ofs - > noxattr ) {
err = ovl_fix_origin ( dentry , this , upperdentry ) ;
if ( err ) {
dput ( this ) ;
goto out_put ;
}
}
2018-01-10 23:29:38 +03:00
/*
* When " verify_lower " feature is enabled , do not merge with a
2018-01-11 11:47:03 +03:00
* lower dir that does not match a stored origin xattr . In any
* case , only verified origin is used for index lookup .
2018-01-10 23:29:38 +03:00
*/
if ( upperdentry & & ! ctr & & ovl_verify_lower ( dentry - > d_sb ) ) {
err = ovl_verify_origin ( upperdentry , this , false ) ;
if ( err ) {
dput ( this ) ;
break ;
}
2018-01-11 11:47:03 +03:00
/* Bless lower dir as verified origin */
origin = this ;
2018-01-10 23:29:38 +03:00
}
2016-12-16 13:02:56 +03:00
stack [ ctr ] . dentry = this ;
2017-07-24 09:57:54 +03:00
stack [ ctr ] . layer = lower . layer ;
2016-12-16 13:02:56 +03:00
ctr + + ;
2016-12-16 13:02:56 +03:00
if ( d . stop )
break ;
2017-12-11 13:28:10 +03:00
/*
* Following redirects can have security consequences : it ' s like
* a symlink into the lower layer without the permission checks .
* This is only a problem if the upper layer is untrusted ( e . g
* comes from an USB drive ) . This can allow a non - readable file
* or directory to become readable .
*
* Only following redirects when redirects are enabled disables
* this attack vector when not necessary .
*/
err = - EPERM ;
if ( d . redirect & & ! ofs - > config . redirect_follow ) {
2017-12-18 15:25:56 +03:00
pr_warn_ratelimited ( " overlayfs: refusing to follow redirect for (%pd2) \n " ,
dentry ) ;
2017-12-11 13:28:10 +03:00
goto out_put ;
}
2017-04-26 23:40:52 +03:00
if ( d . redirect & & d . redirect [ 0 ] = = ' / ' & & poe ! = roe ) {
poe = roe ;
2016-12-16 13:02:56 +03:00
/* Find the current layer on the root dentry */
2017-11-08 20:23:36 +03:00
i = lower . layer - > idx - 1 ;
2016-12-16 13:02:56 +03:00
}
2016-12-16 13:02:56 +03:00
}
2018-01-11 11:47:03 +03:00
/*
* Lookup index by lower inode and verify it matches upper inode .
* We only trust dir index if we verified that lower dir matches
* origin , otherwise dir index entries may be inconsistent and we
* ignore them . Always lookup index of non - dir and non - upper .
*/
if ( ctr & & ( ! upperdentry | | ! d . is_dir ) )
origin = stack [ 0 ] . dentry ;
2017-06-21 15:28:41 +03:00
2018-01-11 11:47:03 +03:00
if ( origin & & ovl_indexdir ( dentry - > d_sb ) & &
( ! d . is_dir | | ovl_index_all ( dentry - > d_sb ) ) ) {
2017-06-21 15:28:41 +03:00
index = ovl_lookup_index ( dentry , upperdentry , origin ) ;
if ( IS_ERR ( index ) ) {
err = PTR_ERR ( index ) ;
index = NULL ;
goto out_put ;
}
}
2016-12-16 13:02:56 +03:00
oe = ovl_alloc_entry ( ctr ) ;
err = - ENOMEM ;
if ( ! oe )
goto out_put ;
2017-07-24 09:57:54 +03:00
memcpy ( oe - > lowerstack , stack , sizeof ( struct ovl_path ) * ctr ) ;
2017-07-04 23:03:16 +03:00
dentry - > d_fsdata = oe ;
2016-12-16 13:02:56 +03:00
2018-01-14 20:25:31 +03:00
if ( upperopaque )
ovl_dentry_set_opaque ( dentry ) ;
2017-07-04 23:03:18 +03:00
if ( upperdentry )
ovl_dentry_set_upper_alias ( dentry ) ;
else if ( index )
2017-06-21 15:28:41 +03:00
upperdentry = dget ( index ) ;
2017-07-04 23:03:16 +03:00
if ( upperdentry | | ctr ) {
2017-12-13 00:43:16 +03:00
inode = ovl_get_inode ( dentry - > d_sb , upperdentry , origin , index ,
ctr ) ;
2017-07-04 23:03:17 +03:00
err = PTR_ERR ( inode ) ;
if ( IS_ERR ( inode ) )
2016-12-16 13:02:56 +03:00
goto out_free_oe ;
2017-07-04 23:03:16 +03:00
OVL_I ( inode ) - > redirect = upperredirect ;
2017-06-21 15:28:41 +03:00
if ( index )
ovl_set_flag ( OVL_INDEX , inode ) ;
2016-12-16 13:02:56 +03:00
}
revert_creds ( old_cred ) ;
2017-06-21 15:28:41 +03:00
dput ( index ) ;
2016-12-16 13:02:56 +03:00
kfree ( stack ) ;
2016-12-16 13:02:56 +03:00
kfree ( d . redirect ) ;
2017-09-29 21:43:07 +03:00
return d_splice_alias ( inode , dentry ) ;
2016-12-16 13:02:56 +03:00
out_free_oe :
2017-07-04 23:03:16 +03:00
dentry - > d_fsdata = NULL ;
2016-12-16 13:02:56 +03:00
kfree ( oe ) ;
out_put :
2017-06-21 15:28:41 +03:00
dput ( index ) ;
2016-12-16 13:02:56 +03:00
for ( i = 0 ; i < ctr ; i + + )
dput ( stack [ i ] . dentry ) ;
kfree ( stack ) ;
out_put_upper :
dput ( upperdentry ) ;
2016-12-16 13:02:56 +03:00
kfree ( upperredirect ) ;
2016-12-16 13:02:56 +03:00
out :
2016-12-16 13:02:56 +03:00
kfree ( d . redirect ) ;
2016-12-16 13:02:56 +03:00
revert_creds ( old_cred ) ;
return ERR_PTR ( err ) ;
}
bool ovl_lower_positive ( struct dentry * dentry )
{
struct ovl_entry * poe = dentry - > d_parent - > d_fsdata ;
const struct qstr * name = & dentry - > d_name ;
2017-11-10 14:18:07 +03:00
const struct cred * old_cred ;
2016-12-16 13:02:56 +03:00
unsigned int i ;
bool positive = false ;
bool done = false ;
/*
* If dentry is negative , then lower is positive iff this is a
* whiteout .
*/
if ( ! dentry - > d_inode )
2018-01-14 20:25:31 +03:00
return ovl_dentry_is_opaque ( dentry ) ;
2016-12-16 13:02:56 +03:00
/* Negative upper -> positive lower */
2017-07-04 23:03:16 +03:00
if ( ! ovl_dentry_upper ( dentry ) )
2016-12-16 13:02:56 +03:00
return true ;
2017-11-10 14:18:07 +03:00
old_cred = ovl_override_creds ( dentry - > d_sb ) ;
2016-12-16 13:02:56 +03:00
/* Positive upper -> have to look up lower to see whether it exists */
for ( i = 0 ; ! done & & ! positive & & i < poe - > numlower ; i + + ) {
struct dentry * this ;
struct dentry * lowerdir = poe - > lowerstack [ i ] . dentry ;
this = lookup_one_len_unlocked ( name - > name , lowerdir ,
name - > len ) ;
if ( IS_ERR ( this ) ) {
switch ( PTR_ERR ( this ) ) {
case - ENOENT :
case - ENAMETOOLONG :
break ;
default :
/*
* Assume something is there , we just couldn ' t
* access it .
*/
positive = true ;
break ;
}
} else {
if ( this - > d_inode ) {
positive = ! ovl_is_whiteout ( this ) ;
done = true ;
}
dput ( this ) ;
}
}
2017-11-10 14:18:07 +03:00
revert_creds ( old_cred ) ;
2016-12-16 13:02:56 +03:00
return positive ;
}