[RFC v2 4/7] kvm: arm64: introduce check_user

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently, if we need to check the value of the register defined by user
space, we should check it in set_user.  However, some system registers
may use the same set_user (for example, almost all ID registers), which
make it difficult to validate the value defined by user space.

Introduce check_user to solve the problem.  And apply check_user before
set_user to make sure that the value of register is valid.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@xxxxxxxxxx>
Signed-off-by: Peng Liang <liangpeng10@xxxxxxxxxx>
---
 arch/arm64/kvm/sys_regs.c | 7 +++++++
 arch/arm64/kvm/sys_regs.h | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2b0fa8d5ac62..86ebb8093c3c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2684,6 +2684,7 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 {
 	const struct sys_reg_desc *r;
 	void __user *uaddr = (void __user *)(unsigned long)reg->addr;
+	int err;
 
 	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
 		return demux_c15_set(reg->id, uaddr);
@@ -2699,6 +2700,12 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 	if (sysreg_hidden_from_user(vcpu, r))
 		return -ENOENT;
 
+	if (r->check_user) {
+		err = (r->check_user)(vcpu, r, reg, uaddr);
+		if (err)
+			return err;
+	}
+
 	if (r->set_user)
 		return (r->set_user)(vcpu, r, reg, uaddr);
 
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index 5a6fc30f5989..9bce5e9a3490 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -53,6 +53,12 @@ struct sys_reg_desc {
 			const struct kvm_one_reg *reg, void __user *uaddr);
 	int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 			const struct kvm_one_reg *reg, void __user *uaddr);
+	/*
+	 * Check the value userspace passed.  It should return 0 on success and
+	 * otherwise on failure.
+	 */
+	int (*check_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+			  const struct kvm_one_reg *reg, void __user *uaddr);
 
 	/* Return mask of REG_* runtime visibility overrides */
 	unsigned int (*visibility)(const struct kvm_vcpu *vcpu,
-- 
2.26.2




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux