mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
xen: guestcopy: Provide an helper to safely copy string from guest
Flask code already provides a helper to copy a string from guest. In a later
patch, the new DT hypercalls will need a similar function.
To avoid code duplication, copy the flask helper (flask_copying_string) to
common code:
- Rename into safe_copy_string_from_guest
- Add comment to explain the extra +1
- Return the buffer directly and use the macros provided by
xen/err.h to return an error code if necessary.
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
This commit is contained in:
1 parent
b49a7517bb
commit
6ea9f0481e
4 files changed
+50
-36
No files matched your search
@@ -9,6 +9,7 @@ obj-y += event_2l.o
|
||||
obj-y += event_channel.o
|
||||
obj-y += event_fifo.o
|
||||
obj-y += grant_table.o
|
||||
obj-y += guestcopy.o
|
||||
obj-y += irq.o
|
||||
obj-y += kernel.o
|
||||
obj-y += keyhandler.o
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/err.h>
|
||||
|
||||
/*
|
||||
* The function copies a string from the guest and adds a NUL to
|
||||
* make sure the string is correctly terminated.
|
||||
*/
|
||||
char *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
|
||||
size_t size, size_t max_size)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if ( size > max_size )
|
||||
return ERR_PTR(-ENOBUFS);
|
||||
|
||||
/* Add an extra +1 to append \0 */
|
||||
tmp = xmalloc_array(char, size + 1);
|
||||
if ( !tmp )
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if ( copy_from_guest(tmp, u_buf, size) )
|
||||
{
|
||||
xfree(tmp);
|
||||
return ERR_PTR(-EFAULT);
|
||||
}
|
||||
tmp[size] = '\0';
|
||||
|
||||
return tmp;
|
||||
}
|
||||
@@ -8,6 +8,8 @@
|
||||
#define __XEN_GUEST_ACCESS_H__
|
||||
|
||||
#include <asm/guest_access.h>
|
||||
#include <xen/types.h>
|
||||
#include <public/xen.h>
|
||||
|
||||
#define copy_to_guest(hnd, ptr, nr) \
|
||||
copy_to_guest_offset(hnd, 0, ptr, nr)
|
||||
@@ -27,4 +29,7 @@
|
||||
#define __clear_guest(hnd, nr) \
|
||||
__clear_guest_offset(hnd, 0, nr)
|
||||
|
||||
char *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
|
||||
size_t size, size_t max_size);
|
||||
|
||||
#endif /* __XEN_GUEST_ACCESS_H__ */
|
||||
+13
-36
@@ -12,6 +12,7 @@
|
||||
#include <xen/event.h>
|
||||
#include <xsm/xsm.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/err.h>
|
||||
|
||||
#include <public/xsm/flask_op.h>
|
||||
|
||||
@@ -93,29 +94,6 @@ static int domain_has_security(struct domain *d, u32 perms)
|
||||
perms, NULL);
|
||||
}
|
||||
|
||||
static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf,
|
||||
size_t size, size_t max_size)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if ( size > max_size )
|
||||
return -ENOENT;
|
||||
|
||||
tmp = xmalloc_array(char, size + 1);
|
||||
if ( !tmp )
|
||||
return -ENOMEM;
|
||||
|
||||
if ( copy_from_guest(tmp, u_buf, size) )
|
||||
{
|
||||
xfree(tmp);
|
||||
return -EFAULT;
|
||||
}
|
||||
tmp[size] = 0;
|
||||
|
||||
*buf = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* COMPAT */
|
||||
|
||||
static int flask_security_user(struct xen_flask_userlist *arg)
|
||||
@@ -129,9 +107,9 @@ static int flask_security_user(struct xen_flask_userlist *arg)
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
rv = flask_copyin_string(arg->u.user, &user, arg->size, PAGE_SIZE);
|
||||
if ( rv )
|
||||
return rv;
|
||||
user = safe_copy_string_from_guest(arg->u.user, arg->size, PAGE_SIZE);
|
||||
if ( IS_ERR(user) )
|
||||
return PTR_ERR(user);
|
||||
|
||||
rv = security_get_user_sids(arg->start_sid, user, &sids, &nsids);
|
||||
if ( rv < 0 )
|
||||
@@ -244,9 +222,9 @@ static int flask_security_context(struct xen_flask_sid_context *arg)
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
rv = flask_copyin_string(arg->context, &buf, arg->size, PAGE_SIZE);
|
||||
if ( rv )
|
||||
return rv;
|
||||
buf = safe_copy_string_from_guest(arg->context, arg->size, PAGE_SIZE);
|
||||
if ( IS_ERR(buf) )
|
||||
return PTR_ERR(buf);
|
||||
|
||||
rv = security_context_to_sid(buf, arg->size, &arg->sid);
|
||||
if ( rv < 0 )
|
||||
@@ -336,14 +314,13 @@ static int flask_security_setavc_threshold(struct xen_flask_setavc_threshold *ar
|
||||
static int flask_security_resolve_bool(struct xen_flask_boolean *arg)
|
||||
{
|
||||
char *name;
|
||||
int rv;
|
||||
|
||||
if ( arg->bool_id != -1 )
|
||||
return 0;
|
||||
|
||||
rv = flask_copyin_string(arg->name, &name, arg->size, bool_maxstr);
|
||||
if ( rv )
|
||||
return rv;
|
||||
name = safe_copy_string_from_guest(arg->name, arg->size, bool_maxstr);
|
||||
if ( IS_ERR(name) )
|
||||
return PTR_ERR(name);
|
||||
|
||||
arg->bool_id = security_find_bool(name);
|
||||
arg->size = 0;
|
||||
@@ -574,9 +551,9 @@ static int flask_devicetree_label(struct xen_flask_devicetree_label *arg)
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
rv = flask_copyin_string(arg->path, &buf, arg->length, PAGE_SIZE);
|
||||
if ( rv )
|
||||
return rv;
|
||||
buf = safe_copy_string_from_guest(arg->path, arg->length, PAGE_SIZE);
|
||||
if ( IS_ERR(buf) )
|
||||
return PTR_ERR(buf);
|
||||
|
||||
/* buf is consumed or freed by this function */
|
||||
rv = security_devicetree_setlabel(buf, sid);
|
||||
|
||||