* [PATCH v3 0/4] livepatch: minor bug fixes and improvements
@ 2024-04-23 13:12 Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 1/4] xen-livepatch: fix parameter name parsing Roger Pau Monne
` (3 more replies)
0 siblings, 4 replies; 17+ messages in thread
From: Roger Pau Monne @ 2024-04-23 13:12 UTC (permalink / raw)
To: xen-devel
Cc: Roger Pau Monne, Ross Lagerwall, Anthony PERARD, Juergen Gross,
Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
Stefano Stabellini
Hello,
Following series contain some minor bugfixes and improvements for
livepatch logic, both inside the hypervisor and on the command line
tool.
Thanks, Roger.
Roger Pau Monne (4):
xen-livepatch: fix parameter name parsing
livepatch: introduce --force option
livepatch: refuse to resolve symbols that belong to init sections
x86/livepatch: perform sanity checks on the payload exception table
contents
tools/include/xenctrl.h | 3 ++-
tools/libs/ctrl/xc_misc.c | 7 +++----
tools/misc/xen-livepatch.c | 27 +++++++++++++++++++++++----
xen/arch/x86/extable.c | 18 ++++++++++++++++++
xen/arch/x86/include/asm/uaccess.h | 4 ++++
xen/common/livepatch.c | 25 +++++++++++++++++++------
xen/common/livepatch_elf.c | 18 +++++++++++++++++-
xen/include/public/sysctl.h | 4 +++-
xen/include/xen/livepatch_elf.h | 2 +-
9 files changed, 90 insertions(+), 18 deletions(-)
--
2.44.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 1/4] xen-livepatch: fix parameter name parsing
2024-04-23 13:12 [PATCH v3 0/4] livepatch: minor bug fixes and improvements Roger Pau Monne
@ 2024-04-23 13:12 ` Roger Pau Monne
2024-04-23 13:33 ` Jan Beulich
2024-04-23 13:12 ` [PATCH v3 2/4] livepatch: introduce --force option Roger Pau Monne
` (2 subsequent siblings)
3 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monne @ 2024-04-23 13:12 UTC (permalink / raw)
To: xen-devel; +Cc: Roger Pau Monne, Ross Lagerwall, Anthony PERARD
It's incorrect to restrict strncmp to the length of the command line input
parameter, as then a user passing a rune like:
% xen-livepatch up foo.livepatch
Would match against the "upload" command, because the string comparison has
been truncated to the length of the input argument. Instead the truncation
should be done based on the length of the command name stored in the internal
array of actions.
Fixes: 05bb8afedede ('xen-xsplice: Tool to manipulate xsplice payloads')
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Changes since v2:
- New in this version.
---
tools/misc/xen-livepatch.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c
index 5bf9d9a32b65..a246e5dfd38e 100644
--- a/tools/misc/xen-livepatch.c
+++ b/tools/misc/xen-livepatch.c
@@ -572,13 +572,15 @@ int main(int argc, char *argv[])
return 0;
}
for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
- if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
+ if (!strncmp(main_options[i].name, argv[1],
+ strlen(main_options[i].name)))
break;
if ( i == ARRAY_SIZE(main_options) )
{
for ( j = 0; j < ARRAY_SIZE(action_options); j++ )
- if (!strncmp(action_options[j].name, argv[1], strlen(argv[1])))
+ if (!strncmp(action_options[j].name, argv[1],
+ strlen(action_options[j].name)))
break;
if ( j == ARRAY_SIZE(action_options) )
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 2/4] livepatch: introduce --force option
2024-04-23 13:12 [PATCH v3 0/4] livepatch: minor bug fixes and improvements Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 1/4] xen-livepatch: fix parameter name parsing Roger Pau Monne
@ 2024-04-23 13:12 ` Roger Pau Monne
2024-04-23 13:38 ` Jan Beulich
2024-04-23 16:05 ` Anthony PERARD
2024-04-23 13:12 ` [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents Roger Pau Monne
3 siblings, 2 replies; 17+ messages in thread
From: Roger Pau Monne @ 2024-04-23 13:12 UTC (permalink / raw)
To: xen-devel
Cc: Roger Pau Monne, Anthony PERARD, Juergen Gross, Andrew Cooper,
George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini,
Ross Lagerwall
Introduce a xen-livepatch tool --force option, that's propagated into the
hyerpvisor for livepatch operations. The intention is for the option to be
used to bypass some checks that would otherwise prevent the patch from being
loaded.
Re purpose the pad field in xen_sysctl_livepatch_op to be a flags field that
applies to all livepatch operations. The flag is currently only set by the
hypercall wrappers for the XEN_SYSCTL_LIVEPATCH_UPLOAD operation, as that's so
far the only one where it will be used initially. Other uses can be added as
required.
Note that helpers would set the .pad field to 0, that's been removed since the
structure is already zero initialized at definition.
No functional usages of the new flag introduced in this patch.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Changes since v2:
- New in this version.
---
tools/include/xenctrl.h | 3 ++-
tools/libs/ctrl/xc_misc.c | 7 +++----
tools/misc/xen-livepatch.c | 21 +++++++++++++++++++--
xen/common/livepatch.c | 3 ++-
xen/include/public/sysctl.h | 4 +++-
5 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 2ef8b4e05422..499685594427 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -2555,7 +2555,8 @@ int xc_psr_get_hw_info(xc_interface *xch, uint32_t socket,
#endif
int xc_livepatch_upload(xc_interface *xch,
- char *name, unsigned char *payload, uint32_t size);
+ char *name, unsigned char *payload, uint32_t size,
+ bool force);
int xc_livepatch_get(xc_interface *xch,
char *name,
diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c
index 5ecdfa2c7934..50282fd60dcc 100644
--- a/tools/libs/ctrl/xc_misc.c
+++ b/tools/libs/ctrl/xc_misc.c
@@ -576,7 +576,8 @@ int xc_getcpuinfo(xc_interface *xch, int max_cpus,
int xc_livepatch_upload(xc_interface *xch,
char *name,
unsigned char *payload,
- uint32_t size)
+ uint32_t size,
+ bool force)
{
int rc;
struct xen_sysctl sysctl = {};
@@ -612,7 +613,7 @@ int xc_livepatch_upload(xc_interface *xch,
sysctl.cmd = XEN_SYSCTL_livepatch_op;
sysctl.u.livepatch.cmd = XEN_SYSCTL_LIVEPATCH_UPLOAD;
- sysctl.u.livepatch.pad = 0;
+ sysctl.u.livepatch.flags = force ? LIVEPATCH_FLAG_FORCE : 0;
sysctl.u.livepatch.u.upload.size = size;
set_xen_guest_handle(sysctl.u.livepatch.u.upload.payload, local);
@@ -656,7 +657,6 @@ int xc_livepatch_get(xc_interface *xch,
sysctl.cmd = XEN_SYSCTL_livepatch_op;
sysctl.u.livepatch.cmd = XEN_SYSCTL_LIVEPATCH_GET;
- sysctl.u.livepatch.pad = 0;
sysctl.u.livepatch.u.get.status.state = 0;
sysctl.u.livepatch.u.get.status.rc = 0;
@@ -985,7 +985,6 @@ static int _xc_livepatch_action(xc_interface *xch,
sysctl.cmd = XEN_SYSCTL_livepatch_op;
sysctl.u.livepatch.cmd = XEN_SYSCTL_LIVEPATCH_ACTION;
- sysctl.u.livepatch.pad = 0;
sysctl.u.livepatch.u.action.cmd = action;
sysctl.u.livepatch.u.action.timeout = timeout;
sysctl.u.livepatch.u.action.flags = flags;
diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c
index a246e5dfd38e..cf2e5fada12d 100644
--- a/tools/misc/xen-livepatch.c
+++ b/tools/misc/xen-livepatch.c
@@ -19,11 +19,15 @@
static xc_interface *xch;
+/* Global option to disable checks. */
+static bool force;
+
void show_help(void)
{
fprintf(stderr,
"xen-livepatch: live patching tool\n"
- "Usage: xen-livepatch <command> [args] [command-flags]\n"
+ "Usage: xen-livepatch [--force] <command> [args] [command-flags]\n"
+ " Use --force option to bypass some checks.\n"
" <name> An unique name of payload. Up to %d characters.\n"
"Commands:\n"
" help display this help\n"
@@ -240,7 +244,7 @@ static int upload_func(int argc, char *argv[])
return saved_errno;
}
printf("Uploading %s... ", filename);
- rc = xc_livepatch_upload(xch, name, fbuf, len);
+ rc = xc_livepatch_upload(xch, name, fbuf, len, force);
if ( rc )
{
rc = errno;
@@ -571,6 +575,19 @@ int main(int argc, char *argv[])
show_help();
return 0;
}
+
+ if ( !strncmp("--force", argv[1], strlen("--force")) )
+ {
+ if ( argc <= 2 )
+ {
+ show_help();
+ return EXIT_FAILURE;
+ }
+ force = true;
+ argv++;
+ argc--;
+ }
+
for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
if (!strncmp(main_options[i].name, argv[1],
strlen(main_options[i].name)))
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 351a3e0b9a60..1503a84457e4 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -2125,7 +2125,8 @@ int livepatch_op(struct xen_sysctl_livepatch_op *livepatch)
{
int rc;
- if ( livepatch->pad )
+ if ( livepatch->flags & ~LIVEPATCH_FLAGS_MASK &&
+ !(livepatch->flags & LIVEPATCH_FLAG_FORCE) )
return -EINVAL;
switch ( livepatch->cmd )
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 9b19679caeb1..febaa4b16ab7 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -1139,7 +1139,9 @@ struct xen_sysctl_livepatch_action {
struct xen_sysctl_livepatch_op {
uint32_t cmd; /* IN: XEN_SYSCTL_LIVEPATCH_*. */
- uint32_t pad; /* IN: Always zero. */
+ uint32_t flags; /* IN, flags. */
+#define LIVEPATCH_FLAG_FORCE (1u << 0) /* Skip some checks. */
+#define LIVEPATCH_FLAGS_MASK LIVEPATCH_FLAG_FORCE
union {
struct xen_sysctl_livepatch_upload upload;
struct xen_sysctl_livepatch_list list;
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 13:12 [PATCH v3 0/4] livepatch: minor bug fixes and improvements Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 1/4] xen-livepatch: fix parameter name parsing Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 2/4] livepatch: introduce --force option Roger Pau Monne
@ 2024-04-23 13:12 ` Roger Pau Monne
2024-04-23 13:44 ` Jan Beulich
2024-04-23 13:12 ` [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents Roger Pau Monne
3 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monne @ 2024-04-23 13:12 UTC (permalink / raw)
To: xen-devel; +Cc: Roger Pau Monne, Ross Lagerwall
Livepatch payloads containing symbols that belong to init sections can only
lead to page faults later on, as by the time the livepatch is loaded init
sections have already been freed.
Refuse to resolve such symbols and return an error instead.
Note such resolutions are only relevant for symbols that point to undefined
sections (SHN_UNDEF), as that implies the symbol is not in the current payload
and hence must either be a Xen or a different livepatch payload symbol.
Do not allow to resolve symbols that point to __init_begin, as that address is
also unmapped. On the other hand, __init_end is not unmapped, and hence allow
resolutions against it.
Since __init_begin can alias other symbols (like _erodata for example)
allow the force flag to override the check and resolve the symbol anyway.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Changes since v2:
- Allow bypassing added check with the force flag.
Changes since v1:
- Fix off-by-one in range checking.
---
xen/common/livepatch.c | 13 ++++++++-----
xen/common/livepatch_elf.c | 18 +++++++++++++++++-
xen/include/xen/livepatch_elf.h | 2 +-
3 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 1503a84457e4..36cf4bee8b8a 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1080,7 +1080,8 @@ static void free_payload(struct payload *data)
xfree(data);
}
-static int load_payload_data(struct payload *payload, void *raw, size_t len)
+static int load_payload_data(struct payload *payload, void *raw, size_t len,
+ bool force)
{
struct livepatch_elf elf = { .name = payload->name, .len = len };
int rc = 0;
@@ -1093,7 +1094,7 @@ static int load_payload_data(struct payload *payload, void *raw, size_t len)
if ( rc )
goto out;
- rc = livepatch_elf_resolve_symbols(&elf);
+ rc = livepatch_elf_resolve_symbols(&elf, force);
if ( rc )
goto out;
@@ -1133,7 +1134,8 @@ static int load_payload_data(struct payload *payload, void *raw, size_t len)
return rc;
}
-static int livepatch_upload(struct xen_sysctl_livepatch_upload *upload)
+static int livepatch_upload(struct xen_sysctl_livepatch_upload *upload,
+ bool force)
{
struct payload *data, *found;
char n[XEN_LIVEPATCH_NAME_SIZE];
@@ -1162,7 +1164,7 @@ static int livepatch_upload(struct xen_sysctl_livepatch_upload *upload)
{
memcpy(data->name, n, strlen(n));
- rc = load_payload_data(data, raw_data, upload->size);
+ rc = load_payload_data(data, raw_data, upload->size, force);
if ( rc )
goto out;
@@ -2132,7 +2134,8 @@ int livepatch_op(struct xen_sysctl_livepatch_op *livepatch)
switch ( livepatch->cmd )
{
case XEN_SYSCTL_LIVEPATCH_UPLOAD:
- rc = livepatch_upload(&livepatch->u.upload);
+ rc = livepatch_upload(&livepatch->u.upload,
+ livepatch->flags & LIVEPATCH_FLAG_FORCE);
break;
case XEN_SYSCTL_LIVEPATCH_GET:
diff --git a/xen/common/livepatch_elf.c b/xen/common/livepatch_elf.c
index 45d73912a3cd..0436f2d5fcbd 100644
--- a/xen/common/livepatch_elf.c
+++ b/xen/common/livepatch_elf.c
@@ -4,6 +4,7 @@
#include <xen/errno.h>
#include <xen/lib.h>
+#include <xen/sections.h>
#include <xen/symbols.h>
#include <xen/livepatch_elf.h>
#include <xen/livepatch.h>
@@ -276,7 +277,7 @@ static int elf_get_sym(struct livepatch_elf *elf, const void *data)
return 0;
}
-int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
+int livepatch_elf_resolve_symbols(struct livepatch_elf *elf, bool force)
{
unsigned int i;
int rc = 0;
@@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
break;
}
}
+
+ /*
+ * Ensure not an init symbol. Only applicable to Xen symbols, as
+ * livepatch payloads don't have init sections or equivalent.
+ */
+ else if ( st_value >= (uintptr_t)&__init_begin &&
+ st_value < (uintptr_t)&__init_end && !force )
+ {
+ printk(XENLOG_ERR LIVEPATCH
+ "%s: symbol %s is in init section, not resolving\n",
+ elf->name, elf->sym[i].name);
+ rc = -ENXIO;
+ break;
+ }
+
dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Undefined symbol resolved: %s => %#"PRIxElfAddr"\n",
elf->name, elf->sym[i].name, st_value);
break;
diff --git a/xen/include/xen/livepatch_elf.h b/xen/include/xen/livepatch_elf.h
index 7116deaddc28..84e9c5eb7be5 100644
--- a/xen/include/xen/livepatch_elf.h
+++ b/xen/include/xen/livepatch_elf.h
@@ -44,7 +44,7 @@ livepatch_elf_sec_by_name(const struct livepatch_elf *elf,
int livepatch_elf_load(struct livepatch_elf *elf, const void *data);
void livepatch_elf_free(struct livepatch_elf *elf);
-int livepatch_elf_resolve_symbols(struct livepatch_elf *elf);
+int livepatch_elf_resolve_symbols(struct livepatch_elf *elf, bool force);
int livepatch_elf_perform_relocs(struct livepatch_elf *elf);
static inline bool livepatch_elf_ignore_section(const Elf_Shdr *sec)
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents
2024-04-23 13:12 [PATCH v3 0/4] livepatch: minor bug fixes and improvements Roger Pau Monne
` (2 preceding siblings ...)
2024-04-23 13:12 ` [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections Roger Pau Monne
@ 2024-04-23 13:12 ` Roger Pau Monne
2024-04-23 13:51 ` Jan Beulich
3 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monne @ 2024-04-23 13:12 UTC (permalink / raw)
To: xen-devel; +Cc: Roger Pau Monne, Jan Beulich, Andrew Cooper, Ross Lagerwall
Ensure the entries of a payload exception table only apply to text regions in
the payload itself. Since the payload exception table needs to be loaded and
active even before a patch is applied (because hooks might already rely on it),
make sure the exception table (if any) only contains fixups for the payload
text section.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Changes since v2:
- New in this version.
---
xen/arch/x86/extable.c | 18 ++++++++++++++++++
xen/arch/x86/include/asm/uaccess.h | 4 ++++
xen/common/livepatch.c | 9 +++++++++
3 files changed, 31 insertions(+)
diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index 8415cd1fa249..9e91e8234e71 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -228,3 +228,21 @@ unsigned long asmlinkage search_pre_exception_table(struct cpu_user_regs *regs)
}
return fixup;
}
+
+#ifdef CONFIG_LIVEPATCH
+bool extable_is_between_bounds(const struct exception_table_entry *ex_start,
+ const struct exception_table_entry *ex_end,
+ const void *start, const void *end)
+{
+ for ( ; ex_start < ex_end; ex_start++ )
+ {
+ const void *addr = (void *)ex_addr(ex_start);
+ const void *cont = (void *)ex_cont(ex_start);
+
+ if ( addr < start || addr >= end || cont < start || cont >= end )
+ return false;
+ }
+
+ return true;
+}
+#endif
diff --git a/xen/arch/x86/include/asm/uaccess.h b/xen/arch/x86/include/asm/uaccess.h
index 48b684c19d44..0dad61e21a9c 100644
--- a/xen/arch/x86/include/asm/uaccess.h
+++ b/xen/arch/x86/include/asm/uaccess.h
@@ -426,5 +426,9 @@ extern unsigned long search_exception_table(const struct cpu_user_regs *regs,
extern void sort_exception_tables(void);
extern void sort_exception_table(struct exception_table_entry *start,
const struct exception_table_entry *stop);
+extern bool extable_is_between_bounds(
+ const struct exception_table_entry *ex_start,
+ const struct exception_table_entry *ex_end,
+ const void *start, const void *end);
#endif /* __X86_UACCESS_H__ */
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 36cf4bee8b8a..67b6815d87ac 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -912,6 +912,15 @@ static int prepare_payload(struct payload *payload,
s = sec->load_addr;
e = sec->load_addr + sec->sec->sh_size;
+ if ( !extable_is_between_bounds(s, e, payload->text_addr,
+ payload->text_addr + payload->text_size) )
+ {
+ printk(XENLOG_ERR LIVEPATCH
+ "%s: Invalid exception table with out of bounds entries\n",
+ elf->name);
+ return -EINVAL;
+ }
+
sort_exception_table(s ,e);
region->ex = s;
--
2.44.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v3 1/4] xen-livepatch: fix parameter name parsing
2024-04-23 13:12 ` [PATCH v3 1/4] xen-livepatch: fix parameter name parsing Roger Pau Monne
@ 2024-04-23 13:33 ` Jan Beulich
2024-04-23 14:11 ` Roger Pau Monné
0 siblings, 1 reply; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 13:33 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Ross Lagerwall, Anthony PERARD, xen-devel
On 23.04.2024 15:12, Roger Pau Monne wrote:
> It's incorrect to restrict strncmp to the length of the command line input
> parameter, as then a user passing a rune like:
>
> % xen-livepatch up foo.livepatch
>
> Would match against the "upload" command, because the string comparison has
> been truncated to the length of the input argument. Instead the truncation
> should be done based on the length of the command name stored in the internal
> array of actions.
But then "xen-livepatch upload-or-not foo.livepatch" would still wrongly
match. Why strncmp() at all, rather than strcmp()?
Jan
> Fixes: 05bb8afedede ('xen-xsplice: Tool to manipulate xsplice payloads')
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> ---
> Changes since v2:
> - New in this version.
> ---
> tools/misc/xen-livepatch.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c
> index 5bf9d9a32b65..a246e5dfd38e 100644
> --- a/tools/misc/xen-livepatch.c
> +++ b/tools/misc/xen-livepatch.c
> @@ -572,13 +572,15 @@ int main(int argc, char *argv[])
> return 0;
> }
> for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
> - if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
> + if (!strncmp(main_options[i].name, argv[1],
> + strlen(main_options[i].name)))
> break;
>
> if ( i == ARRAY_SIZE(main_options) )
> {
> for ( j = 0; j < ARRAY_SIZE(action_options); j++ )
> - if (!strncmp(action_options[j].name, argv[1], strlen(argv[1])))
> + if (!strncmp(action_options[j].name, argv[1],
> + strlen(action_options[j].name)))
> break;
>
> if ( j == ARRAY_SIZE(action_options) )
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/4] livepatch: introduce --force option
2024-04-23 13:12 ` [PATCH v3 2/4] livepatch: introduce --force option Roger Pau Monne
@ 2024-04-23 13:38 ` Jan Beulich
2024-04-23 16:05 ` Anthony PERARD
1 sibling, 0 replies; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 13:38 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Anthony PERARD, Juergen Gross, Andrew Cooper, George Dunlap,
Julien Grall, Stefano Stabellini, Ross Lagerwall, xen-devel
On 23.04.2024 15:12, Roger Pau Monne wrote:
> --- a/xen/common/livepatch.c
> +++ b/xen/common/livepatch.c
> @@ -2125,7 +2125,8 @@ int livepatch_op(struct xen_sysctl_livepatch_op *livepatch)
> {
> int rc;
>
> - if ( livepatch->pad )
> + if ( livepatch->flags & ~LIVEPATCH_FLAGS_MASK &&
With parentheses added here (which presumably could be done while
committing)
Acked-by: Jan Beulich <jbeulich@suse.com>
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 13:12 ` [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections Roger Pau Monne
@ 2024-04-23 13:44 ` Jan Beulich
2024-04-23 14:26 ` Roger Pau Monné
0 siblings, 1 reply; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 13:44 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Ross Lagerwall, xen-devel
On 23.04.2024 15:12, Roger Pau Monne wrote:
> Livepatch payloads containing symbols that belong to init sections can only
> lead to page faults later on, as by the time the livepatch is loaded init
> sections have already been freed.
>
> Refuse to resolve such symbols and return an error instead.
>
> Note such resolutions are only relevant for symbols that point to undefined
> sections (SHN_UNDEF), as that implies the symbol is not in the current payload
> and hence must either be a Xen or a different livepatch payload symbol.
>
> Do not allow to resolve symbols that point to __init_begin, as that address is
> also unmapped. On the other hand, __init_end is not unmapped, and hence allow
> resolutions against it.
>
> Since __init_begin can alias other symbols (like _erodata for example)
> allow the force flag to override the check and resolve the symbol anyway.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
In principle, as promised (and just to indicate earlier concerns were
addressed, as this is meaningless for other purposes)
Acked-by: Jan Beulich <jbeulich@suse.com>
However, ...
> @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
> break;
> }
> }
> +
> + /*
> + * Ensure not an init symbol. Only applicable to Xen symbols, as
> + * livepatch payloads don't have init sections or equivalent.
> + */
> + else if ( st_value >= (uintptr_t)&__init_begin &&
> + st_value < (uintptr_t)&__init_end && !force )
> + {
> + printk(XENLOG_ERR LIVEPATCH
> + "%s: symbol %s is in init section, not resolving\n",
> + elf->name, elf->sym[i].name);
> + rc = -ENXIO;
> + break;
> + }
... wouldn't it make sense to still warn in this case when "force" is set?
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents
2024-04-23 13:12 ` [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents Roger Pau Monne
@ 2024-04-23 13:51 ` Jan Beulich
2024-04-23 14:31 ` Roger Pau Monné
0 siblings, 1 reply; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 13:51 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Andrew Cooper, Ross Lagerwall, xen-devel
On 23.04.2024 15:12, Roger Pau Monne wrote:
> Ensure the entries of a payload exception table only apply to text regions in
> the payload itself. Since the payload exception table needs to be loaded and
> active even before a patch is applied (because hooks might already rely on it),
> make sure the exception table (if any) only contains fixups for the payload
> text section.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
In principle
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Still two comments:
> --- a/xen/arch/x86/extable.c
> +++ b/xen/arch/x86/extable.c
> @@ -228,3 +228,21 @@ unsigned long asmlinkage search_pre_exception_table(struct cpu_user_regs *regs)
> }
> return fixup;
> }
> +
> +#ifdef CONFIG_LIVEPATCH
> +bool extable_is_between_bounds(const struct exception_table_entry *ex_start,
s/between/in/ or even s/is_between/in/? "Between", to me at least, reads
very much like meaning "exclusive at both ends".
> + const struct exception_table_entry *ex_end,
> + const void *start, const void *end)
> +{
> + for ( ; ex_start < ex_end; ex_start++ )
> + {
> + const void *addr = (void *)ex_addr(ex_start);
> + const void *cont = (void *)ex_cont(ex_start);
Might be nicer to use _p() here, or not do the comparisons with pointers, but
instead with unsigned long-s.
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 1/4] xen-livepatch: fix parameter name parsing
2024-04-23 13:33 ` Jan Beulich
@ 2024-04-23 14:11 ` Roger Pau Monné
0 siblings, 0 replies; 17+ messages in thread
From: Roger Pau Monné @ 2024-04-23 14:11 UTC (permalink / raw)
To: Jan Beulich; +Cc: Ross Lagerwall, Anthony PERARD, xen-devel
On Tue, Apr 23, 2024 at 03:33:36PM +0200, Jan Beulich wrote:
> On 23.04.2024 15:12, Roger Pau Monne wrote:
> > It's incorrect to restrict strncmp to the length of the command line input
> > parameter, as then a user passing a rune like:
> >
> > % xen-livepatch up foo.livepatch
> >
> > Would match against the "upload" command, because the string comparison has
> > been truncated to the length of the input argument. Instead the truncation
> > should be done based on the length of the command name stored in the internal
> > array of actions.
>
> But then "xen-livepatch upload-or-not foo.livepatch" would still wrongly
> match. Why strncmp() at all, rather than strcmp()?
Bah, indeed, how dumb of me. Will switch to strcmp in the next
version.
Thanks, Roger.-
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 13:44 ` Jan Beulich
@ 2024-04-23 14:26 ` Roger Pau Monné
2024-04-23 14:28 ` Jan Beulich
0 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monné @ 2024-04-23 14:26 UTC (permalink / raw)
To: Jan Beulich; +Cc: Ross Lagerwall, xen-devel
On Tue, Apr 23, 2024 at 03:44:42PM +0200, Jan Beulich wrote:
> On 23.04.2024 15:12, Roger Pau Monne wrote:
> > Livepatch payloads containing symbols that belong to init sections can only
> > lead to page faults later on, as by the time the livepatch is loaded init
> > sections have already been freed.
> >
> > Refuse to resolve such symbols and return an error instead.
> >
> > Note such resolutions are only relevant for symbols that point to undefined
> > sections (SHN_UNDEF), as that implies the symbol is not in the current payload
> > and hence must either be a Xen or a different livepatch payload symbol.
> >
> > Do not allow to resolve symbols that point to __init_begin, as that address is
> > also unmapped. On the other hand, __init_end is not unmapped, and hence allow
> > resolutions against it.
> >
> > Since __init_begin can alias other symbols (like _erodata for example)
> > allow the force flag to override the check and resolve the symbol anyway.
> >
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>
> In principle, as promised (and just to indicate earlier concerns were
> addressed, as this is meaningless for other purposes)
> Acked-by: Jan Beulich <jbeulich@suse.com>
> However, ...
>
> > @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
> > break;
> > }
> > }
> > +
> > + /*
> > + * Ensure not an init symbol. Only applicable to Xen symbols, as
> > + * livepatch payloads don't have init sections or equivalent.
> > + */
> > + else if ( st_value >= (uintptr_t)&__init_begin &&
> > + st_value < (uintptr_t)&__init_end && !force )
> > + {
> > + printk(XENLOG_ERR LIVEPATCH
> > + "%s: symbol %s is in init section, not resolving\n",
> > + elf->name, elf->sym[i].name);
> > + rc = -ENXIO;
> > + break;
> > + }
>
> ... wouldn't it make sense to still warn in this case when "force" is set?
Pondered it, I was thinking that a user would first run without
--force, and use the option as a result of seeing the first failure.
However if there is more than one check that's bypassed, further ones
won't be noticed, so:
else if ( st_value >= (uintptr_t)&__init_begin &&
st_value < (uintptr_t)&__init_end )
{
printk(XENLOG_ERR LIVEPATCH
"%s: symbol %s is in init section, not resolving\n",
elf->name, elf->sym[i].name);
if ( !force )
{
rc = -ENXIO;
break;
}
}
Would be OK then?
Thanks, Roger.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 14:26 ` Roger Pau Monné
@ 2024-04-23 14:28 ` Jan Beulich
2024-04-23 15:03 ` Roger Pau Monné
0 siblings, 1 reply; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 14:28 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Ross Lagerwall, xen-devel
On 23.04.2024 16:26, Roger Pau Monné wrote:
> On Tue, Apr 23, 2024 at 03:44:42PM +0200, Jan Beulich wrote:
>> On 23.04.2024 15:12, Roger Pau Monne wrote:
>>> Livepatch payloads containing symbols that belong to init sections can only
>>> lead to page faults later on, as by the time the livepatch is loaded init
>>> sections have already been freed.
>>>
>>> Refuse to resolve such symbols and return an error instead.
>>>
>>> Note such resolutions are only relevant for symbols that point to undefined
>>> sections (SHN_UNDEF), as that implies the symbol is not in the current payload
>>> and hence must either be a Xen or a different livepatch payload symbol.
>>>
>>> Do not allow to resolve symbols that point to __init_begin, as that address is
>>> also unmapped. On the other hand, __init_end is not unmapped, and hence allow
>>> resolutions against it.
>>>
>>> Since __init_begin can alias other symbols (like _erodata for example)
>>> allow the force flag to override the check and resolve the symbol anyway.
>>>
>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>
>> In principle, as promised (and just to indicate earlier concerns were
>> addressed, as this is meaningless for other purposes)
>> Acked-by: Jan Beulich <jbeulich@suse.com>
>> However, ...
>>
>>> @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
>>> break;
>>> }
>>> }
>>> +
>>> + /*
>>> + * Ensure not an init symbol. Only applicable to Xen symbols, as
>>> + * livepatch payloads don't have init sections or equivalent.
>>> + */
>>> + else if ( st_value >= (uintptr_t)&__init_begin &&
>>> + st_value < (uintptr_t)&__init_end && !force )
>>> + {
>>> + printk(XENLOG_ERR LIVEPATCH
>>> + "%s: symbol %s is in init section, not resolving\n",
>>> + elf->name, elf->sym[i].name);
>>> + rc = -ENXIO;
>>> + break;
>>> + }
>>
>> ... wouldn't it make sense to still warn in this case when "force" is set?
>
> Pondered it, I was thinking that a user would first run without
> --force, and use the option as a result of seeing the first failure.
>
> However if there is more than one check that's bypassed, further ones
> won't be noticed, so:
>
> else if ( st_value >= (uintptr_t)&__init_begin &&
> st_value < (uintptr_t)&__init_end )
> {
> printk(XENLOG_ERR LIVEPATCH
> "%s: symbol %s is in init section, not resolving\n",
> elf->name, elf->sym[i].name);
> if ( !force )
> {
> rc = -ENXIO;
> break;
> }
> }
>
> Would be OK then?
Perhaps. "not resolving" isn't quite true when "force" is true, and warnings
would also better not be issued with XENLOG_ERR.
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents
2024-04-23 13:51 ` Jan Beulich
@ 2024-04-23 14:31 ` Roger Pau Monné
2024-04-23 14:35 ` Jan Beulich
0 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monné @ 2024-04-23 14:31 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, Ross Lagerwall, xen-devel
On Tue, Apr 23, 2024 at 03:51:31PM +0200, Jan Beulich wrote:
> On 23.04.2024 15:12, Roger Pau Monne wrote:
> > Ensure the entries of a payload exception table only apply to text regions in
> > the payload itself. Since the payload exception table needs to be loaded and
> > active even before a patch is applied (because hooks might already rely on it),
> > make sure the exception table (if any) only contains fixups for the payload
> > text section.
> >
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>
> In principle
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> Still two comments:
>
> > --- a/xen/arch/x86/extable.c
> > +++ b/xen/arch/x86/extable.c
> > @@ -228,3 +228,21 @@ unsigned long asmlinkage search_pre_exception_table(struct cpu_user_regs *regs)
> > }
> > return fixup;
> > }
> > +
> > +#ifdef CONFIG_LIVEPATCH
> > +bool extable_is_between_bounds(const struct exception_table_entry *ex_start,
>
> s/between/in/ or even s/is_between/in/? "Between", to me at least, reads
> very much like meaning "exclusive at both ends".
Oh, OK, I don't associate any boundary inclusion with 'between' or
'in'. The result is shorter, so I like it.
> > + const struct exception_table_entry *ex_end,
> > + const void *start, const void *end)
> > +{
> > + for ( ; ex_start < ex_end; ex_start++ )
> > + {
> > + const void *addr = (void *)ex_addr(ex_start);
> > + const void *cont = (void *)ex_cont(ex_start);
>
> Might be nicer to use _p() here, or not do the comparisons with pointers, but
> instead with unsigned long-s.
No strong opinion regarding whether to use unsigned longs or pointers.
I've used pointers because I think the function parameters should be
pointers, and that avoided doing a cast in the comparison with
obfuscates it (or introducing yet another local variable).
I can switch to _p(), that's indeed better.
Let me know if you have a strong opinion for using unsigned longs,
otherwise my preference would be to leave it with pointers.
Thanks, Roger.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents
2024-04-23 14:31 ` Roger Pau Monné
@ 2024-04-23 14:35 ` Jan Beulich
0 siblings, 0 replies; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 14:35 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Andrew Cooper, Ross Lagerwall, xen-devel
On 23.04.2024 16:31, Roger Pau Monné wrote:
> On Tue, Apr 23, 2024 at 03:51:31PM +0200, Jan Beulich wrote:
>> On 23.04.2024 15:12, Roger Pau Monne wrote:
>>> Ensure the entries of a payload exception table only apply to text regions in
>>> the payload itself. Since the payload exception table needs to be loaded and
>>> active even before a patch is applied (because hooks might already rely on it),
>>> make sure the exception table (if any) only contains fixups for the payload
>>> text section.
>>>
>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>
>> In principle
>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>> Still two comments:
>>
>>> --- a/xen/arch/x86/extable.c
>>> +++ b/xen/arch/x86/extable.c
>>> @@ -228,3 +228,21 @@ unsigned long asmlinkage search_pre_exception_table(struct cpu_user_regs *regs)
>>> }
>>> return fixup;
>>> }
>>> +
>>> +#ifdef CONFIG_LIVEPATCH
>>> +bool extable_is_between_bounds(const struct exception_table_entry *ex_start,
>>
>> s/between/in/ or even s/is_between/in/? "Between", to me at least, reads
>> very much like meaning "exclusive at both ends".
>
> Oh, OK, I don't associate any boundary inclusion with 'between' or
> 'in'. The result is shorter, so I like it.
>
>>> + const struct exception_table_entry *ex_end,
>>> + const void *start, const void *end)
>>> +{
>>> + for ( ; ex_start < ex_end; ex_start++ )
>>> + {
>>> + const void *addr = (void *)ex_addr(ex_start);
>>> + const void *cont = (void *)ex_cont(ex_start);
>>
>> Might be nicer to use _p() here, or not do the comparisons with pointers, but
>> instead with unsigned long-s.
>
> No strong opinion regarding whether to use unsigned longs or pointers.
> I've used pointers because I think the function parameters should be
> pointers, and that avoided doing a cast in the comparison with
> obfuscates it (or introducing yet another local variable).
>
> I can switch to _p(), that's indeed better.
>
> Let me know if you have a strong opinion for using unsigned longs,
> otherwise my preference would be to leave it with pointers.
Especially if you want to stick to pointer function arguments - no, no
strong opinion.
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 14:28 ` Jan Beulich
@ 2024-04-23 15:03 ` Roger Pau Monné
2024-04-23 16:07 ` Jan Beulich
0 siblings, 1 reply; 17+ messages in thread
From: Roger Pau Monné @ 2024-04-23 15:03 UTC (permalink / raw)
To: Jan Beulich; +Cc: Ross Lagerwall, xen-devel
On Tue, Apr 23, 2024 at 04:28:59PM +0200, Jan Beulich wrote:
> On 23.04.2024 16:26, Roger Pau Monné wrote:
> > On Tue, Apr 23, 2024 at 03:44:42PM +0200, Jan Beulich wrote:
> >> On 23.04.2024 15:12, Roger Pau Monne wrote:
> >>> Livepatch payloads containing symbols that belong to init sections can only
> >>> lead to page faults later on, as by the time the livepatch is loaded init
> >>> sections have already been freed.
> >>>
> >>> Refuse to resolve such symbols and return an error instead.
> >>>
> >>> Note such resolutions are only relevant for symbols that point to undefined
> >>> sections (SHN_UNDEF), as that implies the symbol is not in the current payload
> >>> and hence must either be a Xen or a different livepatch payload symbol.
> >>>
> >>> Do not allow to resolve symbols that point to __init_begin, as that address is
> >>> also unmapped. On the other hand, __init_end is not unmapped, and hence allow
> >>> resolutions against it.
> >>>
> >>> Since __init_begin can alias other symbols (like _erodata for example)
> >>> allow the force flag to override the check and resolve the symbol anyway.
> >>>
> >>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> >>
> >> In principle, as promised (and just to indicate earlier concerns were
> >> addressed, as this is meaningless for other purposes)
> >> Acked-by: Jan Beulich <jbeulich@suse.com>
> >> However, ...
> >>
> >>> @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
> >>> break;
> >>> }
> >>> }
> >>> +
> >>> + /*
> >>> + * Ensure not an init symbol. Only applicable to Xen symbols, as
> >>> + * livepatch payloads don't have init sections or equivalent.
> >>> + */
> >>> + else if ( st_value >= (uintptr_t)&__init_begin &&
> >>> + st_value < (uintptr_t)&__init_end && !force )
> >>> + {
> >>> + printk(XENLOG_ERR LIVEPATCH
> >>> + "%s: symbol %s is in init section, not resolving\n",
> >>> + elf->name, elf->sym[i].name);
> >>> + rc = -ENXIO;
> >>> + break;
> >>> + }
> >>
> >> ... wouldn't it make sense to still warn in this case when "force" is set?
> >
> > Pondered it, I was thinking that a user would first run without
> > --force, and use the option as a result of seeing the first failure.
> >
> > However if there is more than one check that's bypassed, further ones
> > won't be noticed, so:
> >
> > else if ( st_value >= (uintptr_t)&__init_begin &&
> > st_value < (uintptr_t)&__init_end )
> > {
> > printk(XENLOG_ERR LIVEPATCH
> > "%s: symbol %s is in init section, not resolving\n",
> > elf->name, elf->sym[i].name);
> > if ( !force )
> > {
> > rc = -ENXIO;
> > break;
> > }
> > }
> >
> > Would be OK then?
>
> Perhaps. "not resolving" isn't quite true when "force" is true, and warnings
> would also better not be issued with XENLOG_ERR.
I was assuming that printing as XENLOG_ERR level would still be OK -
even if bypassed because of the usage of --force. The "not resolving"
part should indeed go away. Maybe this is better:
else if ( st_value >= (uintptr_t)&__init_begin &&
st_value < (uintptr_t)&__init_end )
{
printk("%s" LIVEPATCH "%s: symbol %s is in init section%s\n",
force ? XENLOG_WARNING : XENLOG_ERR,
elf->name, elf->sym[i].name,
force ? "" : ", not resolving");
if ( !force )
{
rc = -ENXIO;
break;
}
}
Thanks, Roger.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 2/4] livepatch: introduce --force option
2024-04-23 13:12 ` [PATCH v3 2/4] livepatch: introduce --force option Roger Pau Monne
2024-04-23 13:38 ` Jan Beulich
@ 2024-04-23 16:05 ` Anthony PERARD
1 sibling, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2024-04-23 16:05 UTC (permalink / raw)
To: Roger Pau Monne
Cc: xen-devel, Juergen Gross, Andrew Cooper, George Dunlap,
Jan Beulich, Julien Grall, Stefano Stabellini, Ross Lagerwall
On Tue, Apr 23, 2024 at 03:12:47PM +0200, Roger Pau Monne wrote:
> Introduce a xen-livepatch tool --force option, that's propagated into the
> hyerpvisor for livepatch operations. The intention is for the option to be
> used to bypass some checks that would otherwise prevent the patch from being
> loaded.
>
> Re purpose the pad field in xen_sysctl_livepatch_op to be a flags field that
> applies to all livepatch operations. The flag is currently only set by the
> hypercall wrappers for the XEN_SYSCTL_LIVEPATCH_UPLOAD operation, as that's so
> far the only one where it will be used initially. Other uses can be added as
> required.
>
> Note that helpers would set the .pad field to 0, that's been removed since the
> structure is already zero initialized at definition.
>
> No functional usages of the new flag introduced in this patch.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
For the tools:
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections
2024-04-23 15:03 ` Roger Pau Monné
@ 2024-04-23 16:07 ` Jan Beulich
0 siblings, 0 replies; 17+ messages in thread
From: Jan Beulich @ 2024-04-23 16:07 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Ross Lagerwall, xen-devel
On 23.04.2024 17:03, Roger Pau Monné wrote:
> On Tue, Apr 23, 2024 at 04:28:59PM +0200, Jan Beulich wrote:
>> On 23.04.2024 16:26, Roger Pau Monné wrote:
>>> On Tue, Apr 23, 2024 at 03:44:42PM +0200, Jan Beulich wrote:
>>>> On 23.04.2024 15:12, Roger Pau Monne wrote:
>>>>> Livepatch payloads containing symbols that belong to init sections can only
>>>>> lead to page faults later on, as by the time the livepatch is loaded init
>>>>> sections have already been freed.
>>>>>
>>>>> Refuse to resolve such symbols and return an error instead.
>>>>>
>>>>> Note such resolutions are only relevant for symbols that point to undefined
>>>>> sections (SHN_UNDEF), as that implies the symbol is not in the current payload
>>>>> and hence must either be a Xen or a different livepatch payload symbol.
>>>>>
>>>>> Do not allow to resolve symbols that point to __init_begin, as that address is
>>>>> also unmapped. On the other hand, __init_end is not unmapped, and hence allow
>>>>> resolutions against it.
>>>>>
>>>>> Since __init_begin can alias other symbols (like _erodata for example)
>>>>> allow the force flag to override the check and resolve the symbol anyway.
>>>>>
>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>
>>>> In principle, as promised (and just to indicate earlier concerns were
>>>> addressed, as this is meaningless for other purposes)
>>>> Acked-by: Jan Beulich <jbeulich@suse.com>
>>>> However, ...
>>>>
>>>>> @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
>>>>> break;
>>>>> }
>>>>> }
>>>>> +
>>>>> + /*
>>>>> + * Ensure not an init symbol. Only applicable to Xen symbols, as
>>>>> + * livepatch payloads don't have init sections or equivalent.
>>>>> + */
>>>>> + else if ( st_value >= (uintptr_t)&__init_begin &&
>>>>> + st_value < (uintptr_t)&__init_end && !force )
>>>>> + {
>>>>> + printk(XENLOG_ERR LIVEPATCH
>>>>> + "%s: symbol %s is in init section, not resolving\n",
>>>>> + elf->name, elf->sym[i].name);
>>>>> + rc = -ENXIO;
>>>>> + break;
>>>>> + }
>>>>
>>>> ... wouldn't it make sense to still warn in this case when "force" is set?
>>>
>>> Pondered it, I was thinking that a user would first run without
>>> --force, and use the option as a result of seeing the first failure.
>>>
>>> However if there is more than one check that's bypassed, further ones
>>> won't be noticed, so:
>>>
>>> else if ( st_value >= (uintptr_t)&__init_begin &&
>>> st_value < (uintptr_t)&__init_end )
>>> {
>>> printk(XENLOG_ERR LIVEPATCH
>>> "%s: symbol %s is in init section, not resolving\n",
>>> elf->name, elf->sym[i].name);
>>> if ( !force )
>>> {
>>> rc = -ENXIO;
>>> break;
>>> }
>>> }
>>>
>>> Would be OK then?
>>
>> Perhaps. "not resolving" isn't quite true when "force" is true, and warnings
>> would also better not be issued with XENLOG_ERR.
>
> I was assuming that printing as XENLOG_ERR level would still be OK -
> even if bypassed because of the usage of --force. The "not resolving"
> part should indeed go away. Maybe this is better:
>
> else if ( st_value >= (uintptr_t)&__init_begin &&
> st_value < (uintptr_t)&__init_end )
> {
> printk("%s" LIVEPATCH "%s: symbol %s is in init section%s\n",
> force ? XENLOG_WARNING : XENLOG_ERR,
> elf->name, elf->sym[i].name,
> force ? "" : ", not resolving");
> if ( !force )
> {
> rc = -ENXIO;
> break;
> }
> }
I'd be okay with this; the livepatch maintainers will have the ultimate say.
Jan
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2024-04-23 16:07 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-23 13:12 [PATCH v3 0/4] livepatch: minor bug fixes and improvements Roger Pau Monne
2024-04-23 13:12 ` [PATCH v3 1/4] xen-livepatch: fix parameter name parsing Roger Pau Monne
2024-04-23 13:33 ` Jan Beulich
2024-04-23 14:11 ` Roger Pau Monné
2024-04-23 13:12 ` [PATCH v3 2/4] livepatch: introduce --force option Roger Pau Monne
2024-04-23 13:38 ` Jan Beulich
2024-04-23 16:05 ` Anthony PERARD
2024-04-23 13:12 ` [PATCH v3 3/4] livepatch: refuse to resolve symbols that belong to init sections Roger Pau Monne
2024-04-23 13:44 ` Jan Beulich
2024-04-23 14:26 ` Roger Pau Monné
2024-04-23 14:28 ` Jan Beulich
2024-04-23 15:03 ` Roger Pau Monné
2024-04-23 16:07 ` Jan Beulich
2024-04-23 13:12 ` [PATCH v3 4/4] x86/livepatch: perform sanity checks on the payload exception table contents Roger Pau Monne
2024-04-23 13:51 ` Jan Beulich
2024-04-23 14:31 ` Roger Pau Monné
2024-04-23 14:35 ` Jan Beulich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.