Reputation: 1
I'm trying to use libseccomp to catch syscalls and get in trouble. As the title says, supervisor can only catch first getpid(). It seems like the fd is no longer vaild(not sure) after first getpid(). The errno is 22:Invalid argument.
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>
#include <seccomp.h>
using namespace std;
int main()
{
int pp[2];
pipe(pp);
pid_t pid = fork();
if(pid == 0)
{
//target
close(pp[0]);
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_NOTIFY, SCMP_SYS(getpid), 0);
seccomp_load(ctx);
int fd = seccomp_notify_fd(ctx);
write(pp[1], &fd, sizeof(fd));
cout << getpid() << endl;//first time call getpid(), success. Supervisor can receive message and send a respond normally. The syscall was executed.
cout << getpid() << endl;//second time call getpid(), supervisor can't receive message.
}
else
{
//supervisor
seccomp_notif *req;
seccomp_notif_resp *resp;
seccomp_notify_alloc(&req, &resp);
int fd, child_fd;
close(pp[1]);
read(pp[0], &child_fd, sizeof(child_fd));
int pidfd = syscall(SYS_pidfd_open, pid, 0);
while(1)
{
fd = syscall(SYS_pidfd_getfd, pidfd, child_fd, 0);
if(fd != -1)break;
}
int status = 0;
fd_set fdset;
while(1)
{
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
if(select(fd+1, &fdset, NULL, NULL, NULL) != -1)
{
sleep(1);
cout << "result_of_req:" << seccomp_notify_receive(fd, req) << endl;
resp->id = req->id;
resp->error = 0;
resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
resp->val = 0;
cout << "result_of_resp:" << seccomp_notify_respond(fd, resp) << endl;
}
}
}
return 0;
}
Program output:
result_of_req:0 //0:success -125:fail.
result_of_resp:0
29155//first getpid()
result_of_req:-125
result_of_resp:-125
result_of_req:-125
result_of_resp:-125
result_of_req:-125
result_of_resp:-125//repeat forever
...
In my expectations, the program will display pid twice. I don't have any idea what's wrong with the code.
Upvotes: 0
Views: 66