1414#include <linux/posix_acl_xattr.h>
1515#include <linux/atomic.h>
1616#include <linux/ratelimit.h>
17+ #include <linux/backing-file.h>
1718#include "overlayfs.h"
1819
1920static unsigned short ovl_redirect_max = 256 ;
@@ -260,14 +261,13 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry)
260261 * may not use to instantiate the new dentry.
261262 */
262263static int ovl_instantiate (struct dentry * dentry , struct inode * inode ,
263- struct dentry * newdentry , bool hardlink )
264+ struct dentry * newdentry , bool hardlink , struct file * tmpfile )
264265{
265266 struct ovl_inode_params oip = {
266267 .upperdentry = newdentry ,
267268 .newinode = inode ,
268269 };
269270
270- ovl_dir_modified (dentry -> d_parent , false);
271271 ovl_dentry_set_upper_alias (dentry );
272272 ovl_dentry_init_reval (dentry , newdentry , NULL );
273273
@@ -295,6 +295,9 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
295295 inc_nlink (inode );
296296 }
297297
298+ if (tmpfile )
299+ d_mark_tmpfile (tmpfile , inode );
300+
298301 d_instantiate (dentry , inode );
299302 if (inode != oip .newinode ) {
300303 pr_warn_ratelimited ("newly created inode found in cache (%pd2)\n" ,
@@ -327,9 +330,6 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
327330 struct dentry * newdentry ;
328331 int err ;
329332
330- if (!attr -> hardlink && !IS_POSIXACL (udir ))
331- attr -> mode &= ~current_umask ();
332-
333333 inode_lock_nested (udir , I_MUTEX_PARENT );
334334 newdentry = ovl_create_real (ofs , udir ,
335335 ovl_lookup_upper (ofs , dentry -> d_name .name ,
@@ -345,7 +345,8 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
345345 ovl_set_opaque (dentry , newdentry );
346346 }
347347
348- err = ovl_instantiate (dentry , inode , newdentry , !!attr -> hardlink );
348+ ovl_dir_modified (dentry -> d_parent , false);
349+ err = ovl_instantiate (dentry , inode , newdentry , !!attr -> hardlink , NULL );
349350 if (err )
350351 goto out_cleanup ;
351352out_unlock :
@@ -529,7 +530,8 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
529530 if (err )
530531 goto out_cleanup ;
531532 }
532- err = ovl_instantiate (dentry , inode , newdentry , hardlink );
533+ ovl_dir_modified (dentry -> d_parent , false);
534+ err = ovl_instantiate (dentry , inode , newdentry , hardlink , NULL );
533535 if (err ) {
534536 ovl_cleanup (ofs , udir , newdentry );
535537 dput (newdentry );
@@ -551,12 +553,35 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
551553 goto out_dput ;
552554}
553555
556+ static int ovl_setup_cred_for_create (struct dentry * dentry , struct inode * inode ,
557+ umode_t mode , const struct cred * old_cred )
558+ {
559+ int err ;
560+ struct cred * override_cred ;
561+
562+ override_cred = prepare_creds ();
563+ if (!override_cred )
564+ return - ENOMEM ;
565+
566+ override_cred -> fsuid = inode -> i_uid ;
567+ override_cred -> fsgid = inode -> i_gid ;
568+ err = security_dentry_create_files_as (dentry , mode , & dentry -> d_name ,
569+ old_cred , override_cred );
570+ if (err ) {
571+ put_cred (override_cred );
572+ return err ;
573+ }
574+ put_cred (override_creds (override_cred ));
575+ put_cred (override_cred );
576+
577+ return 0 ;
578+ }
579+
554580static int ovl_create_or_link (struct dentry * dentry , struct inode * inode ,
555581 struct ovl_cattr * attr , bool origin )
556582{
557583 int err ;
558584 const struct cred * old_cred ;
559- struct cred * override_cred ;
560585 struct dentry * parent = dentry -> d_parent ;
561586
562587 old_cred = ovl_override_creds (dentry -> d_sb );
@@ -572,10 +597,6 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
572597 }
573598
574599 if (!attr -> hardlink ) {
575- err = - ENOMEM ;
576- override_cred = prepare_creds ();
577- if (!override_cred )
578- goto out_revert_creds ;
579600 /*
580601 * In the creation cases(create, mkdir, mknod, symlink),
581602 * ovl should transfer current's fs{u,g}id to underlying
@@ -589,17 +610,9 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
589610 * create a new inode, so just use the ovl mounter's
590611 * fs{u,g}id.
591612 */
592- override_cred -> fsuid = inode -> i_uid ;
593- override_cred -> fsgid = inode -> i_gid ;
594- err = security_dentry_create_files_as (dentry ,
595- attr -> mode , & dentry -> d_name , old_cred ,
596- override_cred );
597- if (err ) {
598- put_cred (override_cred );
613+ err = ovl_setup_cred_for_create (dentry , inode , attr -> mode , old_cred );
614+ if (err )
599615 goto out_revert_creds ;
600- }
601- put_cred (override_creds (override_cred ));
602- put_cred (override_cred );
603616 }
604617
605618 if (!ovl_dentry_is_whiteout (dentry ))
@@ -1290,6 +1303,100 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
12901303 return err ;
12911304}
12921305
1306+ static int ovl_create_tmpfile (struct file * file , struct dentry * dentry ,
1307+ struct inode * inode , umode_t mode )
1308+ {
1309+ const struct cred * old_cred ;
1310+ struct path realparentpath ;
1311+ struct file * realfile ;
1312+ struct dentry * newdentry ;
1313+ /* It's okay to set O_NOATIME, since the owner will be current fsuid */
1314+ int flags = file -> f_flags | OVL_OPEN_FLAGS ;
1315+ int err ;
1316+
1317+ err = ovl_copy_up (dentry -> d_parent );
1318+ if (err )
1319+ return err ;
1320+
1321+ old_cred = ovl_override_creds (dentry -> d_sb );
1322+ err = ovl_setup_cred_for_create (dentry , inode , mode , old_cred );
1323+ if (err )
1324+ goto out_revert_creds ;
1325+
1326+ ovl_path_upper (dentry -> d_parent , & realparentpath );
1327+ realfile = backing_tmpfile_open (& file -> f_path , flags , & realparentpath ,
1328+ mode , current_cred ());
1329+ err = PTR_ERR_OR_ZERO (realfile );
1330+ pr_debug ("tmpfile/open(%pd2, 0%o) = %i\n" , realparentpath .dentry , mode , err );
1331+ if (err )
1332+ goto out_revert_creds ;
1333+
1334+ /* ovl_instantiate() consumes the newdentry reference on success */
1335+ newdentry = dget (realfile -> f_path .dentry );
1336+ err = ovl_instantiate (dentry , inode , newdentry , false, file );
1337+ if (!err ) {
1338+ file -> private_data = realfile ;
1339+ } else {
1340+ dput (newdentry );
1341+ fput (realfile );
1342+ }
1343+ out_revert_creds :
1344+ revert_creds (old_cred );
1345+ return err ;
1346+ }
1347+
1348+ static int ovl_dummy_open (struct inode * inode , struct file * file )
1349+ {
1350+ return 0 ;
1351+ }
1352+
1353+ static int ovl_tmpfile (struct mnt_idmap * idmap , struct inode * dir ,
1354+ struct file * file , umode_t mode )
1355+ {
1356+ int err ;
1357+ struct dentry * dentry = file -> f_path .dentry ;
1358+ struct inode * inode ;
1359+
1360+ if (!OVL_FS (dentry -> d_sb )-> tmpfile )
1361+ return - EOPNOTSUPP ;
1362+
1363+ err = ovl_want_write (dentry );
1364+ if (err )
1365+ return err ;
1366+
1367+ err = - ENOMEM ;
1368+ inode = ovl_new_inode (dentry -> d_sb , mode , 0 );
1369+ if (!inode )
1370+ goto drop_write ;
1371+
1372+ inode_init_owner (& nop_mnt_idmap , inode , dir , mode );
1373+ err = ovl_create_tmpfile (file , dentry , inode , inode -> i_mode );
1374+ if (err )
1375+ goto put_inode ;
1376+
1377+ /*
1378+ * Check if the preallocated inode was actually used. Having something
1379+ * else assigned to the dentry shouldn't happen as that would indicate
1380+ * that the backing tmpfile "leaked" out of overlayfs.
1381+ */
1382+ err = - EIO ;
1383+ if (WARN_ON (inode != d_inode (dentry )))
1384+ goto put_realfile ;
1385+
1386+ /* inode reference was transferred to dentry */
1387+ inode = NULL ;
1388+ err = finish_open (file , dentry , ovl_dummy_open );
1389+ put_realfile :
1390+ /* Without FMODE_OPENED ->release() won't be called on @file */
1391+ if (!(file -> f_mode & FMODE_OPENED ))
1392+ fput (file -> private_data );
1393+ put_inode :
1394+ iput (inode );
1395+ drop_write :
1396+ ovl_drop_write (dentry );
1397+ return err ;
1398+ }
1399+
12931400const struct inode_operations ovl_dir_inode_operations = {
12941401 .lookup = ovl_lookup ,
12951402 .mkdir = ovl_mkdir ,
@@ -1310,4 +1417,5 @@ const struct inode_operations ovl_dir_inode_operations = {
13101417 .update_time = ovl_update_time ,
13111418 .fileattr_get = ovl_fileattr_get ,
13121419 .fileattr_set = ovl_fileattr_set ,
1420+ .tmpfile = ovl_tmpfile ,
13131421};
0 commit comments