From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (mail.openvz.org [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id BC44D8045D for ; Mon, 26 Oct 2026 14:53:55 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69QEqgTo011924; Mon, 26 Oct 2026 17:52:43 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69QEqgTo011924 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="W8NGg2xw" Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69QEqTEe011890 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Mon, 26 Oct 2026 17:52:29 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69QEqTEe011890 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4a20a40d3e9so18930595e9.0 for ; Mon, 26 Oct 2026 07:52:29 -0700 (PDT) X-Forwarded-Encrypted: i=2; AKwUvBy72gTu1+qSIchGtmHbU1aziXsG9RUgHwHl0CNp10uNcBPLX4Hrg9dI2z7MsOm0wgzHgZyAdQ==@openvz.org X-Gm-Message-State: AFq9FYJmX3LENKYSYu1QBSAci1vSVcL5RTyCXlUowzaX44jOUU+rzsuo QwO/40jBqYELa0s6EtjvBbJlwmHYKB7PvOMCvvcO8Q07pyPXa/J5LFOuO6vwc87//nctfDKdZNx E+38Y9fT0fZPWrgNPIdsrxxq9IIUTtoTVth+nVpj2ejlH+aXne/Umtg== X-Gm-Gg: AYBFou1D4602WunJ1G+NQHEXK/4Zmd7gVxrqIpsvbAKicpmiX7KuFTEb+COpIHdIShn s3gHPBZwhmlghiQEkVC9tUVGCoPYrFR9GZTeOIE/RE0snHGQODFpBRekWszoVIXnTquXhXXkAOx xW0r9oJ3/YpyCi/GJqJ0J8HE7qq3i5z6MCtGjQs+8yWj5od5JK3no94Sm01l4W1Do1wiirWwZpM xf3nZJWD7vxBiBIRp0pFy7PUqkrsxzUZYst3maTviS5K/Uvk4ppTpUIRFtqMYi7Dr+lAwjGixhY Lt4Zod9ygsARMHcbnsUq+qBVvKxsl0nawgRNN4KtbB6RCFCGGtNtxigLh5KekeWliRwY0JF22tH t3YYIVhZUZGYIJ/1PLrZH9TfSAozQ X-Received: by 2002:a05:600c:4e87:b0:4a3:59c9:a758 with SMTP id 5b1f17b1804b1-4a35acb1cb7mr131660705e9.32.1793026349214; Mon, 26 Oct 2026 07:52:29 -0700 (PDT) X-Received: by 2002:a05:600c:4e87:b0:4a3:59c9:a758 with SMTP id 5b1f17b1804b1-4a35acb1cb7mr131660045e9.32.1793026348556; Mon, 26 Oct 2026 07:52:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1793026348; cv=none; d=google.com; s=arc-20260327; b=RKR7CPoVAYTi3NR+q1SiAIO9DMPjiK+Fc0xqP5Gnb5hMv14h3ZwZk6hbuA5jCxzWGl UJAEk5oIjrlEQ5PtYDEvh/4BX4tfSTPt8b5qYZo1qdG+yqkqh+iRRQBG37ytoZre4ITg RGvLpT4hOfazfgqq42blcJbZVkkOS5B/T9c+Eu9SxZwu/egahuWn36KTefVF9MeCeED1 0qSfnStBomOV3nV0kDMzN/eN4JusjJIH+C1rbmnkXmzXKPwd50uwnkvbDVBTfVbyz3vU SMl1LM4eEmxHiA31kfdpC0IvtSLKRsPYGyA1Jv8M8QDRgIKzAk5if640meg1f7OKxZvy sVYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=1GmkZgiMeBGzl5baT9y8wyQG6oYlRnbdx0TNIL6OWSc=; fh=cWfQ0WqBv1Pw7PhINIHK2v1yyoiscNQykPdEfpvTs1g=; b=mV/yvC4lei+itwCcEBAECfv7lWwkWQDnHeCviJc2Eul1cKbdKCj6S4DxLijAmBlw9z 5//QwrCCh7JfA4B+ibiErCu9iuEmw0nsGh9O4H5NgVBCoDNHv4KQHqpxdEX8KNfP0hik sJYKHG7TpdmkFqLv4Hk07P9oixLAuErAw0umgGuwYy1JHp2ib4OGBWgWvN0a3fLuAe21 MlwDAiQX1ix7xsP4zIvvyTpkIc7fdSdfiXe6yUzsxvTcPFqptG9ltji3tCVeWEsLAhZC /p9I9r+YITseASlwMxbH5uFlYYbUOFJZzPQni08TOMK1u43SDNwD5dX39dQLv87EhACE 37Xw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=W8NGg2xw; spf=pass (google.com: domain of vladimir.riabchun@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=vladimir.riabchun@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-48e3ece9b53si13859464f8f.209.2026.10.26.07.52.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2026 07:52:28 -0700 (PDT) Received-SPF: pass (google.com: domain of vladimir.riabchun@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=W8NGg2xw; spf=pass (google.com: domain of vladimir.riabchun@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=vladimir.riabchun@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=Message-Id:Content-Type:MIME-Version:Subject:Date :From; bh=1GmkZgiMeBGzl5baT9y8wyQG6oYlRnbdx0TNIL6OWSc=; b=W8NGg2xwtCkiaZGyAcG RwDFST3AUe2IxKLfTrL8TXBfMuQVmAyc9V32TEMnZbtiAoyj8uaEEx8WwiOmOgM04z5G8Q+kD/ZUD tytoAP/yvLVoE+F8w0nr1aLdpr1bhfk02QpPheOiT+jREOZn3kV0wZHRc/2W4YYjHeJvSdEEJocWS uO7Ux/76H4wkkqhDsis21rvcO5Ss13fDFh2mj/8mqSQbhFyemKrXF6TUSxrB2WXnNlLYfXiyg0Ryu nD8MhpZRgmltuMt/iVeyvWA421JngGzeZlGjb5ITtqiU0bO3MC3pMwpihnVgffyZhgiGddP7NYHq0 ZOTBKXYgD0Wv1Dw==; Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=192.168.1.87) by relay.virtuozzo.com with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1xLM04-004zLL-31; Mon, 26 Oct 2026 15:52:19 +0100 From: Vladimir Riabchun Date: Mon, 26 Oct 2026 15:52:23 +0100 MIME-Version: 1.0 Message-Id: <20261026-ovl-use-orig-ve-v2-4-eab58bfc29ca@virtuozzo.com> References: <20261026-ovl-use-orig-ve-v2-0-eab58bfc29ca@virtuozzo.com> In-Reply-To: <20261026-ovl-use-orig-ve-v2-0-eab58bfc29ca@virtuozzo.com> To: Konstantin Khorenko , ptikhomirov@virtuozzo.com, vasileios.almpanis@virtuozzo.com X-Mailer: b4 0.16.0 X-OZ-Fwd: true Cc: devel@openvz.org Subject: [Devel] [PATCH hci-8.1 v2 4/4] ve/overlayfs: Override VE together with creds X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org Host users might want to access overlayfs, owned by CT. In such case ve_capable checks will fail - they will perform VE cred checks against host user_ns. Modify ovl_override_creds so that it returns both old cred and old VE. This will also protect us from future rebase issues - all new users of old_cred and ovl_override_creds will fail with compilation error. This fixes an observed crash in overlayfs when checkpointing a container with a docker running inside: [ 2300.870181] BUG: kernel NULL pointer dereference, address: 0000000000000005 [ 2300.871537] #PF: supervisor read access in kernel mode [ 2300.872577] #PF: error_code(0x0000) - not-present page [ 2300.873595] PGD 800000010a18f067 P4D 800000010a18f067 PUD 10730c067 PMD 0 [ 2300.874900] Oops: Oops: 0000 [#1] SMP PTI [ 2300.875742] CPU: 1 UID: 0 PID: 5419 Comm: criu ve: 0 Kdump: loaded Not tainted 6.12.0-211.39.1.16.6.vz10.x86_64 #1 16.6 PREEMPT(voluntary) [ 2300.878057] Hardware name: Acronis OpenStack Compute/Virtuozzo, BIOS 1.16.1-1.vz9.2 04/01/2014 [ 2300.879684] RIP: 0010:ovl_get_index_name_fh+0x18/0x70 [overlay] [ 2300.880859] Code: ... [ 2300.884128] RSP: 0018:ffffd32582e0f7c0 EFLAGS: 00010246 [ 2300.885153] RAX: ... [ 2300.895807] Call Trace: [ 2300.896397] [ 2300.903298] ? ovl_get_index_name_fh+0x18/0x70 [overlay] [ 2300.904435] ovl_create_index+0x82/0x260 [overlay] [ 2300.905406] ovl_copy_up_workdir+0x30a/0x330 [overlay] [ 2300.906427] ovl_do_copy_up+0x10d/0x2e0 [overlay] [ 2300.907387] ovl_copy_up_one+0x456/0x720 [overlay] [ 2300.910736] ovl_copy_up_flags+0x81/0x110 [overlay] [ 2300.911740] ovl_create_object+0x51/0x130 [overlay] [ 2300.912719] vfs_mkdir+0x194/0x250 [ 2300.913470] do_mkdirat+0x14c/0x180 [ 2300.914223] __x64_sys_mkdir+0x46/0x70 [ 2300.915019] do_syscall_64+0x7d/0x160 [ 2300.922814] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2300.923823] RIP: 0033:0x7f5a2f8de3eb Overlayfs was created inside CT, so ovl_fill_super stored in-container credentials to ofs->creator_cred. Those creds were later used in ovl_override_creds to temporarily swich creds and perform checks using them. One of these checks happened in ovl_get_origin_fh/ovl_can_decode_fh. On fs creation this check passed because we had container VE and container creds, so overlayfs thought that we support file handles (ovl_can_decode_fh call in ovl_make_workdir). When we tried to do something with the overlayfs from host VE, ve_capable check was performed with credentials from CT and with host VE. ovl_get_origin_fh returned unexpected NULL and all exploded. Stroing ve_capable check result on creation is a possible fix, but it just masks the problem. We have other paths from overlay to ve_capable checks: ovl_fileattr_set ovl_override_creds ovl_real_fileattr_set vfs_fileattr_set fileattr_set_prepare ve_capable And storing capability check result will make rebase dangerous - we would have to track new added code - not funny. https://virtuozzo.atlassian.net/browse/VSTOR-142405 Signed-off-by: Vladimir Riabchun --- fs/overlayfs/copy_up.c | 4 ++-- fs/overlayfs/dir.c | 28 ++++++++++++++-------------- fs/overlayfs/file.c | 28 ++++++++++++++-------------- fs/overlayfs/inode.c | 38 +++++++++++++++++++------------------- fs/overlayfs/namei.c | 18 +++++++++--------- fs/overlayfs/overlayfs.h | 9 ++++++++- fs/overlayfs/readdir.c | 16 ++++++++-------- fs/overlayfs/util.c | 22 ++++++++++++++++------ fs/overlayfs/xattrs.c | 14 +++++++------- 9 files changed, 97 insertions(+), 80 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 4388004a319d..0b1270bc6d8d 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -1215,7 +1215,7 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, static int ovl_copy_up_flags(struct dentry *dentry, int flags) { int err = 0; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; bool disconnected = (dentry->d_flags & DCACHE_DISCONNECTED); /* @@ -1260,7 +1260,7 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags) dput(parent); dput(next); } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 1c8009bf194b..fe91fd4b04f0 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -554,7 +554,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, } static int ovl_setup_cred_for_create(struct dentry *dentry, struct inode *inode, - umode_t mode, const struct cred *old_cred) + umode_t mode, const struct ovl_creds_desc *old_cred) { int err; struct cred *override_cred; @@ -566,7 +566,7 @@ static int ovl_setup_cred_for_create(struct dentry *dentry, struct inode *inode, override_cred->fsuid = inode->i_uid; override_cred->fsgid = inode->i_gid; err = security_dentry_create_files_as(dentry, mode, &dentry->d_name, - old_cred, override_cred); + old_cred->cred, override_cred); if (err) { put_cred(override_cred); return err; @@ -581,7 +581,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, struct ovl_cattr *attr, bool origin) { int err; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct dentry *parent = dentry->d_parent; old_cred = ovl_override_creds(dentry->d_sb); @@ -610,7 +610,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, * create a new inode, so just use the ovl mounter's * fs{u,g}id. */ - err = ovl_setup_cred_for_create(dentry, inode, attr->mode, old_cred); + err = ovl_setup_cred_for_create(dentry, inode, attr->mode, &old_cred); if (err) goto out_revert_creds; } @@ -621,7 +621,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, err = ovl_create_over_whiteout(dentry, inode, attr); out_revert_creds: - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -697,12 +697,12 @@ static int ovl_symlink(struct mnt_idmap *idmap, struct inode *dir, static int ovl_set_link_redirect(struct dentry *dentry) { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; old_cred = ovl_override_creds(dentry->d_sb); err = ovl_set_redirect(dentry, false); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -888,7 +888,7 @@ static void ovl_drop_nlink(struct dentry *dentry) static int ovl_do_remove(struct dentry *dentry, bool is_dir) { int err; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; bool lower_positive = ovl_lower_positive(dentry); LIST_HEAD(list); @@ -912,7 +912,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) err = ovl_remove_upper(dentry, is_dir, &list); else err = ovl_remove_and_whiteout(dentry, &list); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (!err) { if (is_dir) clear_nlink(dentry->d_inode); @@ -1095,7 +1095,7 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir, bool new_is_dir = d_is_dir(new); bool samedir = olddir == newdir; struct dentry *opaquedir = NULL; - const struct cred *old_cred = NULL; + struct ovl_creds_desc old_cred = {}; struct ovl_fs *ofs = OVL_FS(old->d_sb); LIST_HEAD(list); @@ -1292,7 +1292,7 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir, out_unlock: unlock_rename(new_upperdir, old_upperdir); out_revert_creds: - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (update_nlink) ovl_nlink_end(new); else @@ -1306,7 +1306,7 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir, static int ovl_create_tmpfile(struct file *file, struct dentry *dentry, struct inode *inode, umode_t mode) { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct path realparentpath; struct file *realfile; struct dentry *newdentry; @@ -1315,7 +1315,7 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry, int err; old_cred = ovl_override_creds(dentry->d_sb); - err = ovl_setup_cred_for_create(dentry, inode, mode, old_cred); + err = ovl_setup_cred_for_create(dentry, inode, mode, &old_cred); if (err) goto out_revert_creds; @@ -1337,7 +1337,7 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry, fput(realfile); } out_revert_creds: - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 84aad9d19bdd..55b4589e895a 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -31,7 +31,7 @@ static struct file *ovl_open_realfile(const struct file *file, struct inode *inode = file_inode(file); struct mnt_idmap *real_idmap; struct file *realfile; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int flags = file->f_flags | OVL_OPEN_FLAGS; int acc_mode = ACC_MODE(flags); int err; @@ -51,7 +51,7 @@ static struct file *ovl_open_realfile(const struct file *file, realfile = backing_file_open(file, flags, realpath, current_cred()); } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n", file, file, ovl_whatisit(inode, realinode), file->f_flags, @@ -184,7 +184,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) { struct inode *inode = file_inode(file); struct fd real; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; loff_t ret; /* @@ -215,7 +215,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) old_cred = ovl_override_creds(inode->i_sb); ret = vfs_llseek(fd_file(real), offset, whence); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); file->f_pos = fd_file(real)->f_pos; ovl_inode_unlock(inode); @@ -392,7 +392,7 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out, static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct fd real; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int ret; ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); @@ -407,7 +407,7 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) if (file_inode(fd_file(real)) == ovl_inode_upper(file_inode(file))) { old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fsync_range(fd_file(real), start, end, datasync); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); } fdput(real); @@ -431,7 +431,7 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len { struct inode *inode = file_inode(file); struct fd real; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int ret; inode_lock(inode); @@ -447,7 +447,7 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fallocate(fd_file(real), mode, offset, len); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); /* Update size */ ovl_file_modified(file); @@ -463,7 +463,7 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice) { struct fd real; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int ret; ret = ovl_real_fdget(file, &real); @@ -472,7 +472,7 @@ static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice) old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fadvise(fd_file(real), offset, len, advice); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); fdput(real); @@ -491,7 +491,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, { struct inode *inode_out = file_inode(file_out); struct fd real_in, real_out; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; loff_t ret; inode_lock(inode_out); @@ -531,7 +531,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, flags); break; } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); /* Update size */ ovl_file_modified(file_out); @@ -583,7 +583,7 @@ static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in, static int ovl_flush(struct file *file, fl_owner_t id) { struct fd real; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; err = ovl_real_fdget(file, &real); @@ -593,7 +593,7 @@ static int ovl_flush(struct file *file, fl_owner_t id) if (fd_file(real)->f_op->flush) { old_cred = ovl_override_creds(file_inode(file)->i_sb); err = fd_file(real)->f_op->flush(fd_file(real), id); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); } fdput(real); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 8b31f44c12cd..6a8d35e8c14a 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -25,7 +25,7 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct ovl_fs *ofs = OVL_FS(dentry->d_sb); bool full_copy_up = false; struct dentry *upperdentry; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; err = setattr_prepare(&nop_mnt_idmap, dentry, attr); if (err) @@ -80,7 +80,7 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, inode_lock(upperdentry->d_inode); old_cred = ovl_override_creds(dentry->d_sb); err = ovl_do_notify_change(ofs, upperdentry, attr); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (!err) ovl_copyattr(dentry->d_inode); inode_unlock(upperdentry->d_inode); @@ -159,7 +159,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, struct dentry *dentry = path->dentry; enum ovl_path_type type; struct path realpath; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct inode *inode = d_inode(dentry); bool is_dir = S_ISDIR(inode->i_mode); int fsid = 0; @@ -280,7 +280,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, stat->nlink = dentry->d_inode->i_nlink; out: - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -291,7 +291,7 @@ int ovl_permission(struct mnt_idmap *idmap, struct inode *upperinode = ovl_inode_upper(inode); struct inode *realinode; struct path realpath; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; /* Careful in RCU walk mode */ @@ -317,7 +317,7 @@ int ovl_permission(struct mnt_idmap *idmap, mask |= MAY_READ; } err = inode_permission(mnt_idmap(realpath.mnt), realinode, mask); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -326,7 +326,7 @@ static const char *ovl_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; const char *p; if (!dentry) @@ -334,7 +334,7 @@ static const char *ovl_get_link(struct dentry *dentry, old_cred = ovl_override_creds(dentry->d_sb); p = vfs_get_link(ovl_dentry_real(dentry), done); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return p; } @@ -465,11 +465,11 @@ struct posix_acl *do_ovl_get_acl(struct mnt_idmap *idmap, acl = get_cached_acl_rcu(realinode, type); } else { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(inode->i_sb); acl = ovl_get_acl_path(&realpath, posix_acl_xattr_name(type), noperm); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); } return acl; @@ -481,7 +481,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, int err; struct path realpath; const char *acl_name; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct ovl_fs *ofs = OVL_FS(dentry->d_sb); struct dentry *upperdentry = ovl_dentry_upper(dentry); struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); @@ -498,7 +498,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, old_cred = ovl_override_creds(dentry->d_sb); real_acl = vfs_get_acl(mnt_idmap(realpath.mnt), realdentry, acl_name); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (IS_ERR(real_acl)) { err = PTR_ERR(real_acl); goto out; @@ -523,7 +523,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, err = ovl_do_set_acl(ofs, realdentry, acl_name, acl); else err = ovl_do_remove_acl(ofs, realdentry, acl_name); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); ovl_drop_write(dentry); /* copy c/mtime */ @@ -590,7 +590,7 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, { int err; struct inode *realinode = ovl_inode_realdata(inode); - const struct cred *old_cred; + struct ovl_creds_desc old_cred; if (!realinode) return -EIO; @@ -600,7 +600,7 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, old_cred = ovl_override_creds(inode->i_sb); err = realinode->i_op->fiemap(realinode, fieinfo, start, len); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -648,7 +648,7 @@ int ovl_fileattr_set(struct mnt_idmap *idmap, { struct inode *inode = d_inode(dentry); struct path upperpath; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; unsigned int flags; int err; @@ -671,7 +671,7 @@ int ovl_fileattr_set(struct mnt_idmap *idmap, err = ovl_set_protattr(inode, upperpath.dentry, fa); if (!err) err = ovl_real_fileattr_set(&upperpath, fa); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); ovl_drop_write(dentry); /* @@ -725,7 +725,7 @@ int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); struct path realpath; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; ovl_path_real(dentry, &realpath); @@ -733,7 +733,7 @@ int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa) old_cred = ovl_override_creds(inode->i_sb); err = ovl_real_fileattr_get(&realpath, fa); ovl_fileattr_prot_flags(inode, fa); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index efa2a072aa69..6af0712fcb83 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -969,7 +969,7 @@ static int ovl_maybe_validate_verity(struct dentry *dentry) return err; if (!ovl_test_flag(OVL_VERIFIED_DIGEST, inode)) { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(dentry->d_sb); @@ -977,7 +977,7 @@ static int ovl_maybe_validate_verity(struct dentry *dentry) if (err == 0) ovl_set_flag(OVL_VERIFIED_DIGEST, inode); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); } ovl_inode_unlock(inode); @@ -991,7 +991,7 @@ static int ovl_maybe_lookup_lowerdata(struct dentry *dentry) struct inode *inode = d_inode(dentry); const char *redirect = ovl_lowerdata_redirect(inode); struct ovl_path datapath = {}; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; if (!redirect || ovl_dentry_lowerdata(dentry)) @@ -1011,7 +1011,7 @@ static int ovl_maybe_lookup_lowerdata(struct dentry *dentry) old_cred = ovl_override_creds(dentry->d_sb); err = ovl_lookup_data_layers(dentry, redirect, &datapath); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (err) goto out_err; @@ -1071,7 +1071,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { struct ovl_entry *oe = NULL; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct ovl_fs *ofs = OVL_FS(dentry->d_sb); struct ovl_entry *poe = OVL_E(dentry->d_parent); struct ovl_entry *roe = OVL_E(dentry->d_sb->s_root); @@ -1378,7 +1378,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_dentry_init_reval(dentry, upperdentry, OVL_I_E(inode)); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (origin_path) { dput(origin_path->dentry); kfree(origin_path); @@ -1402,7 +1402,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, kfree(d.upperredirect); out: kfree(d.redirect); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return ERR_PTR(err); } @@ -1410,7 +1410,7 @@ bool ovl_lower_positive(struct dentry *dentry) { struct ovl_entry *poe = OVL_E(dentry->d_parent); const struct qstr *name = &dentry->d_name; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; unsigned int i; bool positive = false; bool done = false; @@ -1459,7 +1459,7 @@ bool ovl_lower_positive(struct dentry *dentry) dput(this); } } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return positive; } diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 8577c7884fb9..eb2fb473a64b 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -164,6 +164,12 @@ struct ovl_metacopy { u8 digest[FS_VERITY_MAX_DIGEST_SIZE]; /* Only the used part on disk */ } __packed; +/* Credential information used by overlay */ +struct ovl_creds_desc { + const struct cred *cred; + struct ve_struct *ve; +}; + #define OVL_METACOPY_MAX_SIZE (sizeof(struct ovl_metacopy)) #define OVL_METACOPY_MIN_SIZE (OVL_METACOPY_MAX_SIZE - FS_VERITY_MAX_DIGEST_SIZE) #define OVL_METACOPY_INIT { 0, OVL_METACOPY_MIN_SIZE } @@ -420,7 +426,8 @@ void ovl_end_write(struct dentry *dentry); int ovl_want_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry); struct dentry *ovl_workdir(struct dentry *dentry); -const struct cred *ovl_override_creds(struct super_block *sb); +struct ovl_creds_desc ovl_override_creds(struct super_block *sb); +void ovl_revert_creds(struct ovl_creds_desc *old_creds); static inline const struct cred *ovl_creds(struct super_block *sb) { diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 0ca8af060b0c..aca2dd6d4e2f 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -273,7 +273,7 @@ static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data int err; struct ovl_cache_entry *p; struct dentry *dentry, *dir = path->dentry; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(rdd->dentry->d_sb); @@ -290,7 +290,7 @@ static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data } inode_unlock(dir->d_inode); } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -753,7 +753,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) struct dentry *dentry = file->f_path.dentry; struct ovl_fs *ofs = OVL_FS(dentry->d_sb); struct ovl_cache_entry *p; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; old_cred = ovl_override_creds(dentry->d_sb); @@ -808,7 +808,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) } err = 0; out: - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return err; } @@ -856,11 +856,11 @@ static struct file *ovl_dir_open_realfile(const struct file *file, const struct path *realpath) { struct file *res; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(file_inode(file)->i_sb); res = ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE)); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return res; } @@ -983,11 +983,11 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) int err; struct ovl_cache_entry *p, *n; struct rb_root root = RB_ROOT; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(dentry->d_sb); err = ovl_dir_read_merged(dentry, list, &root); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (err) return err; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index f95090f0d29c..e3cbdf7259d1 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -63,11 +63,21 @@ struct dentry *ovl_workdir(struct dentry *dentry) return ofs->workdir; } -const struct cred *ovl_override_creds(struct super_block *sb) +struct ovl_creds_desc ovl_override_creds(struct super_block *sb) { struct ovl_fs *ofs = OVL_FS(sb); + struct ovl_creds_desc desc; - return override_creds(ofs->creator_cred); + desc.cred = override_creds(ofs->creator_cred); + desc.ve = override_ve(ofs->creator_ve); + + return desc; +} + +void ovl_revert_creds(struct ovl_creds_desc *old_creds) +{ + revert_ve(old_creds->ve); + revert_creds(old_creds->cred); } /* @@ -1150,7 +1160,7 @@ static void ovl_cleanup_index(struct dentry *dentry) int ovl_nlink_start(struct dentry *dentry) { struct inode *inode = d_inode(dentry); - const struct cred *old_cred; + struct ovl_creds_desc old_cred; int err; if (WARN_ON(!inode)) @@ -1195,7 +1205,7 @@ int ovl_nlink_start(struct dentry *dentry) * value relative to the upper inode nlink in an upper inode xattr. */ err = ovl_set_nlink_upper(dentry); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (err) goto out_drop_write; @@ -1216,11 +1226,11 @@ void ovl_nlink_end(struct dentry *dentry) ovl_drop_write(dentry); if (ovl_test_flag(OVL_INDEX, inode) && inode->i_nlink == 0) { - const struct cred *old_cred; + struct ovl_creds_desc old_cred; old_cred = ovl_override_creds(dentry->d_sb); ovl_cleanup_index(dentry); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); } ovl_inode_unlock(inode); diff --git a/fs/overlayfs/xattrs.c b/fs/overlayfs/xattrs.c index 0ed2b049056d..0bd5835061fb 100644 --- a/fs/overlayfs/xattrs.c +++ b/fs/overlayfs/xattrs.c @@ -41,13 +41,13 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char struct dentry *upperdentry = ovl_i_dentry_upper(inode); struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); struct path realpath; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; if (!value && !upperdentry) { ovl_path_lower(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (err < 0) goto out; } @@ -72,7 +72,7 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char WARN_ON(flags != XATTR_REPLACE); err = ovl_do_removexattr(ofs, realdentry, name); } - revert_creds(old_cred); + ovl_revert_creds(&old_cred); ovl_drop_write(dentry); /* copy c/mtime */ @@ -85,13 +85,13 @@ static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char void *value, size_t size) { ssize_t res; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; struct path realpath; ovl_i_path_real(inode, &realpath); old_cred = ovl_override_creds(dentry->d_sb); res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); return res; } @@ -116,12 +116,12 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) ssize_t res; size_t len; char *s; - const struct cred *old_cred; + struct ovl_creds_desc old_cred; size_t prefix_len, name_len; old_cred = ovl_override_creds(dentry->d_sb); res = vfs_listxattr(realdentry, list, size); - revert_creds(old_cred); + ovl_revert_creds(&old_cred); if (res <= 0 || size == 0) return res; -- 2.52.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel