14
14
#include <linux/posix_acl_xattr.h>
15
15
#include <linux/atomic.h>
16
16
#include <linux/ratelimit.h>
17
+ #include <linux/backing-file.h>
17
18
#include "overlayfs.h"
18
19
19
20
static unsigned short ovl_redirect_max = 256 ;
@@ -260,14 +261,13 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry)
260
261
* may not use to instantiate the new dentry.
261
262
*/
262
263
static int ovl_instantiate (struct dentry * dentry , struct inode * inode ,
263
- struct dentry * newdentry , bool hardlink )
264
+ struct dentry * newdentry , bool hardlink , struct file * tmpfile )
264
265
{
265
266
struct ovl_inode_params oip = {
266
267
.upperdentry = newdentry ,
267
268
.newinode = inode ,
268
269
};
269
270
270
- ovl_dir_modified (dentry -> d_parent , false);
271
271
ovl_dentry_set_upper_alias (dentry );
272
272
ovl_dentry_init_reval (dentry , newdentry , NULL );
273
273
@@ -295,6 +295,9 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
295
295
inc_nlink (inode );
296
296
}
297
297
298
+ if (tmpfile )
299
+ d_mark_tmpfile (tmpfile , inode );
300
+
298
301
d_instantiate (dentry , inode );
299
302
if (inode != oip .newinode ) {
300
303
pr_warn_ratelimited ("newly created inode found in cache (%pd2)\n" ,
@@ -345,7 +348,8 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
345
348
ovl_set_opaque (dentry , newdentry );
346
349
}
347
350
348
- err = ovl_instantiate (dentry , inode , newdentry , !!attr -> hardlink );
351
+ ovl_dir_modified (dentry -> d_parent , false);
352
+ err = ovl_instantiate (dentry , inode , newdentry , !!attr -> hardlink , NULL );
349
353
if (err )
350
354
goto out_cleanup ;
351
355
out_unlock :
@@ -529,7 +533,8 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
529
533
if (err )
530
534
goto out_cleanup ;
531
535
}
532
- err = ovl_instantiate (dentry , inode , newdentry , hardlink );
536
+ ovl_dir_modified (dentry -> d_parent , false);
537
+ err = ovl_instantiate (dentry , inode , newdentry , hardlink , NULL );
533
538
if (err ) {
534
539
ovl_cleanup (ofs , udir , newdentry );
535
540
dput (newdentry );
@@ -551,12 +556,35 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
551
556
goto out_dput ;
552
557
}
553
558
559
+ static int ovl_setup_cred_for_create (struct dentry * dentry , struct inode * inode ,
560
+ umode_t mode , const struct cred * old_cred )
561
+ {
562
+ int err ;
563
+ struct cred * override_cred ;
564
+
565
+ override_cred = prepare_creds ();
566
+ if (!override_cred )
567
+ return - ENOMEM ;
568
+
569
+ override_cred -> fsuid = inode -> i_uid ;
570
+ override_cred -> fsgid = inode -> i_gid ;
571
+ err = security_dentry_create_files_as (dentry , mode , & dentry -> d_name ,
572
+ old_cred , override_cred );
573
+ if (err ) {
574
+ put_cred (override_cred );
575
+ return err ;
576
+ }
577
+ put_cred (override_creds (override_cred ));
578
+ put_cred (override_cred );
579
+
580
+ return 0 ;
581
+ }
582
+
554
583
static int ovl_create_or_link (struct dentry * dentry , struct inode * inode ,
555
584
struct ovl_cattr * attr , bool origin )
556
585
{
557
586
int err ;
558
587
const struct cred * old_cred ;
559
- struct cred * override_cred ;
560
588
struct dentry * parent = dentry -> d_parent ;
561
589
562
590
old_cred = ovl_override_creds (dentry -> d_sb );
@@ -572,10 +600,6 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
572
600
}
573
601
574
602
if (!attr -> hardlink ) {
575
- err = - ENOMEM ;
576
- override_cred = prepare_creds ();
577
- if (!override_cred )
578
- goto out_revert_creds ;
579
603
/*
580
604
* In the creation cases(create, mkdir, mknod, symlink),
581
605
* ovl should transfer current's fs{u,g}id to underlying
@@ -589,17 +613,9 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
589
613
* create a new inode, so just use the ovl mounter's
590
614
* fs{u,g}id.
591
615
*/
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 );
616
+ err = ovl_setup_cred_for_create (dentry , inode , attr -> mode , old_cred );
617
+ if (err )
599
618
goto out_revert_creds ;
600
- }
601
- put_cred (override_creds (override_cred ));
602
- put_cred (override_cred );
603
619
}
604
620
605
621
if (!ovl_dentry_is_whiteout (dentry ))
@@ -1290,6 +1306,100 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir,
1290
1306
return err ;
1291
1307
}
1292
1308
1309
+ static int ovl_create_tmpfile (struct file * file , struct dentry * dentry ,
1310
+ struct inode * inode , umode_t mode )
1311
+ {
1312
+ const struct cred * old_cred ;
1313
+ struct path realparentpath ;
1314
+ struct file * realfile ;
1315
+ struct dentry * newdentry ;
1316
+ /* It's okay to set O_NOATIME, since the owner will be current fsuid */
1317
+ int flags = file -> f_flags | OVL_OPEN_FLAGS ;
1318
+ int err ;
1319
+
1320
+ err = ovl_copy_up (dentry -> d_parent );
1321
+ if (err )
1322
+ return err ;
1323
+
1324
+ old_cred = ovl_override_creds (dentry -> d_sb );
1325
+ err = ovl_setup_cred_for_create (dentry , inode , mode , old_cred );
1326
+ if (err )
1327
+ goto out_revert_creds ;
1328
+
1329
+ ovl_path_upper (dentry -> d_parent , & realparentpath );
1330
+ realfile = backing_tmpfile_open (& file -> f_path , flags , & realparentpath ,
1331
+ mode , current_cred ());
1332
+ err = PTR_ERR_OR_ZERO (realfile );
1333
+ pr_debug ("tmpfile/open(%pd2, 0%o) = %i\n" , realparentpath .dentry , mode , err );
1334
+ if (err )
1335
+ goto out_revert_creds ;
1336
+
1337
+ /* ovl_instantiate() consumes the newdentry reference on success */
1338
+ newdentry = dget (realfile -> f_path .dentry );
1339
+ err = ovl_instantiate (dentry , inode , newdentry , false, file );
1340
+ if (!err ) {
1341
+ file -> private_data = realfile ;
1342
+ } else {
1343
+ dput (newdentry );
1344
+ fput (realfile );
1345
+ }
1346
+ out_revert_creds :
1347
+ revert_creds (old_cred );
1348
+ return err ;
1349
+ }
1350
+
1351
+ static int ovl_dummy_open (struct inode * inode , struct file * file )
1352
+ {
1353
+ return 0 ;
1354
+ }
1355
+
1356
+ static int ovl_tmpfile (struct mnt_idmap * idmap , struct inode * dir ,
1357
+ struct file * file , umode_t mode )
1358
+ {
1359
+ int err ;
1360
+ struct dentry * dentry = file -> f_path .dentry ;
1361
+ struct inode * inode ;
1362
+
1363
+ if (!OVL_FS (dentry -> d_sb )-> tmpfile )
1364
+ return - EOPNOTSUPP ;
1365
+
1366
+ err = ovl_want_write (dentry );
1367
+ if (err )
1368
+ return err ;
1369
+
1370
+ err = - ENOMEM ;
1371
+ inode = ovl_new_inode (dentry -> d_sb , mode , 0 );
1372
+ if (!inode )
1373
+ goto drop_write ;
1374
+
1375
+ inode_init_owner (& nop_mnt_idmap , inode , dir , mode );
1376
+ err = ovl_create_tmpfile (file , dentry , inode , inode -> i_mode );
1377
+ if (err )
1378
+ goto put_inode ;
1379
+
1380
+ /*
1381
+ * Check if the preallocated inode was actually used. Having something
1382
+ * else assigned to the dentry shouldn't happen as that would indicate
1383
+ * that the backing tmpfile "leaked" out of overlayfs.
1384
+ */
1385
+ err = - EIO ;
1386
+ if (WARN_ON (inode != d_inode (dentry )))
1387
+ goto put_realfile ;
1388
+
1389
+ /* inode reference was transferred to dentry */
1390
+ inode = NULL ;
1391
+ err = finish_open (file , dentry , ovl_dummy_open );
1392
+ put_realfile :
1393
+ /* Without FMODE_OPENED ->release() won't be called on @file */
1394
+ if (!(file -> f_mode & FMODE_OPENED ))
1395
+ fput (file -> private_data );
1396
+ put_inode :
1397
+ iput (inode );
1398
+ drop_write :
1399
+ ovl_drop_write (dentry );
1400
+ return err ;
1401
+ }
1402
+
1293
1403
const struct inode_operations ovl_dir_inode_operations = {
1294
1404
.lookup = ovl_lookup ,
1295
1405
.mkdir = ovl_mkdir ,
@@ -1310,4 +1420,5 @@ const struct inode_operations ovl_dir_inode_operations = {
1310
1420
.update_time = ovl_update_time ,
1311
1421
.fileattr_get = ovl_fileattr_get ,
1312
1422
.fileattr_set = ovl_fileattr_set ,
1423
+ .tmpfile = ovl_tmpfile ,
1313
1424
};
0 commit comments