From patchwork Sat Nov 2 07:31:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860022 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 6FFA713C689; Sat, 2 Nov 2024 07:31:51 +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=1730532713; cv=none; b=d0ZTYsXho5vTGEmRfYNUY5DtFPLx9stczmEFnz8p4dEf3D5jrHYaxIXa8+jG862eHDfm2DPogOAeu9ycDrY9f4Q9hj7wnbtPJ02aslCVMwBDUmvT5zadCUxA4Nc63kRFDk2eGYzBrDsDhJF8BqEW6sZ2AaVL+FwtmrSmxZFKdDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532713; c=relaxed/simple; bh=wrAK8GWUnKgolQ2z/c3Ma/GJvRqLPBCuOn6ORmedNZw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FTNM9f5vCwAwn3WkPUCyT59iqWBKIJsXYdEyny5AOl2XV4Df/1DcccYyrZ2fmy1RdY75r1r/z9bOBdBjj/nTRPmTUydChkxp18GA6IFA8rAHqHfdTk5AegAlEkzTyDWPRsdeYXOpGkHU5Cbw77SHrcPSPb3PsmK4g26sBARVdmk= 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=EAetXOvQ; 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="EAetXOvQ" 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=DGhSDWn32QTMB3ujcBJ0Ej51Fa5Ytz9zjamnl+wee8k=; b=EAetXOvQ1LmMQh92iy/lD5AH63 76zldOodgr3F8OVHeMqeHKmUy+o0M5Tm3yUsts9B446+tnfglaoxazboGjYtoRewFuhQoeAHiI0DB ErUtEmopIe387YAM2qC0q4JIemv3WDO0iahuPuaJX1tAXp450LWVv74hcuEnJNs3SwjEK394clWuy IG9xHwCw4wkEQShUoxFuEXTzNH+VYTVtl2S9TCHME0fsiJ3Ek/fUkVg3XRI1+glRm3IZ+lNX+B375 6RUDOmbFeavHbh3NUW+XswwBJUn9/z/+gHo5e5we5VrNWT99SDFgyTsKaNNsYl1p0zv+s0wNy/+zv 9Ff7qaRA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJF1-0cIW; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 01/13] teach filename_lookup() to treat NULL filename as "" Date: Sat, 2 Nov 2024 07:31:37 +0000 Message-ID: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102072834.GQ1350452@ZenIV> References: <20241102072834.GQ1350452@ZenIV> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Signed-off-by: Al Viro --- fs/namei.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 4a4a22a08ac2..aaf3cd6c802f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -588,6 +588,7 @@ struct nameidata { unsigned seq; } *stack, internal[EMBEDDED_LEVELS]; struct filename *name; + const char *pathname; struct nameidata *saved; unsigned root_seq; int dfd; @@ -606,6 +607,7 @@ static void __set_nameidata(struct nameidata *p, int dfd, struct filename *name) p->depth = 0; p->dfd = dfd; p->name = name; + p->pathname = likely(name) ? name->name : ""; p->path.mnt = NULL; p->path.dentry = NULL; p->total_link_count = old ? old->total_link_count : 0; @@ -2439,7 +2441,7 @@ static int link_path_walk(const char *name, struct nameidata *nd) static const char *path_init(struct nameidata *nd, unsigned flags) { int error; - const char *s = nd->name->name; + const char *s = nd->pathname; /* LOOKUP_CACHED requires RCU, ask caller to retry */ if ((flags & (LOOKUP_RCU | LOOKUP_CACHED)) == LOOKUP_CACHED) From patchwork Sat Nov 2 07:31:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860025 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 1BF0445016; Sat, 2 Nov 2024 07:31:50 +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=1730532713; cv=none; b=Urw1aXGTaYT6UhAHiFkJTn9dBYa1WfSyzZm7rx+Nhu83dmSd+KJcpi11f381MVl8HOr02TRZiRi4jv5DjG5feUo9Izf9diHmmpTUGkm6zs7wVsdPOwaTQpCUE/K/3+leca0NLv5c8cvnxb465Dot8ZXVoEF99UZp9lwqPrRjvGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532713; c=relaxed/simple; bh=nqMcjBz8OfEZR+0v3ZB8jwQ8xqq1cB2f9ecGjIT/2ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mMTObQl0r8Db3CHjWQlPcZJPnYnjxj6+b4GRCxNLt4r/KVvCpBb5LmCFhTBnkWUBWGFPH2LmyoI22rM9oNsD31Z0NjUTPK3WZzUv3eNZ5cR/4B8QwY+Ny4lgggK+EyHm5in+b1hCV+CXe3CNBoLs72KluoBmzz0F4gSgqVGtz+Y= 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=sskV78z2; 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="sskV78z2" 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=RuuIHHAbSyNxuYTJWEVQRL3m+2YxijPnhKo52Q8Rk6I=; b=sskV78z2/+q8q6hSLzYMopxDaC oqg6EowVdFRE+bviTB+WeIu6i4FTw5yT2nuimgBWC9VeswHKkm6eMwS+8x8UUjvUlZRk9ENA3OJMa UjeY/vsW6AM2gNrlENNpxB9mFE1ieckfAe/ynm8rmQ7YedahdDWOZb/qIth9rK9EBc07sRSYTONtE Im5uu+xp7xVbiqcPvO3yLmwdLL7ulaShtZIAa5ZXZJaSoCnYeVT81+7cbOK391tG5PQD4kzQhjFqj ti8aPz6ZpsmjaiH2vx9xRid6Q6V57k9PAc/yAZ27Ls2LpSBr5CyCaKl9t/KykA96GeFyUXvePncdv +nBp5LQQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJF3-1XWL; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 02/13] getname_maybe_null() - the third variant of pathname copy-in Date: Sat, 2 Nov 2024 07:31:38 +0000 Message-ID: <20241102073149.2457240-2-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Semantics used by statx(2) (and later *xattrat(2)): without AT_EMPTY_PATH it's standard getname() (i.e. ERR_PTR(-ENOENT) on empty string, ERR_PTR(-EFAULT) on NULL), with AT_EMPTY_PATH both empty string and NULL are accepted. Calling conventions: getname_maybe_null(user_pointer, flags) returns * pointer to struct filename when non-empty string had been successfully read * ERR_PTR(...) on error * NULL if an empty string or NULL pointer had been given with AT_EMPTY_PATH in the flags argument. It tries to avoid allocation in the last case; it's not always able to do so, in which case the temporary struct filename instance is freed and NULL returned anyway. Fast path is inlined. Signed-off-by: Al Viro --- fs/namei.c | 30 +++++++++++++++++++++++------- fs/stat.c | 28 ++++------------------------ include/linux/fs.h | 10 ++++++++++ 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index aaf3cd6c802f..2bfe476c3bd0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -211,22 +211,38 @@ getname_flags(const char __user *filename, int flags) return result; } -struct filename * -getname_uflags(const char __user *filename, int uflags) +struct filename *getname_uflags(const char __user *filename, int uflags) { int flags = (uflags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0; return getname_flags(filename, flags); } -struct filename * -getname(const char __user * filename) +struct filename *getname(const char __user * filename) { return getname_flags(filename, 0); } -struct filename * -getname_kernel(const char * filename) +struct filename *__getname_maybe_null(const char __user *pathname) +{ + struct filename *name; + char c; + + /* try to save on allocations; loss on 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; +} + +struct filename *getname_kernel(const char * filename) { struct filename *result; int len = strlen(filename) + 1; @@ -264,7 +280,7 @@ EXPORT_SYMBOL(getname_kernel); void putname(struct filename *name) { - if (IS_ERR(name)) + if (IS_ERR_OR_NULL(name)) return; if (WARN_ON_ONCE(!atomic_read(&name->refcnt))) diff --git a/fs/stat.c b/fs/stat.c index 41e598376d7e..b74831dc7ae6 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -326,18 +326,11 @@ int vfs_fstatat(int dfd, const char __user *filename, { int ret; int statx_flags = flags | AT_NO_AUTOMOUNT; - struct filename *name; + struct filename *name = getname_maybe_null(filename, flags); - /* - * Work around glibc turning fstat() into fstatat(AT_EMPTY_PATH) - * - * If AT_EMPTY_PATH is set, we expect the common case to be that - * empty path, and avoid doing all the extra pathname work. - */ - if (flags == AT_EMPTY_PATH && vfs_empty_path(dfd, filename)) + if (!name && dfd >= 0) return vfs_fstat(dfd, stat); - name = getname_flags(filename, getname_statx_lookup_flags(statx_flags)); ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS); putname(name); @@ -774,24 +767,11 @@ SYSCALL_DEFINE5(statx, struct statx __user *, buffer) { int ret; - unsigned lflags; - struct filename *name; + struct filename *name = getname_maybe_null(filename, flags); - /* - * Short-circuit handling of NULL and "" paths. - * - * For a NULL path we require and accept only the AT_EMPTY_PATH flag - * (possibly |'d with AT_STATX flags). - * - * However, glibc on 32-bit architectures implements fstatat as statx - * with the "" pathname and AT_NO_AUTOMOUNT | AT_EMPTY_PATH flags. - * Supporting this results in the uglification below. - */ - lflags = flags & ~(AT_NO_AUTOMOUNT | AT_STATX_SYNC_TYPE); - if (lflags == AT_EMPTY_PATH && vfs_empty_path(dfd, filename)) + if (!name && dfd >= 0) return do_statx_fd(dfd, flags & ~AT_NO_AUTOMOUNT, mask, buffer); - name = getname_flags(filename, getname_statx_lookup_flags(flags)); ret = do_statx(dfd, name, flags, mask, buffer); putname(name); diff --git a/include/linux/fs.h b/include/linux/fs.h index e3c603d01337..403258ac2ea2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2766,6 +2766,16 @@ extern struct filename *getname_flags(const char __user *, int); extern struct filename *getname_uflags(const char __user *, int); extern struct filename *getname(const char __user *); extern struct filename *getname_kernel(const char *); +extern struct filename *__getname_maybe_null(const char __user *); +static inline struct filename *getname_maybe_null(const char __user *name, int flags) +{ + if (!(flags & AT_EMPTY_PATH)) + return getname(name); + + if (!name) + return NULL; + return __getname_maybe_null(name); +} extern void putname(struct filename *name); extern int finish_open(struct file *file, struct dentry *dentry, From patchwork Sat Nov 2 07:31:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860031 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 9FA82155753; Sat, 2 Nov 2024 07:31:52 +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=1730532715; cv=none; b=RvVonE77g2ePfi6WKufk5IBcu7POD6MjJj4hTGWKRHFjjDX1m8rJOU2p6kPezcTRZswMki1hskbDO4nianBygrAJuEGFOtNM0Iog/KDrCe5Act307xK5FuAjegTdsiWSsk/xjOubVQXh0h75gUK2tvJGaD7ysg8iv2AYwgw6SDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532715; c=relaxed/simple; bh=CJ8G1bPsyC/3Aia3l1WvbrclINRXhGnBiiRPsulrqts=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DEPN1RTTprXhPcQEeqjn3MAsfHsj8cJI0qz8Ekb/0i0mw8orEoZttatmVYJNRa1PV+3BBsfsbNPN8QGc17EI1NcdB8/DurxhsOtHUXKY9vut8QdjVA0on8pqfbiO3Jn1jy/FzLCPWcOLSZqH2FQLFGkUun2MNfG1j8UaRDw43e8= 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=JCfrv4ka; 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="JCfrv4ka" 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=/hP85QEGJwGor2x1uEYID+Fvy/bJN990nQDhbDJ138E=; b=JCfrv4kaZ7t9bpea54PUAO6yQj 1szYnhg2jToINbFYrXEufBzHXclIOeJWjXq0Zhw5wEOl8hToUw54NXPsVIfctCSdL/jrlJoWz/uFc uNa+VaZfNgOjN1tXhv/jYWLr0B2osrJCqPNhv/FxyNA1wRgAj/NWDmm9nRO2Rgox3C/hO18KC93oc 8fUxi6qwY0uD1KckBnea/nXSO0Nzsqz2wecjkhQUToxR3c2Nzp44cLyd40ozFae6ZTPbT+YI/r87o yziTzm8H9K1bPvyG7bcTXBjb6kh3cJ0MoG5/j1Tv+hDulEdbrC+NfvihpeNv+SmDhf353Jk2nTmVr w2heSYng==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJF8-2IHw; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 03/13] io_uring: IORING_OP_F[GS]ETXATTR is fine with REQ_F_FIXED_FILE Date: Sat, 2 Nov 2024 07:31:39 +0000 Message-ID: <20241102073149.2457240-3-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro From: Jens Axboe Rejection of IOSQE_FIXED_FILE combined with IORING_OP_[GS]ETXATTR is fine - these do not take a file descriptor, so such combination makes no sense. The checks are misplaced, though - as it is, they triggers on IORING_OP_F[GS]ETXATTR as well, and those do take a file reference, no matter the origin. Signed-off-by: Jens Axboe Signed-off-by: Al Viro --- io_uring/xattr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/io_uring/xattr.c b/io_uring/xattr.c index 6cf41c3bc369..4b68c282c91a 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -48,9 +48,6 @@ static int __io_getxattr_prep(struct io_kiocb *req, const char __user *name; int ret; - if (unlikely(req->flags & REQ_F_FIXED_FILE)) - return -EBADF; - ix->filename = NULL; ix->ctx.kvalue = NULL; name = u64_to_user_ptr(READ_ONCE(sqe->addr)); @@ -90,6 +87,9 @@ int io_getxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) const char __user *path; int ret; + if (unlikely(req->flags & REQ_F_FIXED_FILE)) + return -EBADF; + ret = __io_getxattr_prep(req, sqe); if (ret) return ret; @@ -152,9 +152,6 @@ static int __io_setxattr_prep(struct io_kiocb *req, const char __user *name; int ret; - if (unlikely(req->flags & REQ_F_FIXED_FILE)) - return -EBADF; - ix->filename = NULL; name = u64_to_user_ptr(READ_ONCE(sqe->addr)); ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2)); @@ -183,6 +180,9 @@ int io_setxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) const char __user *path; int ret; + if (unlikely(req->flags & REQ_F_FIXED_FILE)) + return -EBADF; + ret = __io_setxattr_prep(req, sqe); if (ret) return ret; From patchwork Sat Nov 2 07:31:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860021 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 580C778289; Sat, 2 Nov 2024 07:31:51 +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=1730532712; cv=none; b=eB6TH/kn1AdBiU5v4HV/ZWHlOOBbRj4prBBvKia5GSUTDnfF7KEupELI/GxVC+yqKiExB8LXY0gWQnxi4zLOZ4nh2be0AHsXPMM69UVogroT8w7QXgtojr3QO7WWaETFpgWqi+D+mEveZydWCDK1eicP0ntxyEcLb1EFUwPxfCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532712; c=relaxed/simple; bh=tQsnmqXW2K56L9+z+oxlf76cDjO82I5BaJt0mYZtnFU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IhZymxvNZLxnP7zFmbcHfaJs9hZhO9a1awRNB46egdG85GDJTcxTRLtxTrMfai/Pe2fmtlqeYI+ppS9VV2yOeSNnOc88gQXEhngAOMUJnJPqyn9WEOqSu2ymLAdRPJR3WJVr9VoBfzxUpKsUdslb5LPGpoGyGhbXAkmPFwYZ5Jk= 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=AuWhRiTB; 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="AuWhRiTB" 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=ehBlgSNmphaRaQWd8qdZFfTUDathgqXFkHwLaDfH6SU=; b=AuWhRiTBnZDeOy8WrMRhSSryoY 53S5iG0EvqNonTlG8PKexHPx4fVR0qHNviIaRXkPsSGsX0hdxmJdkfZ0dNsybk/wi/gEBnGQ6ji2L kCFHnErGLSFGi2CjyfCURwRIuDfWNL8Dt8PHp6lQhSBtus+9aWlbqFxICRRiPGk5BncAn8MKEd/mN hEF20MWhi0dvfxAfEh+EYwsHCVyN9U6pM1v1+9ODgtRQrFfewx95gWB5mk5TDv0E6A5zTZrbBFryV z0JO7mfLxbUx6tw8Hgrh9b59tCUJ6pWQk7eUzDAFyxxpzicgmqN3EePe/14TKJBptpCBtDoeMriVL n+D9BB7g==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJFD-2lOq; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 04/13] io_[gs]etxattr_prep(): just use getname() Date: Sat, 2 Nov 2024 07:31:40 +0000 Message-ID: <20241102073149.2457240-4-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@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... Reviewed-by: Christian Brauner Signed-off-by: Al Viro Reviewed-by: Jens Axboe --- 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 4b68c282c91a..967c5d8da061 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 Sat Nov 2 07:31:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860029 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 5993513BC39; Sat, 2 Nov 2024 07:31:51 +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=1730532714; cv=none; b=cohw/GoH0a5rCZLAjmTyfxMnkrrwRqmBoXTMIeDRTgza3XkYxU3gEO27fQgGBfyAcF/ssAKb759TwkXEgMkNgB/RvHsvfiX7+ngaNyWxXgJYgsKpppTEQOy14kzHptAyKUVbVQcOkeXR2r0h4moT9gZMY4VC4ifvYOMjrzLlaag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532714; c=relaxed/simple; bh=rZIixYCVAgXjg7EeXFhuy7MGoTFaqUAyWO43RarR0es=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UtFIJoAchLn/mb6/QxBzchpOBU4/4eVcKug8XeKYuTqO+TVvpcrqwElOPa3ob6llf9Q/xunrOFn7XfYmYouzbIRTWNDL6uSaTi+eT/s3zUQgdWJU6fbiw8BsqjnIy2dAN1gxyfZ59xJlAMi0mMx6gA8Jb6XABW7EO2lg/85I9PQ= 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=kd0+eeQg; 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="kd0+eeQg" 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=uTtnVIFSfaEcDJ36yf/YHOGeZdYKnakFbEqlgGoMnro=; b=kd0+eeQgGc1mIvIRIx7vH36Q9l 6Phkeh1dRj9awITXthxryFxj/zcmW4JX5I/tHdIxcOGwsJ912aph9Nh4mry5yJ3/GlzSZOZMbp7UR ZFYQj7W8IxEsn6p5jf527kPzQ69j9qIc63FUic/cV1IYBuvGx8GFz5/8hl4DPVxBrW4JE+xS2Pyl9 nzy9NiUR6vaokI2uXQTUUsCbEOxEdXqN9GGDJ7ZIWnndaIs8xa08lhKoXMi2cvIRYyZYz7b0z1WLE 2M7nKd+pPkWGU+xEJIVCqQEfN7bKMZpxtQMjCH2yRXW6VkGtcjHWSaCAdibCFLlfasrzDx6s0bycI N6WCQL4w==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJFI-31pv; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 05/13] xattr: switch to CLASS(fd) Date: Sat, 2 Nov 2024 07:31:41 +0000 Message-ID: <20241102073149.2457240-5-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- 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 Sat Nov 2 07:31:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860023 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 7159313C914; Sat, 2 Nov 2024 07:31:51 +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=1730532713; cv=none; b=O3upnL1k/eUJmi3c71xKjCWNCTo5R3atSGuF1FpyxrLpPuebLcmT7ktOxkMBZPjo4NofVYAKm4NTfXwPtpp963gG7XuzE71wbObmTC3OwieWDxvhJTA4HjXUjpY2AJL9/SVj32YraocXA3Qvkr6qd5YuQjqNdEpRCFF7pXpRgNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532713; c=relaxed/simple; bh=KZIdB10TNGT1qv2uszYxOzMneBQkka9o/T+Vt7ucH7A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IiY6e3VBggDGtguhPLbtr0Tlmdgw1hCYJ4bw5SRcClsWY4+dCU2MLS2eS/hTWfULz2NDkUzw7dGNpLudF7VK/njh6aHPDphPHCYUMfrFJO1EktB4RnhcqRJdIknKaiwmKUQgoSNhrjiZ2E2B/2UhC1uKBWrpPwa1ZGA9KIaFheU= 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=DVdl+kRG; 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="DVdl+kRG" 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=q0MuLEeJwSLEDP/uaE9xqULL5Bg/hzF02oMQL0NWn/A=; b=DVdl+kRGmxpAaseHah1CpTPunD xNtuX0yvaJCnx01p1Vo5Wl5o4ssUHrFK3WsQjo+9w07IJx0XR2bMlHAzJOf75xn4kL3mdaUTpYS15 xVapW8kMEexUKbzotNIyRYIR7pQttTTetUZnLcX+NMqtDq4qL+OLVOwFwI8Hn2LtLVUWbTtkL73LK J7AWFjGlPsr3YIUMcvf8GvmM6DCF0ThDvXUYaopZQ7OmkmRK1/0xytfAFftQe7/83GQ3B/6Dx+uX9 49FBnLUyztn7Y1D9gq7qdGUvFKCyY4eGnm5RmiighONZRExaBc5HoqG4J9l0/MmyckVlwCL716tdJ eVpmVMbw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJFN-3LGS; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 06/13] fs: rename struct xattr_ctx to kernel_xattr_ctx Date: Sat, 2 Nov 2024 07:31:42 +0000 Message-ID: <20241102073149.2457240-6-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@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 --- 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 967c5d8da061..f440121c3984 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 Sat Nov 2 07:31:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860030 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 BDB6C1448C1; Sat, 2 Nov 2024 07:31:51 +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=1730532714; cv=none; b=Z+yxuPnepy1QUKK6ONyE5dT5M8ikl7i0mLagmG05tdVBXHbtuVjlVP3OHUqpJ/TbBQke4XdCOHgn+R3EnMowMK4A32DDcZPX/kh+C7kWpVynK/Oc7xDvlOfiUT2IKLMrI7/5vzRDknSfi2+eIIo5s8JFnAXJk/RnBD+C93aKpgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532714; c=relaxed/simple; bh=zQQnTZimkNdhhEgtbCqbtkYZqWPqNugT62UQir086FU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jlgh9ycwRnAwOvQ/aZMwbl+AQd3It+cNAfPiJQOebvQlvY5B1qAF0diMfTgA2+vBdigDmwuFBDmzumNL3Qz6pklrcu9+2CKTSqEsuQNahuoRugYdFdQddlWtSAPrWCwu2/zhIF0qC5GpmcNb4r5AEo3RbJ/wYDbNpwI4CMaNdg4= 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=MKwDjBw1; 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="MKwDjBw1" 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=VVU5A6PnIxPNnXJuEEHW+GW30MbPjzG1/fG7IlvwPPI=; b=MKwDjBw1sBmmI/D74EgozmiWm0 fpIxTIW22+42Pd8/PoYYZkv9vWqwweNjspaDDcpRn1aPT3dxE5iWRs91JSrNKk/yx0v6kftuJecd/ oWoc3eDVTZHw/HeVTY+nva6b3oqe1okHdpco+o+gU9BzK42lPLxx9OzxCTk0TLwlewevlNDsbbSJM 2fB8VO9iqnQdp+PSEsR7E8mIxGcfR1vlENRASEk+mSR5lPpztxOF2w/q6YkhC48Fak3/88UNamZy7 c9T0kBLU+eT+A46fwhCD1SZPrPufBCXzJYgDRqKg8cDEXRV7QRsyxFy+x+58UH1cNOL6/s/Z4Lnnd +7IUydkg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bt-0000000AJFS-3qTt; Sat, 02 Nov 2024 07:31:49 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 07/13] new helper: import_xattr_name() Date: Sat, 2 Nov 2024 07:31:43 +0000 Message-ID: <20241102073149.2457240-7-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro common logics for marshalling xattr names. Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- 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 f440121c3984..0b3b871eaa65 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -62,11 +62,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 Sat Nov 2 07:31:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860024 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 BF1BD1494B3; Sat, 2 Nov 2024 07:31:51 +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=1730532713; cv=none; b=CyBgF97N5jZs05iJHVEhSoDSYhHq420DEI/mIGEUEoya3CH/+SOjMH/z8xSL+jEGHnlWlV8tYbJ3u6u/e8ZXsuQwC6NOomy6lCYOzGQdZQOPpeZtjLZAqY79yj47mJMYu15gnGqycfeUiQnlZpww2kp0I2xrGEROA1rZxPfdu2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532713; c=relaxed/simple; bh=iET8QBRBtqoalPoanDAyr5M3rnSmEUjI8VaTE7XAbzs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DCLDbvSTiRGswnL6EvAJOLivij7BF7fKmnY2Bo5LwnCHkKrDcvLGvGFXF2b2Atz6NSuxTaOdMBm/Jb5hw9hrCNlRz1Lpd/PWXMpG+RxJrWN0uhI2e3H51aaNkM0dbsN6eXXnKUU69jy8TBJ2BzYmcTZ8UDXw1vnmT8yTG6av724= 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=eh3AmFqN; 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="eh3AmFqN" 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=WcjWMPIYgNwVesjZZtqGTFXJQRfHhE/DdzXc440ft2Y=; b=eh3AmFqNxYeQn+8Enyr6pysMoe 08jJtNKWQkVt3lZatFKdOcfmmb16lE9aZCl4/OPJ2UmSqz1uZXccmj7Keyr4MkH83H5dLPso4nrI8 xZcGWo//GfAv/ljcafIe18LxdjhnZJQX4ZhrA5M1O0GSMxNS0dTP1/k75S823ycV++8RRYR7hADMr gtW2kkuXdOP8SEKyH5ninJQni0MKgiBgo3jboUrMGDlcCgY70Ut0y6AYWlK9r82KfPeJrS2wc+Lae 7tnAkUsJEzb1MfjoWo+jcAoMOMVQAmgglf6jVrF4QF0HMD01O7GBLrtg3qTaqpW1cAUttloxCF789 5rhrN0AQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJFY-0Bcn; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 08/13] replace do_setxattr() with saner helpers. Date: Sat, 2 Nov 2024 07:31:44 +0000 Message-ID: <20241102073149.2457240-8-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@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. NB: putname(ERR_PTR()) is a no-op Signed-off-by: Al Viro --- fs/internal.h | 6 ++--- fs/xattr.c | 69 ++++++++++++++++++++++++++++++------------------ io_uring/xattr.c | 41 +++++----------------------- 3 files changed, 54 insertions(+), 62 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..38bf8cfbd464 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,32 @@ 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; +} + +/* unconditionally consumes filename */ +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 +672,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 +731,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 0b3b871eaa65..2671ad05d63b 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -187,12 +187,10 @@ 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(path); - if (IS_ERR(ix->filename)) { - ret = PTR_ERR(ix->filename); - ix->filename = NULL; - } + if (IS_ERR(ix->filename)) + return PTR_ERR(ix->filename); - return ret; + return 0; } int io_fsetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) @@ -200,28 +198,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 +213,12 @@ 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); + ix->filename = NULL; io_xattr_finish(req, ret); return IOU_OK; } From patchwork Sat Nov 2 07:31:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860026 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 E0B5014B965; Sat, 2 Nov 2024 07:31:51 +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=1730532713; cv=none; b=SdIE13G5Doq+m1n4n9W2s+9ftdxSQ5vSRvh12XKh5DVXJm7ZLC4vysnLpVw1b3wzgSw2UBUK3AG2N2uW3+43sjIyZWF5UfmZtvVKE4s9EjVe0vhUbC6jr4lKJC5Qp0dz651sEzYJdVoUJ3uRRkVXtriX912dIFKZEOHAD4k42c0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532713; c=relaxed/simple; bh=Q0bq6g1WYuRXDA29tV5jeRWut8wFRc32lj0esrOc7VM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DlVH9Oj6++w0VgadQnF5M0iXXGYjZwjIK2ytblFmeAS3wN5GmBYhQFrWh3wYv7I9v3mPKR2+593RmuEL7vKOinMxBir7ZMLkXZDepw//6IYHIrMDlyX9Z0hIBcQelgeRpRt08q4udXKGAt0k1YmfGME5jEruVa7kmMDadA4s6aA= 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=jL0gX63+; 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="jL0gX63+" 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=RLdqrzxshGAwc4Fl6p/LGqqBkZF/ZdDToNXKS8zEB5E=; b=jL0gX63+PqNfNWrSY4EO4DedV0 Wjb83E2bpqXgfSK/3j+KKusWfAbfLC1awX/hEaBvUGEPjlHI+VUVMM1pm7UU/mhovnz26dgoxameq Mtfk1GwSIGhEKJQmXbIivxpNas7yqqJe/K9PrO2ajw3iVxXMOgJC9L3AeUkBCT/2pNS6v/ElN8SdH /eCaXhk0OSn/qKflumNlBNbtQ4xEYENlPBhzpvrMpJJooBXduvzTonsiSwLyzdfmS8I9gQzs/3jN3 CVpnXosFZbMVfu3/UDV6P09V+KOnp+9c32FRTrOMA56vPWeA7vzimyUng7kSU1kmUcoBBPvnQWJNO +mHtYXfA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJFe-0zIV; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 09/13] replace do_getxattr() with saner helpers. Date: Sat, 2 Nov 2024 07:31:45 +0000 Message-ID: <20241102073149.2457240-9-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro similar to do_setxattr() in the previous commit... Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- fs/internal.h | 8 ++--- fs/xattr.c | 88 ++++++++++++++++++++++++++++-------------------- io_uring/xattr.c | 31 ++++------------- 3 files changed, 61 insertions(+), 66 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 38bf8cfbd464..d55f3d1e7589 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -744,27 +744,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 @@ -772,52 +773,56 @@ 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) +/* unconditionally consumes filename */ +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) { @@ -833,13 +838,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 2671ad05d63b..de5064fcae8a 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -51,7 +51,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); @@ -94,12 +94,10 @@ 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(path); - if (IS_ERR(ix->filename)) { - ret = PTR_ERR(ix->filename); - ix->filename = NULL; - } + if (IS_ERR(ix->filename)) + return PTR_ERR(ix->filename); - return ret; + return 0; } int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags) @@ -109,10 +107,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 +115,12 @@ 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); + ix->filename = NULL; io_xattr_finish(req, ret); return IOU_OK; } From patchwork Sat Nov 2 07:31:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860033 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 EB7BA14F12F; Sat, 2 Nov 2024 07:31:51 +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=1730532716; cv=none; b=FMBXWpk72J7pSqcAjWWTgULoGFHSk8IrmfJNeVui/mNhZj0XHy9t3ZuoX7ackaIRg7ATKZgbsUhWGaw35z3zJ34GPKc/6lZzunobSQAExpXSaH3IG3bzzglPZVwNNEwUcNXk2mqEWXowzihOn+7c+IhnTf1p9fbD4tbJocsJpLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532716; c=relaxed/simple; bh=LkpnveijF39+X/7mCS0EQnhVIUc56Yi3rPaPtn0Du8s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QE1V6efH1BfaRoIuw+sn6zSXY9j6iIgYfltRGbn4OMsFehPmORn/ql9ZKFkcVN18Zb32kxI+3FnqoTzcqsRYf0ImK2u3cwyfDvbgjMin9nMWP8oKIvXCIjrcgawvNilz/27w8VYTA3NWFphsFXLC9Wc5wwiCdImnt2x5jWPhC4M= 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=iYzPTdNb; 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="iYzPTdNb" 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=YEoR7ZhCfUEbk+5+IEhniLUK6GKI/myN5Dr6DI5ii+8=; b=iYzPTdNb3FGQjIWOOgjzYChuSC vkN6KHIrqrvrffPVZuEj+J1Z5nBPWJNK7mz7aUlAvof+4o2DKNbv/dMBMi3VLLLS9dWIusN9H2TV7 6wiX4RkUCFpGmkSi02//GrBkkMgIN7eKO5A58kiZ7tAUyusAVfrCiadrE1Cy4Gcw883XP2dFnnVfq oWIGxfQBcu0DPh5xmAXNO/SaV8O25CV/NVqDcmzg+y1jl2W2muzTjk0fBkhhPgZQwc1Ogvm6Z7OVx HPrp3bhWDokUlfRnqfWhk7xbqXYZNe5CPi+YlWyd1lchwD1JdInade23qDHJq80SSLt5je0qC5jbh zYZpjM/Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJFm-1dHH; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 10/13] new helpers: file_listxattr(), filename_listxattr() Date: Sat, 2 Nov 2024 07:31:46 +0000 Message-ID: <20241102073149.2457240-10-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro switch path_listxattr() and flistxattr(2) to those Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- fs/xattr.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index d55f3d1e7589..988ea737ae7e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -888,24 +888,43 @@ 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); +} + +/* unconditionally consumes filename */ +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) { @@ -924,8 +943,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 Sat Nov 2 07:31:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860028 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 286B114F9F9; Sat, 2 Nov 2024 07:31:51 +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=1730532714; cv=none; b=sV47GjrSL+MYCRL2N48eGegyCLKWv5DvljgPoKXIEsw3XtNk3eINYQoSDZ4j0CmDB4ZyloYRckqcqAe+bU/c2mT5YkcRlkiHXFC2ImYCZxVsixLGS3aaTYQYqDcDXvQJxtNqvNzbKCzGuHhRQg4RXi2ZjpYP880/xZRlrwDXPyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532714; c=relaxed/simple; bh=Cxns49oeB/jZqnRQmZBupXFGxbal6058CA2EL4Y2l/4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I5Xf6rnJ740JhAcblus7Hy2rT/9UWBOf0h5w9v4Kzy2nxjxLMHy5UbJjU+taCjVc2SLzSynFIDGGQO/r4S89EtFfu1xv3tvntTF4QWwpIH8wleu0540y63uRODXyRxIrVn4c60glaYp+fRey5vT7k3X7EIMwdDohK3yhp7P6I1s= 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=gR0Cz1p8; 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="gR0Cz1p8" 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=Rew3+6cBj+9i5jhdTRZP9TEsWMPPsZB7QXK94fQIrnM=; b=gR0Cz1p8TYHA7s9m7Oh6IKbsdP I/BDa4Yw3OBkngQaTczGGj+XKOyG40pD44fjyapAcEtJ7O/kN9YTR5JlJ/KnyoQWXGNa+kXVqGfTW 23OCisg+5J4ag8XqV37OmJjkFtKUP/IBdW9xG8gPkS84wXN5+ZPNWOjXebtjOCzh4YKDt3iM4XiR9 oOk2mciLFMh3dIalWeyLbwQQCBMYg0OtRF24WdlssTIYL0DQhs6oI7XRH435aJWDeHmePLjrxZ061 RSbd/ppF/089Z/A7oZ7+lORwToA30TL0hbZJB/wZhGM3MGPF6Y6PXUWdxSDVDG/LON+7tjBDjtQ6M hKEfxwGg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJFs-205Q; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 11/13] new helpers: file_removexattr(), filename_removexattr() Date: Sat, 2 Nov 2024 07:31:47 +0000 Message-ID: <20241102073149.2457240-11-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro switch path_removexattrat() and fremovexattr(2) to those Reviewed-by: Christian Brauner Signed-off-by: Al Viro --- fs/xattr.c | 53 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 988ea737ae7e..b76911b23293 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -957,23 +957,33 @@ 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; +} + +/* unconditionally consumes filename */ +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); @@ -981,9 +991,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) { @@ -1004,19 +1029,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 Sat Nov 2 07:31:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860032 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 39C6F1514EE; Sat, 2 Nov 2024 07:31:52 +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=1730532715; cv=none; b=nzoymuyvKaqJ3Njmz4QTrCMPHddF5Jr2gH+gffbmWKltw3HlB1+O6s5cZQeAU4nqZGDKGoydJt4G61uK9mLjf0XVEAZENaWCeSVdd664BXtmRhRs6lLH+0jSGLOf36ELGVrQvE9Mi2g0tumrKJRsvbKsU4mTSi++r7rmCRsjMXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532715; c=relaxed/simple; bh=2pAlsr0vyFestCmIqZGkmxqHtdt3YG9gNPfNt45O6bk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=q73Kywzrwp+XUx7KhtbjSMELsLnRnnas4Z8sEI55Aflq7jn41HsZ3VyAaQtO4bR0ZVnXwG+n17Frd4zzzTn7UIb/GRdsrBgj+UE5RDP+WBHVXOG9hAMhr6pHk4Vxt3Vjjr6vqvr07WAY0U44f/9RhdM2W5qQE8AcZgxB0FHe08U= 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=wDnT9cgb; 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="wDnT9cgb" 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=U6ZS0hCJzHg1lHe88i48bRMkxS03JUnpcqTlwY74ouM=; b=wDnT9cgbdRuFE9v8pmNVPKGAHg MMya+tqabMkCxn4hmqaygeZbf5OjcmOwcqDAw687qb2fuYGzrm0gOx+wQ0xl1GWoHZTh09dUL6Y58 ZindSSnSiBULdKIjrcHRTgo5GDJmTy8j/30gdypxPXaHXSZ1YkhOjfZ5fa8RDLvmuAEsBNGxHvUBG Nzq3RIQWqI/U74wAFwq53fMeVSUWVsPgQyO1J60AwF2Uu+EGYH5qjgUH+OVAYtC9XcpNvPXdvsyHq taWNS0MBVeWgQ/6MDEVxs1qABmxeq4vhZjmpBcwIKT885A4E0xMoEnfObrWxGQovPwLJ99HQi7m2T CbNDXUZg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJFx-2EkN; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 12/13] fs/xattr: add *at family syscalls Date: Sat, 2 Nov 2024 07:31:48 +0000 Message-ID: <20241102073149.2457240-12-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@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 Reviewed-by: Christian Brauner 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 --- 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 | 245 +++++++++++++------- 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, 260 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 b76911b23293..deb336b821c9 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -676,69 +676,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_maybe_null(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); } /* @@ -804,11 +825,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, @@ -816,44 +836,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_maybe_null(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); } /* @@ -918,32 +966,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_maybe_null(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); } /* @@ -996,44 +1062,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_maybe_null(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 */ From patchwork Sat Nov 2 07:31:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13860027 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 4BBA9153BF7; Sat, 2 Nov 2024 07:31:52 +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=1730532714; cv=none; b=JKSoCieAmenqosUWEzgC2C/3lRfSI6lhc4ENoVZUe/6HjyujJI6ngK8E9KIwemN6RipMtCu6P7hEChs7UgMLvtUn2RLzuYRs/rjOxR2IsEPRxNaUfLhMnh6NtG0BAHvEMHBerAzb0546zJlLWX8qoCSViz96x/fN1A/h806cpa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730532714; c=relaxed/simple; bh=PoqTX0mDAe6hP72ChBxF/WuOoSBH0ddySuyGaOqiU0o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RK82MZGSag11bqguImoTZ0BJxudiBF67p7rIlKqbqXkeqPf9MXWPS5GW8veiLmiRwbktWXjVA4GHKf2dXLJ+TM7h+18Kn/zjmpSegQsHSGB2yQSmbaIhBoGr2C9YyQSGs+tojS5O47o+G7PACGkghdCy9S/zeS20lNSjXpkIskU= 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=riw0HR2X; 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="riw0HR2X" 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=zhqXfJhI6uiekzNJ4IN4o0rOS1QxLJxd9xlxoLiD+h0=; b=riw0HR2X3sXHhO83/m9q/D33YS OuRvrqpX6gz1ydGWeboMyVno2NbwCaHBkKgnLhxjaQluXXxnHU7/F+saZP6wtwPbKYdqjuUuGDjmi 2Vhut4iJQKtnQsN3+1bhDigC2FA12pvIdwXP+ub1bwkXwOtF4prxmjLXAf/3+0yTRrAI8+dHEilS2 A3GHK0MlStgho6Yo1HoEka3MfeCrDrTHQAVQn3DLVKw0vwOoqN/9LPROW76OLtCcMDpjeroo2sUQa Cd76RVVpdNaGOaE0DOHmTsIgsPnliImYKCteooO7brdA8eG+CcBigDptAOfYmHERm/LtUqfR2mEDM iJ6Pb2aQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.98 #2 (Red Hat Linux)) id 1t78bu-0000000AJG3-2jw1; Sat, 02 Nov 2024 07:31:50 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , io-uring@vger.kernel.org, =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 13/13] xattr: remove redundant check on variable err Date: Sat, 2 Nov 2024 07:31:49 +0000 Message-ID: <20241102073149.2457240-13-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241102073149.2457240-1-viro@zeniv.linux.org.uk> References: <20241102072834.GQ1350452@ZenIV> <20241102073149.2457240-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: io-uring@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro From: Colin Ian King Curretly in function generic_listxattr the for_each_xattr_handler loop checks err and will return out of the function if err is non-zero. It's impossible for err to be non-zero at the end of the function where err is checked again for a non-zero value. The final non-zero check is therefore redundant and can be removed. Also move the declaration of err into the loop. Signed-off-by: Colin Ian King Signed-off-by: Al Viro --- fs/xattr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index deb336b821c9..02bee149ad96 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -1142,9 +1142,10 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) { const struct xattr_handler *handler, * const *handlers = dentry->d_sb->s_xattr; ssize_t remaining_size = buffer_size; - int err = 0; for_each_xattr_handler(handlers, handler) { + int err; + if (!handler->name || (handler->list && !handler->list(dentry))) continue; err = xattr_list_one(&buffer, &remaining_size, handler->name); @@ -1152,7 +1153,7 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) return err; } - return err ? err : buffer_size - remaining_size; + return buffer_size - remaining_size; } EXPORT_SYMBOL(generic_listxattr);