mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
lib: make safe_copy_string_from_guest() validate input
... rather than papering over guest flaws: Strings passed ought to be nul- terminated (yet sadly libxc hasn't been doing so thus far). This way we also avoid order-1 allocations, seeing that all present callers pass PAGE_SIZE for max_size. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Anthony PERARD <anthony.perard@vates.tech> Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> # Changelog
This commit is contained in:
1 parent
dc21138144
commit
508209c473
4 files changed
+20
-10
No files matched your search
@@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
## [4.23.0 UNRELEASED](https://xenbits.xenproject.org/gitweb/?p=xen.git;a=shortlog;h=staging) - TBD
|
||||
|
||||
### Changed
|
||||
- XEN_DOMCTL_DEV_DT's, FLASK_[GS]ETBOOL's, and FLASK_DEVICETREE_LABEL's input
|
||||
string sizes need to include the nul terminator.
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ struct xen_domctl_assign_device {
|
||||
uint32_t machine_sbdf; /* machine PCI ID of assigned device */
|
||||
} pci;
|
||||
struct {
|
||||
uint32_t size; /* Length of the path */
|
||||
uint32_t size; /* Length of the path, including nul terminator */
|
||||
XEN_GUEST_HANDLE_64(char) path; /* Path to the device tree node */
|
||||
#ifdef __XEN__
|
||||
struct dt_device_node *dev; /* Resolved device node of the above */
|
||||
|
||||
@@ -26,7 +26,8 @@ typedef struct xen_flask_setenforce xen_flask_setenforce_t;
|
||||
struct xen_flask_sid_context {
|
||||
/* IN/OUT: sid to convert to/from string */
|
||||
uint32_t sid;
|
||||
/* IN: size of the context buffer
|
||||
/*
|
||||
* IN: size of the context buffer, including nul terminator
|
||||
* OUT: actual size of the output context string
|
||||
*/
|
||||
uint32_t size;
|
||||
@@ -86,8 +87,11 @@ struct xen_flask_boolean {
|
||||
uint8_t new_value;
|
||||
/* IN: commit new value instead of only setting pending [SET] */
|
||||
uint8_t commit;
|
||||
/* IN: size of boolean name buffer [GET/SET]
|
||||
* OUT: actual size of name [GET only] */
|
||||
/*
|
||||
* IN: size of boolean name buffer [GET/SET]; must cover nul terminator
|
||||
* if "name" (below) is an input
|
||||
* OUT: actual size of name [GET only]
|
||||
*/
|
||||
uint32_t size;
|
||||
/* IN: if bool_id is -1, used to find boolean [GET/SET]
|
||||
* OUT: textual name of boolean [GET only]
|
||||
@@ -150,7 +154,7 @@ typedef struct xen_flask_relabel xen_flask_relabel_t;
|
||||
struct xen_flask_devicetree_label {
|
||||
/* IN */
|
||||
uint32_t sid;
|
||||
uint32_t length;
|
||||
uint32_t length; /* length of the path, including nul terminator */
|
||||
XEN_GUEST_HANDLE(char) path;
|
||||
};
|
||||
typedef struct xen_flask_devicetree_label xen_flask_devicetree_label_t;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <xen/err.h>
|
||||
|
||||
/*
|
||||
* The function copies a string from the guest and adds a NUL to
|
||||
* make sure the string is correctly terminated.
|
||||
* The function copies a string from the guest and checks there's a NUL
|
||||
* terminating the string.
|
||||
*/
|
||||
char *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
|
||||
size_t size, size_t max_size)
|
||||
@@ -14,8 +14,7 @@ char *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
|
||||
if ( size > max_size )
|
||||
return ERR_PTR(-ENOBUFS);
|
||||
|
||||
/* Add an extra +1 to append \0 */
|
||||
tmp = xmalloc_array(char, size + 1);
|
||||
tmp = xmalloc_array(char, size);
|
||||
if ( !tmp )
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -24,7 +23,12 @@ char *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
|
||||
xfree(tmp);
|
||||
return ERR_PTR(-EFAULT);
|
||||
}
|
||||
tmp[size] = '\0';
|
||||
|
||||
if ( !memchr(tmp, 0, size) )
|
||||
{
|
||||
xfree(tmp);
|
||||
return ERR_PTR(-EMSGSIZE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||