From patchwork Wed Oct 2 01:22:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819166 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8444944E; Wed, 2 Oct 2024 01:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; cv=none; b=URXYo8SN3aghsR4sYule38S/o+6hYd9nudKmnTeqaTCvAsLgsJEObZVGWpy1essWqpx1po7fpLuWDF6F5qwTCqCkMzEorXBtlpusCKA3AikXZbgIB9TLC5KExrkbzWQgwlfWlO8wtHrb7gSRZAZ65Ygyyuh1M8uZFUV1Ut7gXlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; c=relaxed/simple; bh=4oy05+QC+QtHw8UXpK8yWCleR38ElzdTZCWh3lDpUzQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CRzO/cuQOrEewrI4FEQiLukNYRW6cZ0uW/IclFZf2Ca4fY3AYurCq8UaI+C6fGUaGrBZo2QZOYWKwW88YaJrYFO1TiHCF1zj7JzSlYPZKnXOVQIdGDvfyMhPWiI/ioS3gukPsXJYpUOMeOWIwPRSOG3IHvvKu5kr9g15C2gSRpE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=rNmFDG91; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="rNmFDG91" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=YIq7cR2J9S1CfidyrsAypk2OC0OslepJ1WnLnG0MFcA=; b=rNmFDG916VQUMfWcmAxpk/WA7a QKrFTFaUhnBOkHf+VYZ+t1W4dngs55fvs1oPzetYU1H/LgvhCM7EP+j+9tt1SZ/vr3rkt1Gr6TZyQ RxrZ8ugS4FpJY8dvPt3B6iAj+ot2LGZB1CYXcFhYj3r7EAzIuQY6m+VA1n36wCwRmT+toVA5pCLgd AbJp00m/DXnepyh8jt42r9V06LFg10kEJ0lelJZ445jhq1XmDytphoACurAycnaPG2DOxPeeHcWI+ 5zquM+Pi0IsIUUvaYjCwEB3eHDjTOupJ19/fHlKq9wbCbpAD1cElS1yg9ZfRw8x3BWfYBfZ7UVHUi Gu8GGN3Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW09-18Fd; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 1/9] xattr: switch to CLASS(fd) Date: Wed, 2 Oct 2024 02:22:22 +0100 Message-ID: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002011011.GB4017910@ZenIV> References: <20241002011011.GB4017910@ZenIV> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/xattr.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 05ec7e7d9e87..0fc813cb005c 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -697,9 +697,9 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, int error; CLASS(fd, f)(fd); - if (!fd_file(f)) - return -EBADF; + if (fd_empty(f)) + return -EBADF; audit_file(fd_file(f)); error = setxattr_copy(name, &ctx); if (error) @@ -809,16 +809,13 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size) { - struct fd f = fdget(fd); - ssize_t error = -EBADF; + CLASS(fd, f)(fd); - if (!fd_file(f)) - return error; + if (fd_empty(f)) + return -EBADF; audit_file(fd_file(f)); - error = getxattr(file_mnt_idmap(fd_file(f)), fd_file(f)->f_path.dentry, + return getxattr(file_mnt_idmap(fd_file(f)), fd_file(f)->f_path.dentry, name, value, size); - fdput(f); - return error; } /* @@ -885,15 +882,12 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) { - struct fd f = fdget(fd); - ssize_t error = -EBADF; + CLASS(fd, f)(fd); - if (!fd_file(f)) - return error; + if (fd_empty(f)) + return -EBADF; audit_file(fd_file(f)); - error = listxattr(fd_file(f)->f_path.dentry, list, size); - fdput(f); - return error; + return listxattr(fd_file(f)->f_path.dentry, list, size); } /* @@ -950,12 +944,12 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { - struct fd f = fdget(fd); + CLASS(fd, f)(fd); char kname[XATTR_NAME_MAX + 1]; - int error = -EBADF; + int error; - if (!fd_file(f)) - return error; + if (fd_empty(f)) + return -EBADF; audit_file(fd_file(f)); error = strncpy_from_user(kname, name, sizeof(kname)); @@ -970,7 +964,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) fd_file(f)->f_path.dentry, kname); mnt_drop_write_file(fd_file(f)); } - fdput(f); return error; } From patchwork Wed Oct 2 01:22:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819165 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C84729450; Wed, 2 Oct 2024 01:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; cv=none; b=bxHag7TB27c6mr0JnAhk5G1uA/RFAvQpI4tu9cL2UZP+aw6b2RQz645Sg3o7/ISag3Qf2UZxWlr3mg+n40yAd9a2tYK3sS0pMFDGNflabU00hKV/G1gS65Yfzg7z3bkda3fWG8DMYCtmS1v/fe5D3yuoYhaYYWQJs1skQmocloE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; c=relaxed/simple; bh=f88IB4PTDKAV6GtuYOuya4kyGV9E9/vovooueg0ZoLM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SISslf/oINiDX3Ks6rcUCfdgtA63khmLkMoqp51hetJkjzwiURy9yuuDyFjMkG5NpZttcndkx5fHAmoRAEGSgyiZTJL70vaM/CkOAkfBtqwA4PT+jtaV/iZ5XFFzDALLwahzY09BZwkJhEAtk14Tenk+i/q4n4zqkjvAti0rPwk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=ch0X0zpb; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="ch0X0zpb" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=pkYbQ6A2E8yrKld2874J/quEWv8Girhvo1LfyLaZNPg=; b=ch0X0zpblgb/GayVafec7IRzPa 6RoPMifBXUgBg+kfqfESAQcAonG7vuiOzFn9SY/vdq4e4qcT9z/SMRgkY0a+wJqZIBOlsWHFmwnsU cjM8+dyXtevVgMLU8/pGcKhd2J6GtEY9NyOCgd4QVj6kNMXKfNPkVwVA9Cud/YGwAJcElaa4ZRvpv fD2c7S5IJcZtwwkzQ4t2DY2HXc8ouFuB8I77QSnZlQxLlqlHIBEtOwBRGg8HjFcqXVicNmEuFTe91 hKzbTFHvRwNcICC171O6OXC6UHoPVSTVjXNM7ctIFKXf/q3GOrbuRegHn80gjGiNLgHQ3PurkkOC+ byINkQKw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0B-1ST7; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 2/9] fs: rename struct xattr_ctx to kernel_xattr_ctx Date: Wed, 2 Oct 2024 02:22:23 +0100 Message-ID: <20241002012230.4174585-2-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro From: Christian Göttsche Rename the struct xattr_ctx to increase distinction with the about to be added user API struct xattr_args. No functional change. Suggested-by: Christian Brauner Signed-off-by: Christian Göttsche Link: https://lore.kernel.org/r/20240426162042.191916-2-cgoettsche@seltendoof.de Reviewed-by: Jan Kara Signed-off-by: Christian Brauner Reviewed-by: Christian Brauner --- fs/internal.h | 8 ++++---- fs/xattr.c | 12 ++++++------ io_uring/xattr.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 8c1b7acbbe8f..81c7a085355c 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -267,7 +267,7 @@ struct xattr_name { char name[XATTR_NAME_MAX + 1]; }; -struct xattr_ctx { +struct kernel_xattr_ctx { /* Value of attribute */ union { const void __user *cvalue; @@ -283,11 +283,11 @@ struct xattr_ctx { ssize_t do_getxattr(struct mnt_idmap *idmap, struct dentry *d, - struct xattr_ctx *ctx); + struct kernel_xattr_ctx *ctx); -int setxattr_copy(const char __user *name, struct xattr_ctx *ctx); +int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx); int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, - struct xattr_ctx *ctx); + struct kernel_xattr_ctx *ctx); int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode); #ifdef CONFIG_FS_POSIX_ACL diff --git a/fs/xattr.c b/fs/xattr.c index 0fc813cb005c..1214ae7e71db 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); * Extended attribute SET operations */ -int setxattr_copy(const char __user *name, struct xattr_ctx *ctx) +int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx) { int error; @@ -620,7 +620,7 @@ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx) } int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, - struct xattr_ctx *ctx) + struct kernel_xattr_ctx *ctx) { if (is_posix_acl_xattr(ctx->kname->name)) return do_set_acl(idmap, dentry, ctx->kname->name, @@ -635,7 +635,7 @@ static int path_setxattr(const char __user *pathname, size_t size, int flags, unsigned int lookup_flags) { struct xattr_name kname; - struct xattr_ctx ctx = { + struct kernel_xattr_ctx ctx = { .cvalue = value, .kvalue = NULL, .size = size, @@ -687,7 +687,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, const void __user *,value, size_t, size, int, flags) { struct xattr_name kname; - struct xattr_ctx ctx = { + struct kernel_xattr_ctx ctx = { .cvalue = value, .kvalue = NULL, .size = size, @@ -720,7 +720,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, */ ssize_t do_getxattr(struct mnt_idmap *idmap, struct dentry *d, - struct xattr_ctx *ctx) + struct kernel_xattr_ctx *ctx) { ssize_t error; char *kname = ctx->kname->name; @@ -755,7 +755,7 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d, { ssize_t error; struct xattr_name kname; - struct xattr_ctx ctx = { + struct kernel_xattr_ctx ctx = { .value = value, .kvalue = NULL, .size = size, diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 6cf41c3bc369..5b4594ede935 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -18,7 +18,7 @@ struct io_xattr { struct file *file; - struct xattr_ctx ctx; + struct kernel_xattr_ctx ctx; struct filename *filename; }; From patchwork Wed Oct 2 01:22:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819162 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBAF79454; Wed, 2 Oct 2024 01:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832153; cv=none; b=Tosu8rNIv9dlsIHp8g1vzGPnu7MWnN11wggexI4Dng9avtJTR2CBbB6B3eirEPu0u25CEO/JgRqnvPU+Jk0jDGWqi/WLECP7/2Sf7oatklAK4hZVupvoMBDGrQPBBfrDn2ENcAZIwZ3mhjsWpvEEIeC7yX2FGeLvE1OVZ4Ff2ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832153; c=relaxed/simple; bh=gStnpPyvw9dmCFt/+rNPkZRYWlrAfXwW2VfkGt+hHSA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k5BYCRfhol908NEz2gnAwk/wvagRTnXLeX2tB4PCsAJ/fyGQjclhne6bTbuojah13xFBV4Wtw+grLhbKyEXtcU3nGzdO0twZv5+XB1cm8Ef1hE0bEy5xdPnLTdSgFtUIQwUCT+h39prqDiMynXUJ/A4TeuFhvaxCVRshlrFQ4TA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=heROSkdP; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="heROSkdP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=ZRmhc+N4gRJDAvuKVshJF7vx2/FasZk6WdJnNtu+PX8=; b=heROSkdPtzw9/Gb8QZBf2daWIy y3ysFyd0EWZyRRv5sF+kIa8PeDidFLIyGBQ5OA+BmfVzs/xP9YquN5SaR5R7tSfw0U9I72fbkITSL Vw3UN2uuoCuN1wHpvO++JDZx9dbhB2ZLh8kjytD7qzhRwO8IOIUv7CChQ0y4BgODCIoQ/rOjdo2VF /Ad6RqKjn3gASqZDHBMAZ6ErOydewh7Z74kxhlXrwTPwB/gkrHNNHo+hWlE7L3IyogeypCMtp086Q +cKV8ajE5jLavxQgozzJ4dRE/LcE7FxS+GCF7N4DlnhUsbvRHlkABDQstM3DCXK09FDCObr4tQsu1 ZuUpgGsQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0D-1krp; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 3/9] io_[gs]etxattr_prep(): just use getname() Date: Wed, 2 Oct 2024 02:22:24 +0100 Message-ID: <20241002012230.4174585-3-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro getname_flags(pathname, LOOKUP_FOLLOW) is obviously bogus - following trailing symlinks has no impact on how to copy the pathname from userland... Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- io_uring/xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 5b4594ede935..04abf0739668 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -96,7 +96,7 @@ int io_getxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) path = u64_to_user_ptr(READ_ONCE(sqe->addr3)); - ix->filename = getname_flags(path, LOOKUP_FOLLOW); + ix->filename = getname(path); if (IS_ERR(ix->filename)) { ret = PTR_ERR(ix->filename); ix->filename = NULL; @@ -189,7 +189,7 @@ int io_setxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) path = u64_to_user_ptr(READ_ONCE(sqe->addr3)); - ix->filename = getname_flags(path, LOOKUP_FOLLOW); + ix->filename = getname(path); if (IS_ERR(ix->filename)) { ret = PTR_ERR(ix->filename); ix->filename = NULL; From patchwork Wed Oct 2 01:22:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819163 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 140B69473; Wed, 2 Oct 2024 01:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832153; cv=none; b=Kt7c9jCmwq9xzb5FBvoyCRYqyrqJm/Wb/qgfWyqMi/waB2r7KfXSD8n7yNrwSYmk/pPaGFP6fLVHGi4nmFuuWw7kRFij4wDvjqokOPKJ2gP3vmEr4K5F0XkVvBxSh2FXF6XQmcw3EHVaatHM894gmG5P4QM7l+Inv15kEqV28IY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832153; c=relaxed/simple; bh=6hj6ON21ofjjrr4/UOKvjRRIfFsvmigcJlYXQoJvTDI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qoHC2XIH3ph6IS+xj6Bd7cKECsuygGGgHuXj+TDSblgyPNItDy9HHAJZWj8PobSV2Or3rVL2bUhHnUGNww2PD16SexwXyVpJ9KHBHai9HOcnykJRMeAuuMer4PfSuwgY/GCVrJR/3xM6lDYZBEwa0oQ/DdjeOc1nLa98ogqo+D8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=lepJrpI/; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="lepJrpI/" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=jFUq21m1sQJr6SiaClIO+hP/wJwmB67aDC/vU2ShIh4=; b=lepJrpI/M0lmoQvOPyEl63MJSQ T5L31R3D3dOTjWanQ7ZKvGvSux3xdsA1uzet2AnNrTInMfuHQfSzLr/WAPewfRsoEYMTI0/6+wW87 9+2MRsYBye0B9JRUdi3G82o1S9RZtZI+SpyoGfuo/VT5uwsNuA8eu+sMyTsp1ZmIAKmB++/vBFbd6 R73eM0Q0YPoXfy+76I1LClOKjsJFO+6h93xGf+ij144oxALTle5ToZ0Xkd/RM86XbSlMkwlBSgcZc Hh9RPrTgETfRmWL9LML0jTIoC3K+cdCFqL2F+vXuiTrorNC63IFiVlixjNWZQ7sRuvRoG8ZDfrl82 1f3p0uQw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0F-24Xk; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 4/9] new helper: import_xattr_name() Date: Wed, 2 Oct 2024 02:22:25 +0100 Message-ID: <20241002012230.4174585-4-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro common logics for marshalling xattr names. Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/internal.h | 3 +++ fs/xattr.c | 45 +++++++++++++++++++++++---------------------- io_uring/xattr.c | 7 ++----- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 81c7a085355c..b9f5ac4d39fc 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -288,6 +288,9 @@ ssize_t do_getxattr(struct mnt_idmap *idmap, int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx); int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, struct kernel_xattr_ctx *ctx); + +int import_xattr_name(struct xattr_name *kname, const char __user *name); + int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode); #ifdef CONFIG_FS_POSIX_ACL diff --git a/fs/xattr.c b/fs/xattr.c index 1214ae7e71db..d8f7c766f28a 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -586,6 +586,17 @@ vfs_removexattr(struct mnt_idmap *idmap, struct dentry *dentry, } EXPORT_SYMBOL_GPL(vfs_removexattr); +int import_xattr_name(struct xattr_name *kname, const char __user *name) +{ + int error = strncpy_from_user(kname->name, name, + sizeof(kname->name)); + if (error == 0 || error == sizeof(kname->name)) + return -ERANGE; + if (error < 0) + return error; + return 0; +} + /* * Extended attribute SET operations */ @@ -597,14 +608,10 @@ int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx) if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE)) return -EINVAL; - error = strncpy_from_user(ctx->kname->name, name, - sizeof(ctx->kname->name)); - if (error == 0 || error == sizeof(ctx->kname->name)) - return -ERANGE; - if (error < 0) + error = import_xattr_name(ctx->kname, name); + if (error) return error; - error = 0; if (ctx->size) { if (ctx->size > XATTR_SIZE_MAX) return -E2BIG; @@ -763,10 +770,8 @@ getxattr(struct mnt_idmap *idmap, struct dentry *d, .flags = 0, }; - error = strncpy_from_user(kname.name, name, sizeof(kname.name)); - if (error == 0 || error == sizeof(kname.name)) - error = -ERANGE; - if (error < 0) + error = import_xattr_name(&kname, name); + if (error) return error; error = do_getxattr(idmap, d, &ctx); @@ -906,12 +911,10 @@ static int path_removexattr(const char __user *pathname, { struct path path; int error; - char kname[XATTR_NAME_MAX + 1]; + struct xattr_name kname; - error = strncpy_from_user(kname, name, sizeof(kname)); - if (error == 0 || error == sizeof(kname)) - error = -ERANGE; - if (error < 0) + error = import_xattr_name(&kname, name); + if (error) return error; retry: error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); @@ -919,7 +922,7 @@ static int path_removexattr(const char __user *pathname, return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(mnt_idmap(path.mnt), path.dentry, kname); + error = removexattr(mnt_idmap(path.mnt), path.dentry, kname.name); mnt_drop_write(path.mnt); } path_put(&path); @@ -945,23 +948,21 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { CLASS(fd, f)(fd); - char kname[XATTR_NAME_MAX + 1]; + struct xattr_name kname; int error; if (fd_empty(f)) return -EBADF; audit_file(fd_file(f)); - error = strncpy_from_user(kname, name, sizeof(kname)); - if (error == 0 || error == sizeof(kname)) - error = -ERANGE; - if (error < 0) + error = import_xattr_name(&kname, name); + if (error) return error; error = mnt_want_write_file(fd_file(f)); if (!error) { error = removexattr(file_mnt_idmap(fd_file(f)), - fd_file(f)->f_path.dentry, kname); + fd_file(f)->f_path.dentry, kname.name); mnt_drop_write_file(fd_file(f)); } return error; diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 04abf0739668..71d9e2569a2f 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -65,11 +65,8 @@ static int __io_getxattr_prep(struct io_kiocb *req, if (!ix->ctx.kname) return -ENOMEM; - ret = strncpy_from_user(ix->ctx.kname->name, name, - sizeof(ix->ctx.kname->name)); - if (!ret || ret == sizeof(ix->ctx.kname->name)) - ret = -ERANGE; - if (ret < 0) { + ret = import_xattr_name(ix->ctx.kname, name); + if (ret) { kfree(ix->ctx.kname); return ret; } From patchwork Wed Oct 2 01:22:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819170 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 140FC9475; Wed, 2 Oct 2024 01:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; cv=none; b=bIusIcYTKi29G4LEGua7znDcflWajvGkSGig+Z4qPh0zut0yMfYWKKQGTGD8/DYF7l91XvUoJShosmR80AczglFFhZdh9uot5w/bX1x+wKxzRWrWT86VHJJUNYIn9fJ4yeRyj2Ls0U1rnBnQVnggw2ZKt4pAWWgk7PD+yOr+qyk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; c=relaxed/simple; bh=XtkxNFlzMcN60nLZXGyHQK9m1nCmZ2Em9nhZWDimLMo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ew81CfR98n7b4mr/Rke2/doSR4PMi8S/u/v3aukkdPFD5AZkgPJoccBAw9RIEU3It+lX+dNLNGBEYm3Y2nMVfajlJWlTAYcjAVf8B6uj5WEWhE/IQLV1JI32fygCK86rdoiZ/LPrWPj+x84AW9WB45Kq13/AFdsmhMqA3VxY7dY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=BDSI127M; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="BDSI127M" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=MUCkAroewEGiX5jQBsx3C0g+/ee/jcxLR3LB+g9sTJs=; b=BDSI127MIaxGUGYNmAWveSpQJZ mzRKzx0W34KgR9qYHkdjYibKindXvzJOLMKIw1buDku0YAhRn1fxnweT1VqszNHq91fNn+IzBkQ0/ 7GQMwUY4VtjLTI+XNcb7w+qZyAP9x0B3ginsGMdVX/B4bJAaoYLlDB3d81Q6HJ92G7LLdiAmWFAo+ MkYK5c3d9BpXRBRjnWWZo++x4nW9a8AdUZ93Td0fHJ0gqBba93zgRhS1kAS5mbRF31/XOlFgy1L3Z MpHd+GzHq/1lhdrJXHxTdzXjzreWm81Py6t+iOmrfC8xvDpfjW9R83V+YOWl72NQpw2881/G2Sq9i m1IFRt2Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0Q-2f4a; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 5/9] replace do_setxattr() with saner helpers. Date: Wed, 2 Oct 2024 02:22:26 +0100 Message-ID: <20241002012230.4174585-5-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro io_uring setxattr logics duplicates stuff from fs/xattr.c; provide saner helpers (filename_setxattr() and file_setxattr() resp.) and use them. Signed-off-by: Al Viro Signed-off-by: Jens Axboe --- fs/internal.h | 6 ++--- fs/xattr.c | 68 ++++++++++++++++++++++++++++++------------------ io_uring/xattr.c | 32 +++-------------------- 3 files changed, 49 insertions(+), 57 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index b9f5ac4d39fc..be7c0da3bcec 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -285,10 +285,10 @@ ssize_t do_getxattr(struct mnt_idmap *idmap, struct dentry *d, struct kernel_xattr_ctx *ctx); +int file_setxattr(struct file *file, struct kernel_xattr_ctx *ctx); +int filename_setxattr(int dfd, struct filename *filename, + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx); int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx); -int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, - struct kernel_xattr_ctx *ctx); - int import_xattr_name(struct xattr_name *kname, const char __user *name); int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode); diff --git a/fs/xattr.c b/fs/xattr.c index d8f7c766f28a..6326a1ea28e9 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -626,7 +626,7 @@ int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx) return error; } -int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, +static int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, struct kernel_xattr_ctx *ctx) { if (is_posix_acl_xattr(ctx->kname->name)) @@ -637,32 +637,31 @@ int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, ctx->kvalue, ctx->size, ctx->flags); } -static int path_setxattr(const char __user *pathname, - const char __user *name, const void __user *value, - size_t size, int flags, unsigned int lookup_flags) +int file_setxattr(struct file *f, struct kernel_xattr_ctx *ctx) +{ + int error = mnt_want_write_file(f); + + if (!error) { + audit_file(f); + error = do_setxattr(file_mnt_idmap(f), f->f_path.dentry, ctx); + mnt_drop_write_file(f); + } + return error; +} + +int filename_setxattr(int dfd, struct filename *filename, + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx) { - struct xattr_name kname; - struct kernel_xattr_ctx ctx = { - .cvalue = value, - .kvalue = NULL, - .size = size, - .kname = &kname, - .flags = flags, - }; struct path path; int error; - error = setxattr_copy(name, &ctx); - if (error) - return error; - retry: - error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) goto out; error = mnt_want_write(path.mnt); if (!error) { - error = do_setxattr(mnt_idmap(path.mnt), path.dentry, &ctx); + error = do_setxattr(mnt_idmap(path.mnt), path.dentry, ctx); mnt_drop_write(path.mnt); } path_put(&path); @@ -672,6 +671,30 @@ static int path_setxattr(const char __user *pathname, } out: + putname(filename); + return error; +} + +static int path_setxattr(const char __user *pathname, + const char __user *name, const void __user *value, + size_t size, int flags, unsigned int lookup_flags) +{ + struct xattr_name kname; + struct kernel_xattr_ctx ctx = { + .cvalue = value, + .kvalue = NULL, + .size = size, + .kname = &kname, + .flags = flags, + }; + int error; + + error = setxattr_copy(name, &ctx); + if (error) + return error; + + error = filename_setxattr(AT_FDCWD, getname(pathname), lookup_flags, + &ctx); kvfree(ctx.kvalue); return error; } @@ -707,17 +730,12 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, if (fd_empty(f)) return -EBADF; - audit_file(fd_file(f)); + error = setxattr_copy(name, &ctx); if (error) return error; - error = mnt_want_write_file(fd_file(f)); - if (!error) { - error = do_setxattr(file_mnt_idmap(fd_file(f)), - fd_file(f)->f_path.dentry, &ctx); - mnt_drop_write_file(fd_file(f)); - } + error = file_setxattr(fd_file(f), &ctx); kvfree(ctx.kvalue); return error; } diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 71d9e2569a2f..7f6bbfd846b9 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -200,28 +200,14 @@ int io_fsetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) return __io_setxattr_prep(req, sqe); } -static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags, - const struct path *path) -{ - struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); - int ret; - - ret = mnt_want_write(path->mnt); - if (!ret) { - ret = do_setxattr(mnt_idmap(path->mnt), path->dentry, &ix->ctx); - mnt_drop_write(path->mnt); - } - - return ret; -} - int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags) { + struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = __io_setxattr(req, issue_flags, &req->file->f_path); + ret = file_setxattr(req->file, &ix->ctx); io_xattr_finish(req, ret); return IOU_OK; } @@ -229,23 +215,11 @@ int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags) int io_setxattr(struct io_kiocb *req, unsigned int issue_flags) { struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); - unsigned int lookup_flags = LOOKUP_FOLLOW; - struct path path; int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); -retry: - ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL); - if (!ret) { - ret = __io_setxattr(req, issue_flags, &path); - path_put(&path); - if (retry_estale(ret, lookup_flags)) { - lookup_flags |= LOOKUP_REVAL; - goto retry; - } - } - + ret = filename_setxattr(AT_FDCWD, ix->filename, LOOKUP_FOLLOW, &ix->ctx); io_xattr_finish(req, ret); return IOU_OK; } From patchwork Wed Oct 2 01:22:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819167 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33290B666; Wed, 2 Oct 2024 01:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; cv=none; b=bmg6oJrorCxBwQMutRpifWlpZuiLwBP2oTrcY1DIc/VTjKsW8Iy5I2erTGB6AsgMw33czakSfVFA2zWJka+tQRTeF2LE05w2JZjC351qnuxo0JB43wbIZJW0aFq3E32NAiiaPD61d9FLZg/dN8mug9dJipjeOKOvznDoaIVP8a8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; c=relaxed/simple; bh=bO29qYIKUmAWtU9x8C4mT/xTRvzYTVcFJX7e3m+sSZ0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tt7tTolmS+dQXFXyhlZg5WsX85zPYGu1UVy2EV19/StEa0PTfCIkbVgRZMWbeQwrqWwthE2w9Db47XQCWYTZZhIWjijkMSFh+iVz5z15c2wscIj8isEfo+szytKGktzUEUYpc1+aPOP+V9rT1IBihwpQdObPYuBBooP0QovVLbo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=BwjfJBE6; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="BwjfJBE6" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=hiUGDWGTezfrBN4XzYAYFGCx6wv0AV4FV5hhTU1DsOg=; b=BwjfJBE6cNGeLbxpmNa/kHhLX7 djaaseT1q51cOLCwmFckGQ9/L0LRZ1K5wZLprGWu7uqW5UzmFsP2ChH/0o6arOm8Xptfzt/l7oH6c S1hFHZKULrbKpFnHZwmSqqLIO00p6KIfHW80SKBjSdl/SZcNe8ZJZE37+/5iQQpEz6qNHnMrbrsZs JOAY1cjbLVv3ypzlAp8cnCeGObTd5Tzk9FSPnp8b4MDqHIzAzltGrb4hT+pJCHC0vKHhM4eE9H+HE KHO05Z8xoPY+LMYV5ZMZ/gtmc5PjwXPvv1zwNJQAI+9Xij+/Hlgny2U9iEU56E6oXPnFNJIs5wCBH kZl2Gi9g==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0W-3CQL; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 6/9] replace do_getxattr() with saner helpers. Date: Wed, 2 Oct 2024 02:22:27 +0100 Message-ID: <20241002012230.4174585-6-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro similar to do_setxattr() in the previous commit... Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/internal.h | 8 ++--- fs/xattr.c | 87 ++++++++++++++++++++++++++++-------------------- io_uring/xattr.c | 22 ++---------- 3 files changed, 56 insertions(+), 61 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index be7c0da3bcec..8001efd1f047 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -280,11 +280,9 @@ struct kernel_xattr_ctx { unsigned int flags; }; - -ssize_t do_getxattr(struct mnt_idmap *idmap, - struct dentry *d, - struct kernel_xattr_ctx *ctx); - +ssize_t file_getxattr(struct file *file, struct kernel_xattr_ctx *ctx); +ssize_t filename_getxattr(int dfd, struct filename *filename, + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx); int file_setxattr(struct file *file, struct kernel_xattr_ctx *ctx); int filename_setxattr(int dfd, struct filename *filename, unsigned int lookup_flags, struct kernel_xattr_ctx *ctx); diff --git a/fs/xattr.c b/fs/xattr.c index 6326a1ea28e9..a0e304c65d51 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -743,27 +743,28 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, /* * Extended attribute GET operations */ -ssize_t +static ssize_t do_getxattr(struct mnt_idmap *idmap, struct dentry *d, struct kernel_xattr_ctx *ctx) { ssize_t error; char *kname = ctx->kname->name; + void *kvalue = NULL; if (ctx->size) { if (ctx->size > XATTR_SIZE_MAX) ctx->size = XATTR_SIZE_MAX; - ctx->kvalue = kvzalloc(ctx->size, GFP_KERNEL); - if (!ctx->kvalue) + kvalue = kvzalloc(ctx->size, GFP_KERNEL); + if (!kvalue) return -ENOMEM; } - if (is_posix_acl_xattr(ctx->kname->name)) - error = do_get_acl(idmap, d, kname, ctx->kvalue, ctx->size); + if (is_posix_acl_xattr(kname)) + error = do_get_acl(idmap, d, kname, kvalue, ctx->size); else - error = vfs_getxattr(idmap, d, kname, ctx->kvalue, ctx->size); + error = vfs_getxattr(idmap, d, kname, kvalue, ctx->size); if (error > 0) { - if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error)) + if (ctx->size && copy_to_user(ctx->value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && ctx->size >= XATTR_SIZE_MAX) { /* The file system tried to returned a value bigger @@ -771,52 +772,55 @@ do_getxattr(struct mnt_idmap *idmap, struct dentry *d, error = -E2BIG; } + kvfree(kvalue); return error; } -static ssize_t -getxattr(struct mnt_idmap *idmap, struct dentry *d, - const char __user *name, void __user *value, size_t size) +ssize_t file_getxattr(struct file *f, struct kernel_xattr_ctx *ctx) { - ssize_t error; - struct xattr_name kname; - struct kernel_xattr_ctx ctx = { - .value = value, - .kvalue = NULL, - .size = size, - .kname = &kname, - .flags = 0, - }; - - error = import_xattr_name(&kname, name); - if (error) - return error; - - error = do_getxattr(idmap, d, &ctx); - - kvfree(ctx.kvalue); - return error; + audit_file(f); + return do_getxattr(file_mnt_idmap(f), f->f_path.dentry, ctx); } -static ssize_t path_getxattr(const char __user *pathname, - const char __user *name, void __user *value, - size_t size, unsigned int lookup_flags) +ssize_t filename_getxattr(int dfd, struct filename *filename, + unsigned int lookup_flags, struct kernel_xattr_ctx *ctx) { struct path path; ssize_t error; retry: - error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) - return error; - error = getxattr(mnt_idmap(path.mnt), path.dentry, name, value, size); + goto out; + error = do_getxattr(mnt_idmap(path.mnt), path.dentry, ctx); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } +out: + putname(filename); return error; } +static ssize_t path_getxattr(const char __user *pathname, + const char __user *name, void __user *value, + size_t size, unsigned int lookup_flags) +{ + ssize_t error; + struct xattr_name kname; + struct kernel_xattr_ctx ctx = { + .value = value, + .size = size, + .kname = &kname, + .flags = 0, + }; + + error = import_xattr_name(&kname, name); + if (error) + return error; + return filename_getxattr(AT_FDCWD, getname(pathname), lookup_flags, &ctx); +} + SYSCALL_DEFINE4(getxattr, const char __user *, pathname, const char __user *, name, void __user *, value, size_t, size) { @@ -832,13 +836,22 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size) { + ssize_t error; + struct xattr_name kname; + struct kernel_xattr_ctx ctx = { + .value = value, + .size = size, + .kname = &kname, + .flags = 0, + }; CLASS(fd, f)(fd); if (fd_empty(f)) return -EBADF; - audit_file(fd_file(f)); - return getxattr(file_mnt_idmap(fd_file(f)), fd_file(f)->f_path.dentry, - name, value, size); + error = import_xattr_name(&kname, name); + if (error) + return error; + return file_getxattr(fd_file(f), &ctx); } /* diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 7f6bbfd846b9..0eaeaed39649 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -54,7 +54,7 @@ static int __io_getxattr_prep(struct io_kiocb *req, ix->filename = NULL; ix->ctx.kvalue = NULL; name = u64_to_user_ptr(READ_ONCE(sqe->addr)); - ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2)); + ix->ctx.value = u64_to_user_ptr(READ_ONCE(sqe->addr2)); ix->ctx.size = READ_ONCE(sqe->len); ix->ctx.flags = READ_ONCE(sqe->xattr_flags); @@ -109,10 +109,7 @@ int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags) WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); - ret = do_getxattr(file_mnt_idmap(req->file), - req->file->f_path.dentry, - &ix->ctx); - + ret = file_getxattr(req->file, &ix->ctx); io_xattr_finish(req, ret); return IOU_OK; } @@ -120,24 +117,11 @@ int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags) int io_getxattr(struct io_kiocb *req, unsigned int issue_flags) { struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr); - unsigned int lookup_flags = LOOKUP_FOLLOW; - struct path path; int ret; WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); -retry: - ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL); - if (!ret) { - ret = do_getxattr(mnt_idmap(path.mnt), path.dentry, &ix->ctx); - - path_put(&path); - if (retry_estale(ret, lookup_flags)) { - lookup_flags |= LOOKUP_REVAL; - goto retry; - } - } - + ret = filename_getxattr(AT_FDCWD, ix->filename, LOOKUP_FOLLOW, &ix->ctx); io_xattr_finish(req, ret); return IOU_OK; } From patchwork Wed Oct 2 01:22:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819164 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 687DCB661; Wed, 2 Oct 2024 01:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; cv=none; b=m41m24WP9Oe43acWxN7+V8pSV13azHBv06Dc3to9xLN3y6phT+X+YS0i8CKOZ+40XwAtOYUhwEjsPn4zYntOVjKTzjepX22aLAHLBYRVBTVxceri6WVtHtu7VqVvxa6hKE7kv5FDQYoVqNYAyrde9uHrWZt2DgGfCjgwAquDP/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832154; c=relaxed/simple; bh=LAcO6kLar/jzXelC+U7P8E30181ld+xL6+yS0dU/V7Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tN8H4gHIpv02f4X5ZY2snRMGv38vjJOCx6O521doVQLd0alwP3RgxcSKIJ+Cgc0SV0RwLHPPKBrsejSdlixl/VMpvBqkT2waynI+SHbHM2nuTapHH8KuQw5VaSF/AUi0xiC690zYXH9x7nWSlXOImbScyIxfvl19S475hAHLydg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=mtU4GHf5; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="mtU4GHf5" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=ohpVJLn9t4W/NiAg7UbpvG1tUTmBfnNzLpci18vWTkE=; b=mtU4GHf56PEUYo6Zk80af3alDL F+BVu2NizvprXT0NlX5nXPvgJdSTw8GIP4b+Kz6SGN2e3njQEBfltHQ0cESOdbU7+i5Gzce5ELbuf SOiCC3t1fQfbshkAqporuD+PZM8ovonzlq6nmCnMVmA7TgJ6+6W5iAaWnJbP8idJ5/Sjn7VacnqI6 8rjl9LZr8vnHKy5mRl9Bsj49oh90kQCGIMYoWMo/xPHwONad6UrqxLJSn8SvWLOpAac+4tU98YQH3 SR9BH5bWkwTSslBo25VAdXXaF2Q3X99LIsoVw8DkP1mEQ5rkLxRS5WEN1ayEM6mYsSQtfuio+jRbx E4W0yM+A==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4U-0000000HW0b-3eNo; Wed, 02 Oct 2024 01:22:30 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 7/9] new helpers: file_listxattr(), filename_listxattr() Date: Wed, 2 Oct 2024 02:22:28 +0100 Message-ID: <20241002012230.4174585-7-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro switch path_listxattr() and flistxattr(2) to those Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/xattr.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index a0e304c65d51..0a1da16f74b1 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -886,24 +886,42 @@ listxattr(struct dentry *d, char __user *list, size_t size) return error; } -static ssize_t path_listxattr(const char __user *pathname, char __user *list, - size_t size, unsigned int lookup_flags) +static +ssize_t file_listxattr(struct file *f, char __user *list, size_t size) +{ + audit_file(f); + return listxattr(f->f_path.dentry, list, size); +} + +static +ssize_t filename_listxattr(int dfd, struct filename *filename, + unsigned int lookup_flags, + char __user *list, size_t size) { struct path path; ssize_t error; retry: - error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) - return error; + goto out; error = listxattr(path.dentry, list, size); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } +out: + putname(filename); return error; } +static ssize_t path_listxattr(const char __user *pathname, char __user *list, + size_t size, unsigned int lookup_flags) +{ + return filename_listxattr(AT_FDCWD, getname(pathname), lookup_flags, + list, size); +} + SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, size_t, size) { @@ -922,8 +940,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) if (fd_empty(f)) return -EBADF; - audit_file(fd_file(f)); - return listxattr(fd_file(f)->f_path.dentry, list, size); + return file_listxattr(fd_file(f), list, size); } /* From patchwork Wed Oct 2 01:22:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819168 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B14DB66E; Wed, 2 Oct 2024 01:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; cv=none; b=f/j6ROXc32IlQ+iSLl44relYIAzFYl9zIJdw76VTzBI0oeb4GzAvumLLwiE50bvExIgOygjuUMF5QZpzByFdDuGlDOAgTAgOets/lz5FxBCCYWoUgofgwOfETVO1Ycx9W+QTF3XY+NYrrbJvSTbNCsiXcRcFA8ijhK9Ix+60W+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; c=relaxed/simple; bh=VNQ+ez5qKBJ3SnuWtn0DrDNWpC2eEvPWUeX31u9P0wM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Dd7FlbMO/4ONGQA0iffS9cjhVBuZdL4nJnTB2hJ0awTUhm+g8p3t24BcMfL2gMDaE6unhuusI6VAsuuZ3Oof+fXywXpWBsEJK2D6l5VDR0ZI8oZ7QeA5Ua1FGjiG4cVmfJzmTNRhONAXV9ZiDP4tfEsF51GzHmGLTE7KhGF4XR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=NN3U2RLQ; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="NN3U2RLQ" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=tuJ0USvtoQ9FyOpmJn8A5DIA56W4830JHccLaKT1zSc=; b=NN3U2RLQo+0FrmyJ5VKGM4pkI1 jaT4HUbA27mCiEvkQ9hJib8lILtm8tXU4q7ueGu0BSlZxtZRK4rkig1vM9w9eAGCQbc3RR36f8s32 335/FM9P2wd/Q4IPJsBPpb9lllkAyzxZVMKqIEwWqRLitLvdRz9rMZMz6pfagtOShmLQ2IfsBC/v9 wrOZ9aPv4XURq2U5eXgNBeKrKee7QI6RQX9540s9HlHbn8HT+hSN2wJ3MneKJoyV/q7+I7YoZvkxg 2NQSndqY4iQaE2ZsSNXOdyHbs/KKKYZwAVeOtl3qe4g2NZBrl9PDSPoeuLPc03VQ1jAnuHdta6CEC f8TpRikA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4V-0000000HW0h-08FZ; Wed, 02 Oct 2024 01:22:31 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 8/9] new helpers: file_removexattr(), filename_removexattr() Date: Wed, 2 Oct 2024 02:22:29 +0100 Message-ID: <20241002012230.4174585-8-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro switch path_removexattrat() and fremovexattr(2) to those Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/xattr.c | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 0a1da16f74b1..6f87f23c0e84 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -954,23 +954,32 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d, const char *name) return vfs_removexattr(idmap, d, name); } -static int path_removexattr(const char __user *pathname, - const char __user *name, unsigned int lookup_flags) +static int file_removexattr(struct file *f, struct xattr_name *kname) +{ + int error = mnt_want_write_file(f); + + if (!error) { + audit_file(f); + error = removexattr(file_mnt_idmap(f), + f->f_path.dentry, kname->name); + mnt_drop_write_file(f); + } + return error; +} + +static int filename_removexattr(int dfd, struct filename *filename, + unsigned int lookup_flags, struct xattr_name *kname) { struct path path; int error; - struct xattr_name kname; - error = import_xattr_name(&kname, name); - if (error) - return error; retry: - error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); + error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) - return error; + goto out; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(mnt_idmap(path.mnt), path.dentry, kname.name); + error = removexattr(mnt_idmap(path.mnt), path.dentry, kname->name); mnt_drop_write(path.mnt); } path_put(&path); @@ -978,9 +987,24 @@ static int path_removexattr(const char __user *pathname, lookup_flags |= LOOKUP_REVAL; goto retry; } +out: + putname(filename); return error; } +static int path_removexattr(const char __user *pathname, + const char __user *name, unsigned int lookup_flags) +{ + struct xattr_name kname; + int error; + + error = import_xattr_name(&kname, name); + if (error) + return error; + return filename_removexattr(AT_FDCWD, getname(pathname), lookup_flags, + &kname); +} + SYSCALL_DEFINE2(removexattr, const char __user *, pathname, const char __user *, name) { @@ -1001,19 +1025,11 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) if (fd_empty(f)) return -EBADF; - audit_file(fd_file(f)); error = import_xattr_name(&kname, name); if (error) return error; - - error = mnt_want_write_file(fd_file(f)); - if (!error) { - error = removexattr(file_mnt_idmap(fd_file(f)), - fd_file(f)->f_path.dentry, kname.name); - mnt_drop_write_file(fd_file(f)); - } - return error; + return file_removexattr(fd_file(f), &kname); } int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name) From patchwork Wed Oct 2 01:22:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13819169 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92FFCB674; Wed, 2 Oct 2024 01:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; cv=none; b=JHiw/1XPWTeHIqzotpoAXXWhvR2yaaFIY3rRqEBfIGNdeo4gVHAzfOUvsv9MrAbAt7FRX3sib6afoCyjqSq/hu8auIIp85woOL5J1Bfs/1lZ3mGzmeOlDqRW9ZVOa39f/u0ssASm7dbnJNy2wJA5Z++7U9ZmHmrTEl5N3kyfG38= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727832155; c=relaxed/simple; bh=z/1wNhbPZY84KptqS48Zoxu9t/L4UZTAjkm8ShjUhos=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J6F2eLqU8HAJecvBJ3rKXSCju/e6GKjA+oao39FN99dxi0NCNxQg+e8uH30QXPM89ogGQyolJreSffr6KUe3t8zvHoaiYHYQWRUJ5fe7Pzh2avAQVfjyZT4JcLNrOCM3gGGVVPSsPryHgn8DE5s5WU+q0/hktnDXgq/HcoTywVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=Y72uVuZL; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="Y72uVuZL" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=dpW4U1vUG7v5XSgdCL9t9GpdlJAruZ4zMZf+McI+BFg=; b=Y72uVuZLBMHyqH7lfh4FUl5YLG FZvghEHC7XPv0RlrotXe+QVfKRDKK5bO5gBAIu8wJid8v9q0z3ulyeDONF6X7Ii9KCrEWvWRzAghI sfzuF5LcD+M2/qUTtDwWA48nck5wGNsftwPW137cDkFqlVQglNEVwU0GD/bXJaX1ZIzvRS17LDIpT GzIAP2hA/+B60GH3knh5KIIXLCdS6ef6muCaLi4w9GFacrJDN76eQq/ETC96rZmycIItYynAI9Chy LIuTe4xcwtaL/n3Ai1Dt+Bu/zyiREhH00r8zJiRBfTD1vryr646lLEgKmehSQsK7OdKiS+kK5hXew Eov4syLg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1svo4V-0000000HW0o-0Tfz; Wed, 02 Oct 2024 01:22:31 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: brauner@kernel.org, io-uring@vger.kernel.org, cgzones@googlemail.com Subject: [PATCH 9/9] fs/xattr: add *at family syscalls Date: Wed, 2 Oct 2024 02:22:30 +0100 Message-ID: <20241002012230.4174585-9-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241002012230.4174585-1-viro@zeniv.linux.org.uk> References: <20241002011011.GB4017910@ZenIV> <20241002012230.4174585-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro From: Christian Göttsche Add the four syscalls setxattrat(), getxattrat(), listxattrat() and removexattrat(). Those can be used to operate on extended attributes, especially security related ones, either relative to a pinned directory or on a file descriptor without read access, avoiding a /proc//fd/ detour, requiring a mounted procfs. One use case will be setfiles(8) setting SELinux file contexts ("security.selinux") without race conditions and without a file descriptor opened with read access requiring SELinux read permission. Use the do_{name}at() pattern from fs/open.c. Pass the value of the extended attribute, its length, and for setxattrat(2) the command (XATTR_CREATE or XATTR_REPLACE) via an added struct xattr_args to not exceed six syscall arguments and not merging the AT_* and XATTR_* flags. [AV: fixes by Christian Brauner folded in, the entire thing rebased on top of {filename,file}_...xattr() primitives, treatment of empty pathnames regularized. As the result, AT_EMPTY_PATH+NULL handling is cheap, so f...(2) can use it] Signed-off-by: Christian Göttsche Link: https://lore.kernel.org/r/20240426162042.191916-1-cgoettsche@seltendoof.de Reviewed-by: Arnd Bergmann CC: x86@kernel.org CC: linux-alpha@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: linux-arm-kernel@lists.infradead.org CC: linux-ia64@vger.kernel.org CC: linux-m68k@lists.linux-m68k.org CC: linux-mips@vger.kernel.org CC: linux-parisc@vger.kernel.org CC: linuxppc-dev@lists.ozlabs.org CC: linux-s390@vger.kernel.org CC: linux-sh@vger.kernel.org CC: sparclinux@vger.kernel.org CC: linux-fsdevel@vger.kernel.org CC: audit@vger.kernel.org CC: linux-arch@vger.kernel.org CC: linux-api@vger.kernel.org CC: linux-security-module@vger.kernel.org CC: selinux@vger.kernel.org [brauner: slight tweaks] Signed-off-by: Christian Brauner Reviewed-by: Christian Brauner --- arch/alpha/kernel/syscalls/syscall.tbl | 4 + arch/arm/tools/syscall.tbl | 4 + arch/m68k/kernel/syscalls/syscall.tbl | 4 + arch/microblaze/kernel/syscalls/syscall.tbl | 4 + arch/mips/kernel/syscalls/syscall_n32.tbl | 4 + arch/mips/kernel/syscalls/syscall_n64.tbl | 4 + arch/mips/kernel/syscalls/syscall_o32.tbl | 4 + arch/parisc/kernel/syscalls/syscall.tbl | 4 + arch/powerpc/kernel/syscalls/syscall.tbl | 4 + arch/s390/kernel/syscalls/syscall.tbl | 4 + arch/sh/kernel/syscalls/syscall.tbl | 4 + arch/sparc/kernel/syscalls/syscall.tbl | 4 + arch/x86/entry/syscalls/syscall_32.tbl | 4 + arch/x86/entry/syscalls/syscall_64.tbl | 4 + arch/xtensa/kernel/syscalls/syscall.tbl | 4 + fs/xattr.c | 271 ++++++++++++++------ include/asm-generic/audit_change_attr.h | 6 + include/linux/syscalls.h | 13 + include/linux/xattr.h | 4 + include/uapi/asm-generic/unistd.h | 11 +- include/uapi/linux/xattr.h | 7 + 21 files changed, 286 insertions(+), 86 deletions(-) diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index 74720667fe09..c59d53d6d3f3 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -502,3 +502,7 @@ 570 common lsm_set_self_attr sys_lsm_set_self_attr 571 common lsm_list_modules sys_lsm_list_modules 572 common mseal sys_mseal +573 common setxattrat sys_setxattrat +574 common getxattrat sys_getxattrat +575 common listxattrat sys_listxattrat +576 common removexattrat sys_removexattrat diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 23c98203c40f..49eeb2ad8dbd 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -477,3 +477,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index 22a3cbd4c602..f5ed71f1910d 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -462,3 +462,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl index 2b81a6bd78b2..680f568b77f2 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -468,3 +468,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index 953f5b7dc723..0b9b7e25b69a 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -401,3 +401,7 @@ 460 n32 lsm_set_self_attr sys_lsm_set_self_attr 461 n32 lsm_list_modules sys_lsm_list_modules 462 n32 mseal sys_mseal +463 n32 setxattrat sys_setxattrat +464 n32 getxattrat sys_getxattrat +465 n32 listxattrat sys_listxattrat +466 n32 removexattrat sys_removexattrat diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index 1464c6be6eb3..c844cd5cda62 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -377,3 +377,7 @@ 460 n64 lsm_set_self_attr sys_lsm_set_self_attr 461 n64 lsm_list_modules sys_lsm_list_modules 462 n64 mseal sys_mseal +463 n64 setxattrat sys_setxattrat +464 n64 getxattrat sys_getxattrat +465 n64 listxattrat sys_listxattrat +466 n64 removexattrat sys_removexattrat diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index 2439a2491cff..349b8aad1159 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -450,3 +450,7 @@ 460 o32 lsm_set_self_attr sys_lsm_set_self_attr 461 o32 lsm_list_modules sys_lsm_list_modules 462 o32 mseal sys_mseal +463 o32 setxattrat sys_setxattrat +464 o32 getxattrat sys_getxattrat +465 o32 listxattrat sys_listxattrat +466 o32 removexattrat sys_removexattrat diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index 66dc406b12e4..d9fc94c86965 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -461,3 +461,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index ebae8415dfbb..d8b4ab78bef0 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -553,3 +553,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 01071182763e..e9115b4d8b63 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -465,3 +465,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal sys_mseal +463 common setxattrat sys_setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat sys_removexattrat diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index c55fd7696d40..c8cad33bf250 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -466,3 +466,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index cfdfb3707c16..727f99d333b3 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -508,3 +508,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 534c74b14fab..4d0fb2fba7e2 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -468,3 +468,7 @@ 460 i386 lsm_set_self_attr sys_lsm_set_self_attr 461 i386 lsm_list_modules sys_lsm_list_modules 462 i386 mseal sys_mseal +463 i386 setxattrat sys_setxattrat +464 i386 getxattrat sys_getxattrat +465 i386 listxattrat sys_listxattrat +466 i386 removexattrat sys_removexattrat diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 7093ee21c0d1..5eb708bff1c7 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -386,6 +386,10 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat # # Due to a historical design error, certain syscalls are numbered differently diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index 67083fc1b2f5..37effc1b134e 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -433,3 +433,7 @@ 460 common lsm_set_self_attr sys_lsm_set_self_attr 461 common lsm_list_modules sys_lsm_list_modules 462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat diff --git a/fs/xattr.c b/fs/xattr.c index 6f87f23c0e84..59cdb524412e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -597,6 +597,32 @@ int import_xattr_name(struct xattr_name *kname, const char __user *name) return 0; } +static struct filename *getname_xattr(const char __user *pathname, + unsigned int at_flags) +{ + struct filename *name; + char c; + + if (!(at_flags & AT_EMPTY_PATH)) + return getname(pathname); + + if (!pathname) + return NULL; + + /* try to save on allocations; will suck on s390 and um, though */ + if (get_user(c, pathname)) + return ERR_PTR(-EFAULT); + if (!c) + return NULL; + + name = getname_flags(pathname, LOOKUP_EMPTY); + if (!IS_ERR(name) && !(name->name[0])) { + putname(name); + name = NULL; + } + return name; +} + /* * Extended attribute SET operations */ @@ -675,69 +701,90 @@ int filename_setxattr(int dfd, struct filename *filename, return error; } -static int path_setxattr(const char __user *pathname, - const char __user *name, const void __user *value, - size_t size, int flags, unsigned int lookup_flags) +static int path_setxattrat(int dfd, const char __user *pathname, + unsigned int at_flags, const char __user *name, + const void __user *value, size_t size, int flags) { struct xattr_name kname; struct kernel_xattr_ctx ctx = { - .cvalue = value, - .kvalue = NULL, - .size = size, - .kname = &kname, - .flags = flags, + .cvalue = value, + .kvalue = NULL, + .size = size, + .kname = &kname, + .flags = flags, }; + struct filename *filename; + unsigned int lookup_flags = 0; int error; + if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) + return -EINVAL; + + if (at_flags & AT_SYMLINK_NOFOLLOW) + lookup_flags = LOOKUP_FOLLOW; + error = setxattr_copy(name, &ctx); if (error) return error; - error = filename_setxattr(AT_FDCWD, getname(pathname), lookup_flags, - &ctx); + filename = getname_xattr(pathname, at_flags); + if (!filename) { + CLASS(fd, f)(dfd); + if (fd_empty(f)) + error = -EBADF; + else + error = file_setxattr(fd_file(f), &ctx); + } else { + error = filename_setxattr(dfd, filename, lookup_flags, &ctx); + } kvfree(ctx.kvalue); return error; } +SYSCALL_DEFINE6(setxattrat, int, dfd, const char __user *, pathname, unsigned int, at_flags, + const char __user *, name, const struct xattr_args __user *, uargs, + size_t, usize) +{ + struct xattr_args args = {}; + int error; + + BUILD_BUG_ON(sizeof(struct xattr_args) < XATTR_ARGS_SIZE_VER0); + BUILD_BUG_ON(sizeof(struct xattr_args) != XATTR_ARGS_SIZE_LATEST); + + if (unlikely(usize < XATTR_ARGS_SIZE_VER0)) + return -EINVAL; + if (usize > PAGE_SIZE) + return -E2BIG; + + error = copy_struct_from_user(&args, sizeof(args), uargs, usize); + if (error) + return error; + + return path_setxattrat(dfd, pathname, at_flags, name, + u64_to_user_ptr(args.value), args.size, + args.flags); +} + SYSCALL_DEFINE5(setxattr, const char __user *, pathname, const char __user *, name, const void __user *, value, size_t, size, int, flags) { - return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW); + return path_setxattrat(AT_FDCWD, pathname, 0, name, value, size, flags); } SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, const char __user *, name, const void __user *, value, size_t, size, int, flags) { - return path_setxattr(pathname, name, value, size, flags, 0); + return path_setxattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, name, + value, size, flags); } SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, const void __user *,value, size_t, size, int, flags) { - struct xattr_name kname; - struct kernel_xattr_ctx ctx = { - .cvalue = value, - .kvalue = NULL, - .size = size, - .kname = &kname, - .flags = flags, - }; - int error; - - CLASS(fd, f)(fd); - - if (fd_empty(f)) - return -EBADF; - - error = setxattr_copy(name, &ctx); - if (error) - return error; - - error = file_setxattr(fd_file(f), &ctx); - kvfree(ctx.kvalue); - return error; + return path_setxattrat(fd, NULL, AT_EMPTY_PATH, name, + value, size, flags); } /* @@ -802,11 +849,10 @@ ssize_t filename_getxattr(int dfd, struct filename *filename, return error; } -static ssize_t path_getxattr(const char __user *pathname, - const char __user *name, void __user *value, - size_t size, unsigned int lookup_flags) +static ssize_t path_getxattrat(int dfd, const char __user *pathname, + unsigned int at_flags, const char __user *name, + void __user *value, size_t size) { - ssize_t error; struct xattr_name kname; struct kernel_xattr_ctx ctx = { .value = value, @@ -814,44 +860,72 @@ static ssize_t path_getxattr(const char __user *pathname, .kname = &kname, .flags = 0, }; + struct filename *filename; + ssize_t error; + + if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) + return -EINVAL; error = import_xattr_name(&kname, name); if (error) return error; - return filename_getxattr(AT_FDCWD, getname(pathname), lookup_flags, &ctx); + + filename = getname_xattr(pathname, at_flags); + if (!filename) { + CLASS(fd, f)(dfd); + if (fd_empty(f)) + return -EBADF; + return file_getxattr(fd_file(f), &ctx); + } else { + int lookup_flags = 0; + if (at_flags & AT_SYMLINK_NOFOLLOW) + lookup_flags = LOOKUP_FOLLOW; + return filename_getxattr(dfd, filename, lookup_flags, &ctx); + } +} + +SYSCALL_DEFINE6(getxattrat, int, dfd, const char __user *, pathname, unsigned int, at_flags, + const char __user *, name, struct xattr_args __user *, uargs, size_t, usize) +{ + struct xattr_args args = {}; + int error; + + BUILD_BUG_ON(sizeof(struct xattr_args) < XATTR_ARGS_SIZE_VER0); + BUILD_BUG_ON(sizeof(struct xattr_args) != XATTR_ARGS_SIZE_LATEST); + + if (unlikely(usize < XATTR_ARGS_SIZE_VER0)) + return -EINVAL; + if (usize > PAGE_SIZE) + return -E2BIG; + + error = copy_struct_from_user(&args, sizeof(args), uargs, usize); + if (error) + return error; + + if (args.flags != 0) + return -EINVAL; + + return path_getxattrat(dfd, pathname, at_flags, name, + u64_to_user_ptr(args.value), args.size); } SYSCALL_DEFINE4(getxattr, const char __user *, pathname, const char __user *, name, void __user *, value, size_t, size) { - return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW); + return path_getxattrat(AT_FDCWD, pathname, 0, name, value, size); } SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, const char __user *, name, void __user *, value, size_t, size) { - return path_getxattr(pathname, name, value, size, 0); + return path_getxattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, name, + value, size); } SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size) { - ssize_t error; - struct xattr_name kname; - struct kernel_xattr_ctx ctx = { - .value = value, - .size = size, - .kname = &kname, - .flags = 0, - }; - CLASS(fd, f)(fd); - - if (fd_empty(f)) - return -EBADF; - error = import_xattr_name(&kname, name); - if (error) - return error; - return file_getxattr(fd_file(f), &ctx); + return path_getxattrat(fd, NULL, AT_EMPTY_PATH, name, value, size); } /* @@ -915,32 +989,50 @@ ssize_t filename_listxattr(int dfd, struct filename *filename, return error; } -static ssize_t path_listxattr(const char __user *pathname, char __user *list, - size_t size, unsigned int lookup_flags) +static ssize_t path_listxattrat(int dfd, const char __user *pathname, + unsigned int at_flags, char __user *list, + size_t size) +{ + struct filename *filename; + int lookup_flags; + + if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) + return -EINVAL; + + filename = getname_xattr(pathname, at_flags); + if (!filename) { + CLASS(fd, f)(dfd); + if (fd_empty(f)) + return -EBADF; + return file_listxattr(fd_file(f), list, size); + } + + lookup_flags = (at_flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; + return filename_listxattr(dfd, filename, lookup_flags, list, size); +} + +SYSCALL_DEFINE5(listxattrat, int, dfd, const char __user *, pathname, + unsigned int, at_flags, + char __user *, list, size_t, size) { - return filename_listxattr(AT_FDCWD, getname(pathname), lookup_flags, - list, size); + return path_listxattrat(dfd, pathname, at_flags, list, size); } SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, size_t, size) { - return path_listxattr(pathname, list, size, LOOKUP_FOLLOW); + return path_listxattrat(AT_FDCWD, pathname, 0, list, size); } SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, size_t, size) { - return path_listxattr(pathname, list, size, 0); + return path_listxattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, list, size); } SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) { - CLASS(fd, f)(fd); - - if (fd_empty(f)) - return -EBADF; - return file_listxattr(fd_file(f), list, size); + return path_listxattrat(fd, NULL, AT_EMPTY_PATH, list, size); } /* @@ -992,44 +1084,53 @@ static int filename_removexattr(int dfd, struct filename *filename, return error; } -static int path_removexattr(const char __user *pathname, - const char __user *name, unsigned int lookup_flags) +static int path_removexattrat(int dfd, const char __user *pathname, + unsigned int at_flags, const char __user *name) { struct xattr_name kname; + struct filename *filename; + unsigned int lookup_flags; int error; + if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) + return -EINVAL; + error = import_xattr_name(&kname, name); if (error) return error; - return filename_removexattr(AT_FDCWD, getname(pathname), lookup_flags, - &kname); + + filename = getname_xattr(pathname, at_flags); + if (!filename) { + CLASS(fd, f)(dfd); + if (fd_empty(f)) + return -EBADF; + return file_removexattr(fd_file(f), &kname); + } + lookup_flags = (at_flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; + return filename_removexattr(dfd, filename, lookup_flags, &kname); +} + +SYSCALL_DEFINE4(removexattrat, int, dfd, const char __user *, pathname, + unsigned int, at_flags, const char __user *, name) +{ + return path_removexattrat(dfd, pathname, at_flags, name); } SYSCALL_DEFINE2(removexattr, const char __user *, pathname, const char __user *, name) { - return path_removexattr(pathname, name, LOOKUP_FOLLOW); + return path_removexattrat(AT_FDCWD, pathname, 0, name); } SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, const char __user *, name) { - return path_removexattr(pathname, name, 0); + return path_removexattrat(AT_FDCWD, pathname, AT_SYMLINK_NOFOLLOW, name); } SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { - CLASS(fd, f)(fd); - struct xattr_name kname; - int error; - - if (fd_empty(f)) - return -EBADF; - - error = import_xattr_name(&kname, name); - if (error) - return error; - return file_removexattr(fd_file(f), &kname); + return path_removexattrat(fd, NULL, AT_EMPTY_PATH, name); } int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name) diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h index 331670807cf0..cc840537885f 100644 --- a/include/asm-generic/audit_change_attr.h +++ b/include/asm-generic/audit_change_attr.h @@ -11,9 +11,15 @@ __NR_lchown, __NR_fchown, #endif __NR_setxattr, +#ifdef __NR_setxattrat +__NR_setxattrat, +#endif __NR_lsetxattr, __NR_fsetxattr, __NR_removexattr, +#ifdef __NR_removexattrat +__NR_removexattrat, +#endif __NR_lremovexattr, __NR_fremovexattr, #ifdef __NR_fchownat diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 5758104921e6..c6333204d451 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -77,6 +77,7 @@ struct cachestat_range; struct cachestat; struct statmount; struct mnt_id_req; +struct xattr_args; #include #include @@ -338,23 +339,35 @@ asmlinkage long sys_io_uring_register(unsigned int fd, unsigned int op, void __user *arg, unsigned int nr_args); asmlinkage long sys_setxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags); +asmlinkage long sys_setxattrat(int dfd, const char __user *path, unsigned int at_flags, + const char __user *name, + const struct xattr_args __user *args, size_t size); asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags); asmlinkage long sys_fsetxattr(int fd, const char __user *name, const void __user *value, size_t size, int flags); asmlinkage long sys_getxattr(const char __user *path, const char __user *name, void __user *value, size_t size); +asmlinkage long sys_getxattrat(int dfd, const char __user *path, unsigned int at_flags, + const char __user *name, + struct xattr_args __user *args, size_t size); asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name, void __user *value, size_t size); asmlinkage long sys_fgetxattr(int fd, const char __user *name, void __user *value, size_t size); asmlinkage long sys_listxattr(const char __user *path, char __user *list, size_t size); +asmlinkage long sys_listxattrat(int dfd, const char __user *path, + unsigned int at_flags, + char __user *list, size_t size); asmlinkage long sys_llistxattr(const char __user *path, char __user *list, size_t size); asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size); asmlinkage long sys_removexattr(const char __user *path, const char __user *name); +asmlinkage long sys_removexattrat(int dfd, const char __user *path, + unsigned int at_flags, + const char __user *name); asmlinkage long sys_lremovexattr(const char __user *path, const char __user *name); asmlinkage long sys_fremovexattr(int fd, const char __user *name); diff --git a/include/linux/xattr.h b/include/linux/xattr.h index d20051865800..86b0d47984a1 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -19,6 +19,10 @@ #include #include +/* List of all open_how "versions". */ +#define XATTR_ARGS_SIZE_VER0 16 /* sizeof first published struct */ +#define XATTR_ARGS_SIZE_LATEST XATTR_ARGS_SIZE_VER0 + struct inode; struct dentry; diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 5bf6148cac2b..88dc393c2bca 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -841,8 +841,17 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules) #define __NR_mseal 462 __SYSCALL(__NR_mseal, sys_mseal) +#define __NR_setxattrat 463 +__SYSCALL(__NR_setxattrat, sys_setxattrat) +#define __NR_getxattrat 464 +__SYSCALL(__NR_getxattrat, sys_getxattrat) +#define __NR_listxattrat 465 +__SYSCALL(__NR_listxattrat, sys_listxattrat) +#define __NR_removexattrat 466 +__SYSCALL(__NR_removexattrat, sys_removexattrat) + #undef __NR_syscalls -#define __NR_syscalls 463 +#define __NR_syscalls 467 /* * 32 bit systems traditionally used different diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 9463db2dfa9d..9854f9cff3c6 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -11,6 +11,7 @@ */ #include +#include #ifndef _UAPI_LINUX_XATTR_H #define _UAPI_LINUX_XATTR_H @@ -20,6 +21,12 @@ #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ + +struct xattr_args { + __aligned_u64 __user value; + __u32 size; + __u32 flags; +}; #endif /* Namespaces */