From: David Matlack <dmatlack@google.com>
To: kexec@lists.infradead.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-mm@kvack.org
Cc: Alexander Graf <graf@amazon.com>,
Andrew Morton <akpm@linux-foundation.org>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
Christian Brauner <brauner@kernel.org>,
David Hildenbrand <david@kernel.org>,
Hugh Dickins <hughd@google.com>, Jonathan Corbet <corbet@lwn.net>,
"Liam R. Howlett" <liam@infradead.org>,
Lorenzo Stoakes <ljs@kernel.org>, Michal Hocko <mhocko@suse.com>,
Mike Rapoport <rppt@kernel.org>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Pratyush Yadav <pratyush@kernel.org>,
Randy Dunlap <rdunlap@infradead.org>,
Samiullah Khawaja <skhawaja@google.com>,
Shuah Khan <skhan@linuxfoundation.org>,
Suren Baghdasaryan <surenb@google.com>,
Vlastimil Babka <vbabka@kernel.org>,
David Matlack <dmatlack@google.com>
Subject: [PATCH v2 09/10] mm/shmem_luo: Allow retrieving tmpfs files with O_RDONLY
Date: Thu, 22 Oct 2026 22:50:34 +0000 [thread overview]
Message-ID: <20261022225035.377445-10-dmatlack@google.com> (raw)
In-Reply-To: <20261022225035.377445-1-dmatlack@google.com>
Allow userspace to pass O_RDONLY in struct liveupdate_shmem_retrieve_arg
to retrieve a tmpfs file read-only.
open() requires write access for O_TMPFILE, so create the file writable
like before, then reopen it read-only with dentry_open() using the same
flags, and drop the writable file. Like open(), which grants the
requested access to a new file regardless of its mode, don't check
permission for the read-only open.
Retrieving a file read-only allows a restored binary to be executed
before the session is finished. LUO keeps the retrieved file open until
then, and executing a binary that is open for writing fails with
-ETXTBSY. Being able to execute restored binaries right away matters
when they are needed to finish restoring the system, e.g. to bring up
the services that retrieve and finish the remaining sessions.
Assisted-by: LLM
Signed-off-by: David Matlack <dmatlack@google.com>
---
include/uapi/linux/liveupdate.h | 6 +++---
mm/shmem_luo.c | 28 +++++++++++++++++++++-------
2 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/liveupdate.h b/include/uapi/linux/liveupdate.h
index a9dcc4fcc87b..790742a247e8 100644
--- a/include/uapi/linux/liveupdate.h
+++ b/include/uapi/linux/liveupdate.h
@@ -265,9 +265,9 @@ struct liveupdate_session_get_name {
*
* The kernel creates a new file as if by openat(@dirfd, ".", O_TMPFILE |
* @flags, @mode), fills it with the preserved contents, and returns it in
- * &struct liveupdate_session_retrieve_fd.fd. Like any O_TMPFILE file, the file
- * is not linked into the filesystem. Userspace can link it with linkat(),
- * unless @flags contains O_EXCL.
+ * &struct liveupdate_session_retrieve_fd.fd. Unlike open(), O_RDONLY is
+ * allowed. Like any O_TMPFILE file, the file is not linked into the filesystem.
+ * Userspace can link it with linkat(), unless @flags contains O_EXCL.
*
* If @flags contains unknown flags or O_PATH, if @mode contains unknown mode
* bits, or if @dirfd is not on a tmpfs mount, the retrieve fails with -EINVAL.
diff --git a/mm/shmem_luo.c b/mm/shmem_luo.c
index aba2bc1f18c5..0b4a9d6e2968 100644
--- a/mm/shmem_luo.c
+++ b/mm/shmem_luo.c
@@ -112,9 +112,10 @@
*
* Like any ``O_TMPFILE`` file, the new file is not linked into the filesystem.
* Userspace can link it at the path it wants with ``linkat()``, unless it asked
- * for ``O_EXCL``. Like with ``open()``, the file must be opened for writing.
- * LUO keeps the file open until the session is finished, so a retrieved binary
- * can't be executed until then.
+ * for ``O_EXCL``. Unlike ``open()``, the file can be retrieved with
+ * ``O_RDONLY``. LUO keeps the file open until the session is finished, so a
+ * binary retrieved with ``O_RDWR`` or ``O_WRONLY`` can't be executed until
+ * then.
*
* The blocks of the file are charged to the target mount, so the size limit
* and quotas of the mount apply. If the file doesn't fit, the retrieve fails
@@ -649,7 +650,9 @@ static struct file *shmem_luo_create_memfd(const struct liveupdate_shmem_retriev
static struct file *shmem_luo_create_tmpfs_file(const struct liveupdate_shmem_retrieve_arg *arg,
unsigned int seals)
{
- struct file *file;
+ struct file *file, *ro_file;
+ bool rdonly;
+ int flags;
int err;
if (!arg)
@@ -673,10 +676,16 @@ static struct file *shmem_luo_create_tmpfs_file(const struct liveupdate_shmem_re
/*
* Create the file like open(O_TMPFILE) does, so that it gets the same
- * flag checks, permission checks, owner and security labels.
+ * flag checks, permission checks, owner and security labels. open()
+ * requires write access for O_TMPFILE, so create the file writable and
+ * reopen it read-only below if that is what userspace asked for. LUO
+ * keeps the file until the session is finished, and a file opened for
+ * writing couldn't be executed until then.
*/
+ flags = O_TMPFILE | O_LARGEFILE | arg->flags;
+ rdonly = (flags & O_ACCMODE) == O_RDONLY;
file = file_open_root(&fd_file(dir)->f_path, ".",
- O_TMPFILE | O_LARGEFILE | arg->flags, arg->mode);
+ flags | (rdonly ? O_RDWR : 0), arg->mode);
if (IS_ERR(file))
return file;
@@ -694,7 +703,12 @@ static struct file *shmem_luo_create_tmpfs_file(const struct liveupdate_shmem_re
}
SHMEM_I(file_inode(file))->seals = seals;
- return file;
+ if (!rdonly)
+ return file;
+
+ ro_file = dentry_open(&file->f_path, flags, current_cred());
+ fput(file);
+ return ro_file;
}
static int shmem_luo_retrieve(struct liveupdate_file_op_args *args)
--
2.56.0.257.gf7497c7d27-goog
next prev parent reply other threads:[~2026-10-22 22:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 22:50 [PATCH v2 00/10] liveupdate: Preserve tmpfs files across Live Update David Matlack
2026-10-22 22:50 ` [PATCH v2 01/10] liveupdate: Pass user argument to file preserve and retrieve David Matlack
2026-10-22 22:50 ` [PATCH v2 02/10] selftests: liveupdate: Add tests for preserve and retrieve user argument David Matlack
2026-10-22 22:50 ` [PATCH v2 03/10] liveupdate: Allow file handlers to mark retrieve failures as retryable David Matlack
2026-10-22 22:50 ` [PATCH v2 04/10] mm: Rename memfd_luo to shmem_luo David Matlack
2026-10-22 22:50 ` [PATCH v2 05/10] liveupdate: Don't WARN if tracking a retrieved file fails David Matlack
2026-10-22 22:50 ` [PATCH v2 06/10] mm/shmem_luo: Don't make early retrieve failures permanent David Matlack
2026-10-22 22:50 ` [PATCH v2 07/10] mm/shmem_luo: Retrieve tmpfs files onto a tmpfs mount chosen by userspace David Matlack
2026-10-22 22:50 ` [PATCH v2 08/10] mm/shmem_luo: Allow preserving tmpfs files that are still linked David Matlack
2026-10-22 22:50 ` David Matlack [this message]
2026-10-22 22:50 ` [PATCH v2 10/10] selftests/liveupdate: Add a test for preserving tmpfs files David Matlack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022225035.377445-10-dmatlack@google.com \
--to=dmatlack@google.com \
--cc=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=brauner@kernel.org \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=graf@amazon.com \
--cc=hughd@google.com \
--cc=kexec@lists.infradead.org \
--cc=liam@infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=rdunlap@infradead.org \
--cc=rppt@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=skhawaja@google.com \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®