From patchwork Fri Nov 29 13:02:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13888644 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AC7B219E82A; Fri, 29 Nov 2024 13:02:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885363; cv=none; b=c/34e0WsrHPq3okBHuL/r0KZ/Zza8DIEBb/DeAFzqupDl3gxOUMYT8GLagkiAmCnNdGtDTWs1TT8S9uH9t41c7RoE+AAO789a678d5OEq6YFF0Tyk4dOmqNypAhPSITAAwD7zSydrIEP13CI2rqa2v+lEExSId9TsZlRsrA4otA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885363; c=relaxed/simple; bh=ZtEOfSxutMiKP+fqJthkkwAmwUVN4TMIiXdhF9NO+S4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cnzIp9oQQCx7GAtsPrJdexZuyOyzzsGvaL4ke2AS2lBmr/snn+CXbgIrZMuMkUvwt8DY+MAzAAhKhP6uv/4aqHTCVeEJEdxYSTTBA17vQfXyNT+qfHjVYqmExjFbyQ0yEx3ORFe35mzkG32AQEuB73AahQ6/g5pGL3w8pM/hdCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZSTLZMgh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZSTLZMgh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05E6DC4CED4; Fri, 29 Nov 2024 13:02:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1732885363; bh=ZtEOfSxutMiKP+fqJthkkwAmwUVN4TMIiXdhF9NO+S4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZSTLZMghiAyMvwKU/gsJkRxBtOUpXDF0ePFFrmt48dbmsMHTtr34mW/6rIafPWr21 Y6povQeUtE5dDtW1hUkqAeC2NPkpoxYO0thheoKm56W+AggL6yIP7cU1jgY2apjX4/ 782BcN+6AJy/1du4enUFoC+js776G7HZdrBnX6REwIpvle3ZQAI4/wra+XkconSheP /nbpe2V+fXwuedV5cyVoLqxplzl5qNsXhH9k57FGvszBR3m52OxsN6gNQAP1vc6I0g ghvyM3T5tcquHDPWh6pZi/LT0Tfy2Rd/xQDIyAFIc7KKDDBce1rQc3UZV4Rrknc3Ag UAEBiD2ykrdUg== From: Christian Brauner Date: Fri, 29 Nov 2024 14:02:23 +0100 Subject: [PATCH RFC v2 1/3] pidfs: rework inode number allocation Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241129-work-pidfs-v2-1-61043d66fbce@kernel.org> References: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> In-Reply-To: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> To: Erin Shepherd , Amir Goldstein , Jeff Layton Cc: Alexander Viro , Jan Kara , Chuck Lever , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=5719; i=brauner@kernel.org; h=from:subject:message-id; bh=ZtEOfSxutMiKP+fqJthkkwAmwUVN4TMIiXdhF9NO+S4=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaR77s69IXdr3XF19UTVLXsafSerFpuLHPZ6llsodmbX8 y/6bzkKO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACYSto/hv9femO2V2x5wa315 +0Np3pUdK1bOXsbOrXjHsOKxTcQ75zhGhjex3p9FT2xeGP2n9eMpzU+FFvN3vI/03SX8S32X9Se DDgYA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Recently we received a patchset that aims to enable file handle encoding and decoding via name_to_handle_at(2) and open_by_handle_at(2). A crucical step in the patch series is how to go from inode number to struct pid without leaking information into unprivileged contexts. The issue is that in order to find a struct pid the pid number in the initial pid namespace must be encoded into the file handle via name_to_handle_at(2). This can be used by containers using a separate pid namespace to learn what the pid number of a given process in the initial pid namespace is. While this is a weak information leak it could be used in various exploits and in general is an ugly wart in the design. To solve this problem a new way is needed to lookup a struct pid based on the inode number allocated for that struct pid. The other part is to remove the custom inode number allocation on 32bit systems that is also an ugly wart that should go away. So, a new scheme is used that I was discusssing with Tejun some time back. A cyclic ida is used for the lower 32 bits and a the high 32 bits are used for the generation number. This gives a 64 bit inode number that is unique on both 32 bit and 64 bit. The lower 32 bit number is recycled slowly and can be used to lookup struct pids. Signed-off-by: Christian Brauner --- fs/pidfs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pidfs.h | 2 ++ kernel/pid.c | 14 ++++++------ 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/fs/pidfs.c b/fs/pidfs.c index 618abb1fa1b84cf31282c922374e28d60cd49d00..0bdd9c525b80895d33f2eae5e8e375788580072f 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -23,6 +23,59 @@ #include "internal.h" #include "mount.h" +static u32 pidfs_ino_highbits; +static u32 pidfs_ino_last_ino_lowbits; + +static DEFINE_IDR(pidfs_ino_idr); + +static inline ino_t pidfs_ino(u64 ino) +{ + /* On 32 bit low 32 bits are the inode. */ + if (sizeof(ino_t) < sizeof(u64)) + return (u32)ino; + + /* On 64 bit simply return ino. */ + return ino; +} + +static inline u32 pidfs_gen(u64 ino) +{ + /* On 32 bit the generation number are the upper 32 bits. */ + if (sizeof(ino_t) < sizeof(u64)) + return ino >> 32; + + /* On 64 bit the generation number is 1. */ + return 1; +} + +/* + * Construct an inode number for struct pid in a way that we can use the + * lower 32bit to lookup struct pid independent of any pid numbers that + * could be leaked into userspace (e.g., via file handle encoding). + */ +int pidfs_add_pid(struct pid *pid) +{ + u32 ino_highbits; + int ret; + + ret = idr_alloc_cyclic(&pidfs_ino_idr, pid, 1, 0, GFP_ATOMIC); + if (ret >= 0 && ret < pidfs_ino_last_ino_lowbits) + pidfs_ino_highbits++; + ino_highbits = pidfs_ino_highbits; + pidfs_ino_last_ino_lowbits = ret; + if (ret < 0) + return ret; + + pid->ino = (u64)ino_highbits << 32 | ret; + pid->stashed = NULL; + return 0; +} + +void pidfs_remove_pid(struct pid *pid) +{ + idr_remove(&pidfs_ino_idr, (u32)pidfs_ino(pid->ino)); +} + #ifdef CONFIG_PROC_FS /** * pidfd_show_fdinfo - print information about a pidfd @@ -491,6 +544,16 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags) void __init pidfs_init(void) { + /* + * On 32 bit systems the lower 32 bits are the inode number and + * the higher 32 bits are the generation number. The starting + * value for the inode number and the generation number is one. + */ + if (sizeof(ino_t) < sizeof(u64)) + pidfs_ino_highbits = 1; + else + pidfs_ino_highbits = 0; + pidfs_mnt = kern_mount(&pidfs_type); if (IS_ERR(pidfs_mnt)) panic("Failed to mount pidfs pseudo filesystem"); diff --git a/include/linux/pidfs.h b/include/linux/pidfs.h index 75bdf9807802a5d1a9699c99aa42648c2bd34170..2958652bb108b8a2e02128e17317be4545b40a01 100644 --- a/include/linux/pidfs.h +++ b/include/linux/pidfs.h @@ -4,5 +4,7 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags); void __init pidfs_init(void); +int pidfs_add_pid(struct pid *pid); +void pidfs_remove_pid(struct pid *pid); #endif /* _LINUX_PID_FS_H */ diff --git a/kernel/pid.c b/kernel/pid.c index 115448e89c3e9e664d0d51c8d853e8167ba0540c..6131543e7c090c164a2bac014f8eeee61926b13d 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -64,11 +64,6 @@ int pid_max = PID_MAX_DEFAULT; int pid_max_min = RESERVED_PIDS + 1; int pid_max_max = PID_MAX_LIMIT; -/* - * Pseudo filesystems start inode numbering after one. We use Reserved - * PIDs as a natural offset. - */ -static u64 pidfs_ino = RESERVED_PIDS; /* * PID-map pages start out as NULL, they get allocated upon @@ -157,6 +152,7 @@ void free_pid(struct pid *pid) } idr_remove(&ns->idr, upid->nr); + pidfs_remove_pid(pid); } spin_unlock_irqrestore(&pidmap_lock, flags); @@ -273,22 +269,26 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *set_tid, INIT_HLIST_HEAD(&pid->inodes); upid = pid->numbers + ns->level; + idr_preload(GFP_KERNEL); spin_lock_irq(&pidmap_lock); if (!(ns->pid_allocated & PIDNS_ADDING)) goto out_unlock; - pid->stashed = NULL; - pid->ino = ++pidfs_ino; + retval = pidfs_add_pid(pid); + if (retval) + goto out_unlock; for ( ; upid >= pid->numbers; --upid) { /* Make the PID visible to find_pid_ns. */ idr_replace(&upid->ns->idr, pid, upid->nr); upid->ns->pid_allocated++; } spin_unlock_irq(&pidmap_lock); + idr_preload_end(); return pid; out_unlock: spin_unlock_irq(&pidmap_lock); + idr_preload_end(); put_pid_ns(ns); out_free: From patchwork Fri Nov 29 13:02:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13888645 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7EC5A1990C9; Fri, 29 Nov 2024 13:02:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885366; cv=none; b=jU6ppsDvG+1Hkw5GESejzyWpXlb915AYHIDQDIgXESDEp8YB0o/Wv9U6TIIBzSS3iWAz921zGZyVch+OFgbFgzry/ry7XCrWXYt3whRtsoEk9Wg8+v8ZKEru8M5Vehdcp7rQAa9x2/kZ99LvirNycwC/aHBG++WK8UkRD7mBh0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885366; c=relaxed/simple; bh=1J6UPxtILhTxdAU/YMMXiqJEhnPoxJ1JRHaUYLuJeZw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JrOZ69pizb2wTlbHlAKl4XIO5EaGleQ2uSdTLMNKvmJq4f9oQTc+uwO1vibNhoNPp1yFi6vAyrtMPgcoty0SoYhuaG37l0B8ufV3JM72F4W1yIK6hu8SRn087A2/iZsRjipCh4Nz/tjRp+9Cc3BfsjVulSgYlAUbp3QPGZPXe/w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VudsppRh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VudsppRh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB7B3C4CECF; Fri, 29 Nov 2024 13:02:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1732885366; bh=1J6UPxtILhTxdAU/YMMXiqJEhnPoxJ1JRHaUYLuJeZw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VudsppRhDcZTvMCxd3Ztdh6/34k2uLmBbngDpI5HUlH7Ol9RIaeRGZun23ahma538 rSUJmuT4JdbiD2L7IQXfMaS3u7cmJxgJEylrk82DsPPusZUB8oZNl8IOIs3ELm+99I Z0IQx6woSRx61LTgTkbLUelRT54IYh7tf0HZSqxzc9F3vBijLPXbDQ6TqC0vm3G4Kj qaubtEYs0UlI3KZH14iMqy1GVfP6QJamf67SGJ4c5lNxMFNvuBgN1Qxc0jeeBQphP1 wqEgUoAV+iHSL8UGbsuHyzZrX8MWGjs2Loy2Y73nT/5Aw2WT+T/j4pUoZ/rL8Ici4E CwDyyKgi08S7w== From: Christian Brauner Date: Fri, 29 Nov 2024 14:02:24 +0100 Subject: [PATCH RFC v2 2/3] pidfs: remove 32bit inode number handling Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241129-work-pidfs-v2-2-61043d66fbce@kernel.org> References: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> In-Reply-To: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> To: Erin Shepherd , Amir Goldstein , Jeff Layton Cc: Alexander Viro , Jan Kara , Chuck Lever , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=2419; i=brauner@kernel.org; h=from:subject:message-id; bh=1J6UPxtILhTxdAU/YMMXiqJEhnPoxJ1JRHaUYLuJeZw=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaR77s5NlH7auXrjs8ObrkQoLnpVLB0b45taom9Z48EY3 LAgOP5kRykLgxgXg6yYIotDu0m43HKeis1GmRowc1iZQIYwcHEKwEQmWjP801h+aIaVtXrl94ly r2dvjV++bvcdNsXUvOJwy+R7RqEWtgz/i55ZF+z8mJj1xdx2Wt2h1L7m0OTmqv8Wf+8+Xsa45mk QGwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Now that we have a unified inode number handling model remove the custom ida-based allocation for 32bit. Signed-off-by: Christian Brauner --- fs/pidfs.c | 46 +++++----------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/fs/pidfs.c b/fs/pidfs.c index 0bdd9c525b80895d33f2eae5e8e375788580072f..ff4f25078f3d983bce630e597adbb12262e5d727 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -371,40 +371,6 @@ struct pid *pidfd_pid(const struct file *file) static struct vfsmount *pidfs_mnt __ro_after_init; -#if BITS_PER_LONG == 32 -/* - * Provide a fallback mechanism for 32-bit systems so processes remain - * reliably comparable by inode number even on those systems. - */ -static DEFINE_IDA(pidfd_inum_ida); - -static int pidfs_inum(struct pid *pid, unsigned long *ino) -{ - int ret; - - ret = ida_alloc_range(&pidfd_inum_ida, RESERVED_PIDS + 1, - UINT_MAX, GFP_ATOMIC); - if (ret < 0) - return -ENOSPC; - - *ino = ret; - return 0; -} - -static inline void pidfs_free_inum(unsigned long ino) -{ - if (ino > 0) - ida_free(&pidfd_inum_ida, ino); -} -#else -static inline int pidfs_inum(struct pid *pid, unsigned long *ino) -{ - *ino = pid->ino; - return 0; -} -#define pidfs_free_inum(ino) ((void)(ino)) -#endif - /* * The vfs falls back to simple_setattr() if i_op->setattr() isn't * implemented. Let's reject it completely until we have a clean @@ -456,7 +422,6 @@ static void pidfs_evict_inode(struct inode *inode) clear_inode(inode); put_pid(pid); - pidfs_free_inum(inode->i_ino); } static const struct super_operations pidfs_sops = { @@ -482,17 +447,16 @@ static const struct dentry_operations pidfs_dentry_operations = { static int pidfs_init_inode(struct inode *inode, void *data) { + struct pid *pid = data; + inode->i_private = data; inode->i_flags |= S_PRIVATE; inode->i_mode |= S_IRWXU; inode->i_op = &pidfs_inode_operations; inode->i_fop = &pidfs_file_operations; - /* - * Inode numbering for pidfs start at RESERVED_PIDS + 1. This - * avoids collisions with the root inode which is 1 for pseudo - * filesystems. - */ - return pidfs_inum(data, &inode->i_ino); + inode->i_ino = pidfs_ino(pid->ino); + inode->i_generation = pidfs_gen(pid->ino); + return 0; } static void pidfs_put_data(void *data) From patchwork Fri Nov 29 13:02:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13888646 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D3A381A0706; Fri, 29 Nov 2024 13:02:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885368; cv=none; b=E8iBz4HKMq2ac/fPvQIuYQ3OL9c8rY7N48zYA07pW7FqiPWh7v3NXDgqJgEIGxsKvQYiJ8sa6iaIDBMUSt1oOIVeFLiu8NGQXheC6UmcF8hCQbr+BUDglwqZGDebHOWT6s3lw/B2heuvtfLIl7a9txLtG/SThF3Jye0bNMXYels= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732885368; c=relaxed/simple; bh=XhmuC7UVdeZQ/uhtuvNv/UVaqirRNFdh/oaaipVsfRc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ksNrrKaVRLg4+dMsk1gZyGO60BUAXwDBUCLldgVBQx+6ZF14Alwtn8KpmM2eaRNDLjiR4oajF8CRvcYTIyKOcXxRtVQpP1KTTwIpO/cAiJgAbsqmwAnt8fopPj3vbKcOYHvsGxVOrssh3f3mMCax2BRkYGmiDVQewWvC0JYxjYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PjhtfZk0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PjhtfZk0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 822C2C4CED3; Fri, 29 Nov 2024 13:02:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1732885368; bh=XhmuC7UVdeZQ/uhtuvNv/UVaqirRNFdh/oaaipVsfRc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PjhtfZk0ennq7ZEBI3+NGUEphXnemG+VidNwx9FE+hkrKfDt9MTutasl3vul6HEH+ KJv05nzfWr60w5OSpPjxse9GAzTWTj5dqP8HoJYsw82W4HyRIF/YGG7djNLFsMqVrT bLeMX+VQClxY+c4Q3zzIvF0f0X9VP6VlBDauUyvlIeAHM0ei/8mOd5hW3LgGlnh7iY rWgAnHs9RXMFuvc8mLO5qNdU7nATeRaOpO/sWFRwTRuOwtIhL/WjIWdccBdyApKycO L569FAsPY8L5UeEPZLklnRDtghKVfHSwMSvTDyxYQdNjQJweuRycg+KS5NlxywLiNh xvRYqlZ6XU+zw== From: Christian Brauner Date: Fri, 29 Nov 2024 14:02:25 +0100 Subject: [PATCH RFC v2 3/3] pidfs: support FS_IOC_GETVERSION Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241129-work-pidfs-v2-3-61043d66fbce@kernel.org> References: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> In-Reply-To: <20241129-work-pidfs-v2-0-61043d66fbce@kernel.org> To: Erin Shepherd , Amir Goldstein , Jeff Layton Cc: Alexander Viro , Jan Kara , Chuck Lever , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Christian Brauner X-Mailer: b4 0.15-dev-355e8 X-Developer-Signature: v=1; a=openpgp-sha256; l=871; i=brauner@kernel.org; h=from:subject:message-id; bh=XhmuC7UVdeZQ/uhtuvNv/UVaqirRNFdh/oaaipVsfRc=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaR77s5tbp6xN6bja/mff2rpykf3G+xxPrP468e6h6FFz U8ZDrNyd5SyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEzEx4SRobv80VcDX2+mpFiH go2/N7OecnU4pVh0YLGJc11JV+MHTYb/XsG5bF0ML/+o582x3Z6z9Fvi7K9d6SHdM+d+W+vjqH2 ZEwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 This will allow 32 bit userspace to detect when a given inode number has been recycled and also to construct a unique 64 bit identifier. Signed-off-by: Christian Brauner --- fs/pidfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/pidfs.c b/fs/pidfs.c index ff4f25078f3d983bce630e597adbb12262e5d727..f73a47e1d8379df886a90a044fb887f8d06f7c0b 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -262,6 +262,15 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (arg) return -EINVAL; + switch (cmd) { + case FS_IOC32_GETVERSION: + fallthrough; + case FS_IOC_GETVERSION: { + __u32 __user *argp = (__u32 __user *)arg; + return put_user(file_inode(file)->i_generation, argp); + } + } + scoped_guard(task_lock, task) { nsp = task->nsproxy; if (nsp)