Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can 't use kvm_vm_ioctl #109

Open
wangbaba523 opened this issue Jul 19, 2021 · 10 comments
Open

can 't use kvm_vm_ioctl #109

wangbaba523 opened this issue Jul 19, 2021 · 10 comments

Comments

@wangbaba523
Copy link

wangbaba523 commented Jul 19, 2021

hi,I don't want to use PathToSocket, so I didn't add
<qemu:arg value='-chardev'/>
<qemu:arg value='socket,patch=/tmp/introspector,id=chardev0'>
<........>
to the XML file.
But,In order to use "KVM_INTROSPECTION_HOOK", I am in kvm_dev_ioctl add nitro of "KVM_NITRO_ATTACH_VM" to get the fd communicating with VM, But when we use this fd to communicate with VM, we can 't in kvm_vm_ioctl, could you tell me what's wrong, or how can I add it. Thanks!

@Wenzel
Copy link
Member

Wenzel commented Jul 19, 2021

hi @wangbaba523 ,

If I'm not mistaken, KVM_INTROSPECTION_HOOK refers to the bitdefender KVMI subsystem, the new API that is currently maintained by this project

KVM_NITRO_ATTACH_VM is refering to the Nitro project for syscall interception, which is now deprecated.
You can't use both at the same time

@wangbaba523
Copy link
Author

hi @wangbaba523 ,

If I'm not mistaken, KVM_INTROSPECTION_HOOK refers to the bitdefender KVMI subsystem, the new API that is currently maintained by this project

KVM_NITRO_ATTACH_VM is refering to the Nitro project for syscall interception, which is now deprecated.
You can't use both at the same time

yes,I know,I add the nitro code in KVMI subsystem to support it ,in kvm_dev_ioctl add
case KVM_VMI_ATTACH_VM:

    r = -EFAULT;
    if(copy_from_user(&creator, argp, sizeof(pid_t)))
        goto out;
    r = -ESRCH;
    
    kvm = kvmi_get_vm_by_creator(creator);
    if(kvm == NULL)
        goto out;
    kvm_get_kvm(kvm);
    r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR | O_CLOEXEC);
    
    if(r<0)
        kvm_put_kvm(kvm);

    break;

@adlazar
Copy link
Collaborator

adlazar commented Jul 20, 2021

@wangbaba523, can you show kvmi_get_vm_by_creator() ?

@wangbaba523
Copy link
Author

/*
This function uses “/var/run/libvirt/qemu/vm.pid”
to find the kvm structure of the corresponding virtual machine
*/

struct kvm* kvmi_get_vm_by_creator(pid_t creator)
{
struct kvm *rv;
struct kvm *kvm;

rv = NULL;

spin_lock(&kvm_lock);
list_for_each_entry(kvm,&vm_list,vm_list)
if(kvm->mm->owner->pid == creator){
rv = kvm;
break;
}
spin_unlock(&kvm_lock);

return rv;
}

@adlazar
Copy link
Collaborator

adlazar commented Jul 21, 2021

The KVMi subsystem uses a socket. On one side of this socket is the QEMU process of the introspected guest + the kernel (KVM) and on the other side is the introspection tool.

QEMU initiates the connection by writing and reading during a simple handshake (see handshake header). After this, the socket is handed over to KVM, where the KVMi subsystem will use a couple of socket specific functions (see kvmi_msg.c for sock_fd_lookup(), sock_fd_put(), kernel_sock_shutdown(), kernel_recvmsg(), kernel_sendmsg()).

You'll have to replace the code using the socket functions (from QEMU and KVMi) if you still want to use the KVMi API without a socket.

@wangbaba523
Copy link
Author

Thank you for your reply,but how to call the case of "KVM_INTROSPECTION_HOOK"

in kvmi-v7 /virt/kvm/kvm_main.c
case KVM_INTROSPECTION_HOOK:
if (enable_introspection)
r = kvmi_ioctl_hook(kvm, argp);
else
r = -EPERM;
break;

@adlazar
Copy link
Collaborator

adlazar commented Jul 23, 2021

I don't know how would you combine Nitro and KVMi.

You said that you don't want to use a socket. I assumed you will replace it with another "channel".

@wangbaba523
Copy link
Author

In short, i want to use the function of
.....
struct kvm_introspection_hook i;
ioctl(vmfd, KVM_INTROSPECTION_HOOK, &i);
......
in my vmi process.but there can' t find vmfd, So I added nitro code to get vmfd.

@adlazar
Copy link
Collaborator

adlazar commented Jul 28, 2021

Do you want to use QEMU to run your introspected VMs or something else? Because the kvm-vmi/qemu project (kvmi-v7 branch) has all that you might need.
In your code, vmfd is the file descriptor returned by ioctl/KVM_CREATE_VM (kvm_state from QEMU code).

@Wenzel
Copy link
Member

Wenzel commented Jul 28, 2021

@wangbaba523 from what I understand you are trying to use both Nitro and KVMi and these are 2 incompatibles APIs.

What you need to do is to rebuild the Nitro capabilities on top of the KVMi API.
Nitro was capable of trapping syscall automatically, by forcing a VM-exit on the syscall/sysret and sysenter/sysexit instructions.

You will need to setup a breakpoint system manually and figure out where the syscall entrypoint and exitpoints are, insert them and reconstruct the semantic context.

I'm not maintaining Nitro anymore.

I hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants