Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull overlayfs fixes from Miklos Szeredi:
"This contains a fix for a potential crash/corruption issue and another
where the suid/sgid bits weren't cleared on write"

* 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
ovl: verify upper dentry in ovl_remove_and_whiteout()
ovl: Copy up underlying inode's ->i_mode to overlay inode
ovl: handle ATTR_KILL*

+29 -32
+24 -30
fs/overlayfs/dir.c
··· 505 505 struct dentry *upper; 506 506 struct dentry *opaquedir = NULL; 507 507 int err; 508 + int flags = 0; 508 509 509 510 if (WARN_ON(!workdir)) 510 511 return -EROFS; ··· 535 534 if (err) 536 535 goto out_dput; 537 536 537 + upper = lookup_one_len(dentry->d_name.name, upperdir, 538 + dentry->d_name.len); 539 + err = PTR_ERR(upper); 540 + if (IS_ERR(upper)) 541 + goto out_unlock; 542 + 543 + err = -ESTALE; 544 + if ((opaquedir && upper != opaquedir) || 545 + (!opaquedir && ovl_dentry_upper(dentry) && 546 + upper != ovl_dentry_upper(dentry))) { 547 + goto out_dput_upper; 548 + } 549 + 538 550 whiteout = ovl_whiteout(workdir, dentry); 539 551 err = PTR_ERR(whiteout); 540 552 if (IS_ERR(whiteout)) 541 - goto out_unlock; 553 + goto out_dput_upper; 542 554 543 - upper = ovl_dentry_upper(dentry); 544 - if (!upper) { 545 - upper = lookup_one_len(dentry->d_name.name, upperdir, 546 - dentry->d_name.len); 547 - err = PTR_ERR(upper); 548 - if (IS_ERR(upper)) 549 - goto kill_whiteout; 555 + if (d_is_dir(upper)) 556 + flags = RENAME_EXCHANGE; 550 557 551 - err = ovl_do_rename(wdir, whiteout, udir, upper, 0); 552 - dput(upper); 553 - if (err) 554 - goto kill_whiteout; 555 - } else { 556 - int flags = 0; 558 + err = ovl_do_rename(wdir, whiteout, udir, upper, flags); 559 + if (err) 560 + goto kill_whiteout; 561 + if (flags) 562 + ovl_cleanup(wdir, upper); 557 563 558 - if (opaquedir) 559 - upper = opaquedir; 560 - err = -ESTALE; 561 - if (upper->d_parent != upperdir) 562 - goto kill_whiteout; 563 - 564 - if (is_dir) 565 - flags |= RENAME_EXCHANGE; 566 - 567 - err = ovl_do_rename(wdir, whiteout, udir, upper, flags); 568 - if (err) 569 - goto kill_whiteout; 570 - 571 - if (is_dir) 572 - ovl_cleanup(wdir, upper); 573 - } 574 564 ovl_dentry_version_inc(dentry->d_parent); 575 565 out_d_drop: 576 566 d_drop(dentry); 577 567 dput(whiteout); 568 + out_dput_upper: 569 + dput(upper); 578 570 out_unlock: 579 571 unlock_rename(workdir, upperdir); 580 572 out_dput:
+4 -2
fs/overlayfs/inode.c
··· 80 80 goto out_drop_write; 81 81 } 82 82 83 + if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) 84 + attr->ia_valid &= ~ATTR_MODE; 85 + 83 86 inode_lock(upperdentry->d_inode); 84 87 err = notify_change(upperdentry, attr, NULL); 85 88 if (!err) ··· 413 410 if (!inode) 414 411 return NULL; 415 412 416 - mode &= S_IFMT; 417 - 418 413 inode->i_ino = get_next_ino(); 419 414 inode->i_mode = mode; 420 415 inode->i_flags |= S_NOATIME | S_NOCMTIME; 421 416 417 + mode &= S_IFMT; 422 418 switch (mode) { 423 419 case S_IFDIR: 424 420 inode->i_private = oe;
+1
fs/overlayfs/overlayfs.h
··· 187 187 { 188 188 to->i_uid = from->i_uid; 189 189 to->i_gid = from->i_gid; 190 + to->i_mode = from->i_mode; 190 191 } 191 192 192 193 /* dir.c */