dpu-utilities/0005-Add-whitelist-of-qtfs.patch
yangxin 4141866c23 Add udsproxy, add whitelist to qtfs and rexec, fix errors.
Signed-off-by: yangxin <245051644@qq.com>
2023-02-10 14:16:08 +00:00

897 lines
28 KiB
Diff

From 2052c2d81abe204e557b7b7d15be623caf26d7f7 Mon Sep 17 00:00:00 2001
From: yangxin <245051644@qq.com>
Date: Fri, 10 Feb 2023 16:37:27 +0800
Subject: [PATCH 1/5] Add whitelist of qtfs.
Signed-off-by: yangxin <245051644@qq.com>
---
qtfs/comm.h | 31 ++++
qtfs/misc.c | 2 -
qtfs/qtfs/Makefile | 2 +-
qtfs/qtfs/qtfs-mod.h | 1 -
qtfs/qtfs/sb.c | 17 +-
qtfs/qtfs/syscall.c | 3 +-
qtfs/qtfs_server/Makefile | 4 +-
qtfs/qtfs_server/fsops.c | 145 ++++++++++++++----
qtfs/qtfs_server/qtfs-server.c | 35 ++++-
qtfs/qtfs_server/qtfs-server.h | 1 +
qtfs/qtfs_server/user_engine.c | 51 +++++-
qtfs/req.h | 36 ++---
.../whitelist/libvirt/qtfs_whitelist | 35 +++++
13 files changed, 286 insertions(+), 77 deletions(-)
create mode 100644 usecases/transparent-offload/whitelist/libvirt/qtfs_whitelist
diff --git a/qtfs/comm.h b/qtfs/comm.h
index d639c19..901552c 100644
--- a/qtfs/comm.h
+++ b/qtfs/comm.h
@@ -13,6 +13,7 @@ enum {
_QTFS_IOCTL_EXIT,
_QTFS_IOCTL_ALLINFO,
+ _QTFS_IOCTL_WHITELIST,
_QTFS_IOCTL_CLEARALL,
_QTFS_IOCTL_LOG_LEVEL,
@@ -26,6 +27,7 @@ enum {
#define QTFS_IOCTL_EPOLL_THREAD_RUN _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EPOLL_THREAD_RUN)
#define QTFS_IOCTL_EXIT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EXIT)
#define QTFS_IOCTL_ALLINFO _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_ALLINFO)
+#define QTFS_IOCTL_WHITELIST _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_WHITELIST)
#define QTFS_IOCTL_CLEARALL _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_CLEARALL)
#define QTFS_IOCTL_LOGLEVEL _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_LOG_LEVEL)
#define QTFS_IOCTL_EPOLL_SUPPORT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EPOLL_SUPPORT)
@@ -42,6 +44,35 @@ struct qtfs_server_userp_s {
void *userp2;
};
+
+enum {
+ QTFS_WHITELIST_OPEN,
+ QTFS_WHITELIST_WRITE,
+ QTFS_WHITELIST_READ,
+ QTFS_WHITELIST_READDIR,
+ QTFS_WHITELIST_MKDIR,
+ QTFS_WHITELIST_RMDIR,
+ QTFS_WHITELIST_CREATE,
+ QTFS_WHITELIST_UNLINK,
+ QTFS_WHITELIST_RENAME,
+ QTFS_WHITELIST_SETATTR,
+ QTFS_WHITELIST_SETXATTR,
+ QTFS_WHITELIST_MOUNT,
+ QTFS_WHITELIST_MAX,
+};
+
+
+struct wl_item {
+ int len;
+ char path[4096];
+};
+
+struct whitelist {
+ int len;
+ int type;
+ struct wl_item wl[0];
+};
+
struct qtfs_thread_init_s {
int thread_nums;
struct qtfs_server_userp_s *userp;
diff --git a/qtfs/misc.c b/qtfs/misc.c
index 90c8d36..98222bd 100644
--- a/qtfs/misc.c
+++ b/qtfs/misc.c
@@ -61,7 +61,6 @@ void qtfs_req_size(void)
qtfs_diag_info->req_size[QTFS_REQ_MOUNT] = sizeof(struct qtreq_mount);
qtfs_diag_info->req_size[QTFS_REQ_OPEN] = sizeof(struct qtreq_open);
qtfs_diag_info->req_size[QTFS_REQ_CLOSE] = sizeof(struct qtreq_close);
- qtfs_diag_info->req_size[QTFS_REQ_READ] = sizeof(struct qtreq_read);
qtfs_diag_info->req_size[QTFS_REQ_READITER] = sizeof(struct qtreq_readiter);
qtfs_diag_info->req_size[QTFS_REQ_WRITE] = sizeof(struct qtreq_write);
qtfs_diag_info->req_size[QTFS_REQ_LOOKUP] = sizeof(struct qtreq_lookup);
@@ -92,7 +91,6 @@ void qtfs_req_size(void)
qtfs_diag_info->rsp_size[QTFS_REQ_MOUNT] = sizeof(struct qtrsp_mount);
qtfs_diag_info->rsp_size[QTFS_REQ_OPEN] = sizeof(struct qtrsp_open);
qtfs_diag_info->rsp_size[QTFS_REQ_CLOSE] = sizeof(struct qtrsp_close);
- qtfs_diag_info->rsp_size[QTFS_REQ_READ] = sizeof(struct qtrsp_read);
qtfs_diag_info->rsp_size[QTFS_REQ_READITER] = sizeof(struct qtrsp_readiter);
qtfs_diag_info->rsp_size[QTFS_REQ_WRITE] = sizeof(struct qtrsp_write);
qtfs_diag_info->rsp_size[QTFS_REQ_LOOKUP] = sizeof(struct qtrsp_lookup);
diff --git a/qtfs/qtfs/Makefile b/qtfs/qtfs/Makefile
index f3c6014..f03ec52 100644
--- a/qtfs/qtfs/Makefile
+++ b/qtfs/qtfs/Makefile
@@ -11,4 +11,4 @@ qtfs:
clean:
make -C $(KBUILD) M=$(PWD) clean
- rm -rf ../*.o
+ rm -rf ../*.o ../.*.o.cmd
diff --git a/qtfs/qtfs/qtfs-mod.h b/qtfs/qtfs/qtfs-mod.h
index 5a30868..6ba7a4d 100644
--- a/qtfs/qtfs/qtfs-mod.h
+++ b/qtfs/qtfs/qtfs-mod.h
@@ -35,7 +35,6 @@ extern struct kmem_cache *qtfs_inode_priv_cache;
struct private_data {
int fd;
- unsigned long long file;
};
struct qtfs_inode_priv {
diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c
index 06ce402..9374cfb 100644
--- a/qtfs/qtfs/sb.c
+++ b/qtfs/qtfs/sb.c
@@ -196,7 +196,6 @@ int qtfs_open(struct inode *inode, struct file *file)
return err;
}
qtfs_info("qtfs open:%s success, f_mode:%o flag:%x, fd:%d", req->path, file->f_mode, file->f_flags, rsp->fd);
- data->file = rsp->file;
data->fd = rsp->fd;
WARN_ON(file->private_data);
file->private_data = data;
@@ -287,9 +286,9 @@ ssize_t qtfs_readiter(struct kiocb *kio, struct iov_iter *iov)
return -ENOMEM;
}
- req->file = private->file;
- if (req->file <= 0) {
- qtfs_err("qtfs_readiter: invalid file(0x%llx)", req->file);
+ req->fd = private->fd;
+ if (req->fd <= 0) {
+ qtfs_err("qtfs_readiter: invalid file(0x%llx)", req->fd);
qtfs_conn_put_param(pvar);
return -EINVAL;
}
@@ -359,9 +358,9 @@ ssize_t qtfs_writeiter(struct kiocb *kio, struct iov_iter *iov)
return -ENOMEM;
}
- req->d.file = private->file;
- if (req->d.file < 0) {
- qtfs_err("qtfs_write: invalid file(0x%llx)", req->d.file);
+ req->d.fd = private->fd;
+ if (req->d.fd < 0) {
+ qtfs_err("qtfs_write: invalid file(0x%llx)", req->d.fd);
qtfs_conn_put_param(pvar);
return -EINVAL;
}
@@ -617,7 +616,7 @@ qtfsfifo_poll(struct file *filp, poll_table *wait)
p = &priv->readq.head;
- if (IS_ERR((void *)fpriv->file) || (void *)fpriv->file == NULL) {
+ if (fpriv->fd < 0) {
qtfs_err("fifo poll priv file invalid.");
return 0;
}
@@ -627,7 +626,7 @@ qtfsfifo_poll(struct file *filp, poll_table *wait)
return 0;
}
req = qtfs_sock_msg_buf(pvar, QTFS_SEND);
- req->file = fpriv->file;
+ req->fd = fpriv->fd;
rsp = qtfs_remote_run(pvar, QTFS_REQ_FIFOPOLL, sizeof(struct qtreq_poll));
if (IS_ERR(rsp) || rsp == NULL) {
qtfs_conn_put_param(pvar);
diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c
index 85cfbbe..2912f48 100644
--- a/qtfs/qtfs/syscall.c
+++ b/qtfs/qtfs/syscall.c
@@ -110,7 +110,6 @@ static void do_epoll_ctl_remote(int op, struct epoll_event __user *event, struct
}
req = qtfs_sock_msg_buf(pvar, QTFS_SEND);
req->fd = priv->fd;
- req->file = priv->file;
req->op = op;
if (ep_op_has_event(op) && copy_from_user(&tmp, event, sizeof(struct epoll_event))) {
qtfs_err("qtfs do epoll ctl remote copy from user failed.");
@@ -131,7 +130,7 @@ static void do_epoll_ctl_remote(int op, struct epoll_event __user *event, struct
} else {
qtinfo_cntinc(QTINF_EPOLL_DELFDS);
}
- qtfs_info("qtfs do epoll ctl remote success, fd:%d file:%lx.", req->fd, (unsigned long)req->file);
+ qtfs_info("qtfs do epoll ctl remote success, fd:%d.", req->fd);
qtfs_conn_put_param(pvar);
return;
}
diff --git a/qtfs/qtfs_server/Makefile b/qtfs/qtfs_server/Makefile
index c1c5ef6..9c6bcd5 100644
--- a/qtfs/qtfs_server/Makefile
+++ b/qtfs/qtfs_server/Makefile
@@ -10,9 +10,9 @@ qtfs_server:
make -C $(KBUILD) M=$(PWD) modules
engine:
- gcc -O2 -o engine user_engine.c -lpthread -I../ -DQTFS_SERVER
+ gcc -O2 -o engine user_engine.c -lpthread -lglib-2.0 -I../ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -DQTFS_SERVER
clean:
make -C $(KBUILD) M=$(PWD) clean
rm -rf engine
- rm -rf ../*.o
+ rm -rf ../*.o ../.*.o.cmd
diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c
index 48ec7ab..d00db6d 100644
--- a/qtfs/qtfs_server/fsops.c
+++ b/qtfs/qtfs_server/fsops.c
@@ -23,6 +23,21 @@
#define RSP(arg) (arg->out)
#define USERP(arg) (arg->userp)
+bool in_white_list(char *path, int type)
+{
+ if (!whitelist[type]) {
+ return true;
+ }
+ int i, in_wl = -1;
+ for (i = 0; i < whitelist[type]->len; i++) {
+ if (!strncmp(path, whitelist[type]->wl[i].path, whitelist[type]->wl[i].len)){
+ in_wl = i;
+ break;
+ }
+ }
+ return in_wl != -1;
+}
+
static inline void qtfs_inode_info_fill(struct inode_info *ii, struct inode *inode)
{
ii->mode = inode->i_mode;
@@ -55,7 +70,6 @@ static int handle_ioctl(struct qtserver_arg *arg)
struct qtreq_ioctl *req = (struct qtreq_ioctl *)REQ(arg);
struct qtrsp_ioctl *rsp = (struct qtrsp_ioctl *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
-
file = filp_open(req->path, O_RDONLY, 0);
if (err_ptr(file)) {
qtfs_err("handle ioctl error, path:<%s> failed.\n", req->path);
@@ -188,9 +202,13 @@ static int handle_statfs(struct qtserver_arg *arg)
static int handle_mount(struct qtserver_arg *arg)
{
struct path path;
- int ret;
+ int ret, i, in_wl = -1;
struct qtreq_mount *req = (struct qtreq_mount *)REQ(arg);
struct qtrsp_mount *rsp = (struct qtrsp_mount *)RSP(arg);
+ if (!in_white_list(req->path, QTFS_WHITELIST_MOUNT)) {
+ rsp->ret = QTFS_ERR;
+ return sizeof(rsp->ret);
+ }
ret = kern_path(req->path, LOOKUP_DIRECTORY, &path);
if (ret) {
@@ -208,11 +226,15 @@ int handle_open(struct qtserver_arg *arg)
{
int fd;
int ret;
- struct fd f;
- struct file *file = NULL;
struct qtreq_open *req = (struct qtreq_open *)REQ(arg);
struct qtrsp_open *rsp = (struct qtrsp_open *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
+ if (!in_white_list(req->path, QTFS_WHITELIST_OPEN)) {
+ qtfs_err("handle open path:%s not permited", req->path);
+ rsp->ret = QTFS_ERR;
+ rsp->fd = -EACCES;
+ return sizeof(struct qtrsp_open);
+ }
ret = copy_to_user(userp->userp, req->path, strlen(req->path)+1);
if (ret) {
@@ -235,26 +257,11 @@ int handle_open(struct qtserver_arg *arg)
}
rsp->ret = QTFS_ERR;
rsp->fd = fd;
- rsp->file = 0;
return sizeof(struct qtrsp_open);
}
- f = fdget(fd);
- file = f.file;
- if (err_ptr(file)) {
- rsp->ret = QTFS_ERR;
- rsp->fd = PTR_ERR(file);
- // must close_fd(fd)?
- WARN_ON(1);
- qtfs_err("handle open get file pointer of <<%s>> error, fd:%d file err:%d.", req->path, fd, rsp->fd);
- // XXX: fileclose here?
- } else {
- rsp->ret = QTFS_OK;
- rsp->file = (__u64)file;
- rsp->fd = fd;
- }
- qtfs_info("handle open file :%s fd:%d filep:%lx.", req->path, fd, (unsigned long)rsp->file);
- fdput(f);
+ rsp->ret = QTFS_OK;
+ rsp->fd = fd;
return sizeof(struct qtrsp_open);
}
@@ -279,18 +286,30 @@ int handle_close(struct qtserver_arg *arg)
static int handle_readiter(struct qtserver_arg *arg)
{
struct file *file = NULL;
+ char *pathbuf, *fullname;
struct qtreq_readiter *req = (struct qtreq_readiter *)REQ(arg);
struct qtrsp_readiter *rsp = (struct qtrsp_readiter *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
size_t maxlen = (req->len >= sizeof(rsp->readbuf)) ? (sizeof(rsp->readbuf) - 1) : req->len;
- file = (struct file *)req->file;
+ file = fget(req->fd);
+ pathbuf = __getname();
+ fullname = file_path(file, pathbuf, PATH_MAX);
+ if (!in_white_list(fullname, QTFS_WHITELIST_READ)) {
+ qtfs_err("%s not in whitelist.\n", fullname);
+ __putname(pathbuf);
+ rsp->d.ret = QTFS_ERR;
+ rsp->d.len = 0;
+ rsp->d.errno = -ENOENT;
+ goto end;
+ }
+ __putname(pathbuf);
if (err_ptr(file)) {
qtfs_err("handle readiter error, open failed, file:%p.\n", file);
rsp->d.ret = QTFS_ERR;
rsp->d.len = 0;
rsp->d.errno = -ENOENT;
- return sizeof(struct qtrsp_readiter) - sizeof(rsp->readbuf) + rsp->d.len;
+ goto end;
}
if (file->f_op->read) {
int idx = 0;
@@ -326,23 +345,35 @@ static int handle_readiter(struct qtserver_arg *arg)
qtfs_info("handle readiter file:<%s>, len:%lu, rsplen:%ld, pos:%lld, ret:%d errno:%d.\n",
file->f_path.dentry->d_iname, req->len, rsp->d.len, req->pos, rsp->d.ret, rsp->d.errno);
+end:
+ fput(file);
return sizeof(struct qtrsp_readiter) - sizeof(rsp->readbuf) + rsp->d.len;
}
static int handle_write(struct qtserver_arg *arg)
{
struct file *file = NULL;
+ char *pathbuf, *fullname;
struct qtreq_write *req = (struct qtreq_write *)REQ(arg);
struct qtrsp_write *rsp = (struct qtrsp_write *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
int idx = 0, leftlen = 0, ret = 0, len = 0;
- file = (struct file *)req->d.file;
+ file = fget(req->d.fd);
+ pathbuf = __getname();
+ fullname = file_path(file, pathbuf, PATH_MAX);
+ if (!in_white_list(fullname, QTFS_WHITELIST_WRITE)) {
+ kfree(pathbuf);
+ rsp->ret = QTFS_ERR;
+ rsp->len = 0;
+ goto end;
+ }
+ __putname(pathbuf);
if (err_ptr(file)) {
qtfs_err("qtfs handle write error, filp:<%p> open failed.\n", file);
rsp->ret = QTFS_ERR;
rsp->len = 0;
- return sizeof(struct qtrsp_write);
+ goto end;
}
file->f_mode = req->d.mode;
@@ -372,6 +403,8 @@ static int handle_write(struct qtserver_arg *arg)
rsp->ret = (rsp->len <= 0) ? QTFS_ERR : QTFS_OK;
qtfs_info("handle write file<%s> %s, write len:%ld pos:%lld mode:%o flags:%x.", file->f_path.dentry->d_iname,
(rsp->ret == QTFS_ERR) ? "failed" : "succeded", rsp->len, req->d.pos, file->f_mode, file->f_flags);
+end:
+ fput(file);
return sizeof(struct qtrsp_write);
}
@@ -438,6 +471,12 @@ static int handle_readdir(struct qtserver_arg *arg)
.dir = (struct qtfs_dirent64 *)rsp->dirent,
.vldcnt = 0,
};
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_READDIR)) {
+ rsp->d.ret = QTFS_ERR;
+ rsp->d.vldcnt = 0;
+ return sizeof(struct qtrsp_readdir) - sizeof(rsp->dirent);
+ }
file = filp_open(req->path, O_RDONLY|O_NONBLOCK|O_DIRECTORY, 0);
if (err_ptr(file)) {
qtfs_err("handle readdir error, filp:<%s> open failed.\n", req->path);
@@ -466,7 +505,11 @@ static int handle_mkdir(struct qtserver_arg *arg)
struct inode *inode;
struct path path;
int ret;
-
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_MKDIR)) {
+ rsp->errno = -EFAULT;
+ goto err;
+ }
if (copy_to_user(userp->userp, req->path, strlen(req->path) + 1)) {
qtfs_err("handle mkdir copy to userp failed.\n");
rsp->errno = -EFAULT;
@@ -499,7 +542,11 @@ static int handle_rmdir(struct qtserver_arg *arg)
struct qtreq_rmdir *req = (struct qtreq_rmdir *)REQ(arg);
struct qtrsp_rmdir *rsp = (struct qtrsp_rmdir *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
-
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_RMDIR)) {
+ rsp->errno = -EFAULT;
+ goto err;
+ }
if (copy_to_user(userp->userp, req->path, strlen(req->path) + 1)) {
qtfs_err("handle rmdir copy to userp failed.\n");
rsp->errno = -EFAULT;
@@ -558,6 +605,12 @@ static int handle_setattr(struct qtserver_arg *arg)
struct inode *inode = NULL;
struct path path;
int ret;
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_SETATTR)) {
+ rsp->ret = QTFS_ERR;
+ rsp->errno = -ENOENT;
+ return sizeof(struct qtrsp_setattr);
+ }
ret = kern_path(req->path, 0, &path);
if (ret) {
@@ -610,6 +663,12 @@ int handle_icreate(struct qtserver_arg *arg)
struct inode *inode;
struct qtreq_icreate *req = (struct qtreq_icreate *)REQ(arg);
struct qtrsp_icreate *rsp = (struct qtrsp_icreate *)RSP(arg);
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_CREATE)) {
+ rsp->ret = QTFS_ERR;
+ rsp->errno = -ENOENT;
+ return sizeof(struct qtrsp_icreate);
+ }
file = filp_open(req->path, O_CREAT, req->mode);
if (err_ptr(file)) {
@@ -635,6 +694,12 @@ static int handle_mknod(struct qtserver_arg *arg)
struct path path;
int error;
unsigned int flags = LOOKUP_DIRECTORY;
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_CREATE)) {
+ rsp->ret = QTFS_ERR;
+ rsp->errno = -ENOENT;
+ return sizeof(struct qtrsp_mknod);
+ }
retry:
dent = kern_path_create(AT_FDCWD, req->path, &path, flags);
@@ -668,6 +733,11 @@ int handle_unlink(struct qtserver_arg *arg)
{
struct qtreq_unlink *req = (struct qtreq_unlink *)REQ(arg);
struct qtrsp_unlink *rsp = (struct qtrsp_unlink *)RSP(arg);
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_UNLINK)) {
+ rsp->errno = -ENOENT;
+ return sizeof(struct qtrsp_unlink);
+ }
rsp->errno = qtfs_kern_syms.do_unlinkat(AT_FDCWD, qtfs_kern_syms.getname_kernel(req->path));
if (rsp->errno < 0) {
@@ -770,7 +840,11 @@ int handle_rename(struct qtserver_arg *arg)
struct qtreq_rename *req = (struct qtreq_rename *)REQ(arg);
struct qtrsp_rename *rsp = (struct qtrsp_rename *)RSP(arg);
struct qtfs_server_userp_s *userp = (struct qtfs_server_userp_s *)USERP(arg);
-
+
+ if (!in_white_list(req->path, QTFS_WHITELIST_RENAME)) {
+ rsp->errno = -ENOENT;
+ goto err_handle;
+ }
if (copy_to_user(userp->userp, req->path, strlen(req->path) + 1) ||
copy_to_user(userp->userp2, &req->path[req->d.oldlen], strlen(&req->path[req->d.oldlen]) + 1)) {
qtfs_err("handle rename copy to userp failed.\n");
@@ -831,6 +905,12 @@ int handle_xattrset(struct qtserver_arg *arg)
struct path path;
int ret = 0;
+ if (!in_white_list(req->buf, QTFS_WHITELIST_SETXATTR)) {
+ rsp->errno = -ENOENT;
+ rsp->ret = QTFS_ERR;
+ goto err_handle;
+ }
+
ret = kern_path(req->buf, 0, &path);
if (ret) {
qtfs_err("handle xattrset path error, file:%s.\n", req->buf);
@@ -997,7 +1077,7 @@ int handle_fifopoll(struct qtserver_arg *arg)
struct poll_wqueues table;
poll_table *pt;
- filp = (struct file *)req->file;
+ filp = fget(req->fd);
inode = filp->f_inode;
if (!S_ISFIFO(inode->i_mode)) {
msleep(1);
@@ -1011,6 +1091,7 @@ int handle_fifopoll(struct qtserver_arg *arg)
if (pipe == NULL) {
qtfs_err("file :%s pipe data is NULL.", filp->f_path.dentry->d_iname);
rsp->ret = QTFS_ERR;
+ fput(filp);
return sizeof(struct qtrsp_poll);
}
head = READ_ONCE(pipe->head);
@@ -1035,6 +1116,7 @@ end:
qtfs_info("handle fifo poll f_mode:%o: %s get poll mask 0x%x poll:%lx\n",
filp->f_mode, filp->f_path.dentry->d_iname, rsp->mask, (unsigned long)filp->f_op->poll);
+ fput(filp);
return sizeof(struct qtrsp_poll);
}
@@ -1055,8 +1137,8 @@ int handle_epollctl(struct qtserver_arg *arg)
}
qtinfo_cntinc((req->op == EPOLL_CTL_ADD) ? QTINF_EPOLL_ADDFDS : QTINF_EPOLL_DELFDS);
rsp->ret = QTFS_OK;
- qtfs_info("handle do epoll ctl success, fd:%d file:%lx op:%x data:%lx poll_t:%x.",
- req->fd, (unsigned long)req->file, req->op, req->event.data, (unsigned)req->event.events);
+ qtfs_info("handle do epoll ctl success, fd:%d op:%x data:%lx poll_t:%x.",
+ req->fd, req->op, req->event.data, (unsigned)req->event.events);
return sizeof(struct qtrsp_epollctl);
}
@@ -1197,3 +1279,4 @@ int qtfs_sock_server_run(struct qtfs_sock_var_s *pvar)
qtfs_sock_msg_clear(pvar);
return (ret < 0) ? QTERROR : QTOK;
}
+
diff --git a/qtfs/qtfs_server/qtfs-server.c b/qtfs/qtfs_server/qtfs-server.c
index bcd60b7..b0b8ab0 100644
--- a/qtfs/qtfs_server/qtfs-server.c
+++ b/qtfs/qtfs_server/qtfs-server.c
@@ -28,6 +28,8 @@ struct qtfs_server_epoll_s qtfs_epoll = {
.events = NULL,
};
+struct whitelist* whitelist[QTFS_WHITELIST_MAX];
+
long qtfs_server_epoll_thread(struct qtfs_sock_var_s *pvar)
{
int n;
@@ -140,9 +142,10 @@ long qtfs_server_epoll_init(void)
long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- int i;
+ int i, len;
long ret = 0;
struct qtfs_sock_var_s *pvar;
+ struct whitelist *tmp;
struct qtfs_thread_init_s init_userp;
switch (cmd) {
case QTFS_IOCTL_THREAD_INIT:
@@ -216,6 +219,26 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a
case QTFS_IOCTL_LOGLEVEL:
ret = qtfs_misc_ioctl(file, cmd, arg);
break;
+ case QTFS_IOCTL_WHITELIST:
+ if (copy_from_user(&len, (void __user *)arg, sizeof(int))) {
+ qtfs_err("qtfs ioctl white init copy from user failed.");
+ return QTERROR;
+ }
+ tmp = (struct whitelist *)kmalloc(sizeof(struct whitelist) + sizeof(struct wl_item) * len, GFP_KERNEL);
+
+ if (copy_from_user(tmp, (void __user *)arg, sizeof(struct whitelist) + sizeof(struct wl_item) * len)) {
+ qtfs_err("qtfs ioctl white init copy from user failed.");
+ return QTERROR;
+ }
+
+ if (whitelist[tmp->type] != NULL) {
+ kfree(whitelist[tmp->type]);
+ }
+ whitelist[tmp->type] = tmp;
+ for (i = 0; i < whitelist[tmp->type]->len; i++) {
+ qtfs_err("init %d list:%d %s", tmp->type, i, whitelist[tmp->type]->wl[i].path);
+ }
+ break;
default:
qtfs_err("qtfs misc ioctl unknown cmd:%u.", cmd);
break;
@@ -226,7 +249,11 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a
static int __init qtfs_server_init(void)
{
+ int i;
qtfs_log_init(qtfs_log_level);
+ for (i = 0; i < QTFS_WHITELIST_MAX; i++) {
+ whitelist[i] = NULL;
+ }
qtfs_diag_info = (struct qtinfo *)kmalloc(sizeof(struct qtinfo), GFP_KERNEL);
if (qtfs_diag_info == NULL)
qtfs_err("kmalloc qtfs diag info failed.");
@@ -246,6 +273,7 @@ static int __init qtfs_server_init(void)
static void __exit qtfs_server_exit(void)
{
+ int i;
qtfs_mod_exiting = true;
qtfs_server_thread_run = 0;
@@ -269,6 +297,11 @@ static void __exit qtfs_server_exit(void)
kfree(qtfs_userps);
qtfs_userps = NULL;
}
+ for (i = 0; i < QTFS_WHITELIST_MAX; i++) {
+ if (whitelist[i] != NULL) {
+ kfree(whitelist[i]);
+ }
+ }
qtfs_misc_destroy();
qtfs_info("qtfs server exit done.\n");
return;
diff --git a/qtfs/qtfs_server/qtfs-server.h b/qtfs/qtfs_server/qtfs-server.h
index 8bcadf6..d10742a 100644
--- a/qtfs/qtfs_server/qtfs-server.h
+++ b/qtfs/qtfs_server/qtfs-server.h
@@ -4,6 +4,7 @@
extern int qtfs_server_thread_run;
extern struct qtfs_server_epoll_s qtfs_epoll;
extern int qtfs_mod_exiting;
+extern struct whitelist* whitelist[QTFS_WHITELIST_MAX];
struct qtserver_arg {
char *data;
diff --git a/qtfs/qtfs_server/user_engine.c b/qtfs/qtfs_server/user_engine.c
index a062b63..547935c 100644
--- a/qtfs/qtfs_server/user_engine.c
+++ b/qtfs/qtfs_server/user_engine.c
@@ -9,11 +9,14 @@
#include <string.h>
#include <pthread.h>
#include <signal.h>
+#include <glib.h>
#include <sys/epoll.h>
#include "comm.h"
+char wl_type_str[QTFS_WHITELIST_MAX][10] = {"Open", "Write", "Read", "Readdir", "Mkdir", "Rmdir", "Create", "Unlink", "Rename", "Setattr", "Setxattr", "Mount"};
+
#define engine_out(info, ...) \
do {\
printf("[Engine::%s:%3d]"info"\n", __func__, __LINE__, ##__VA_ARGS__);\
@@ -29,6 +32,10 @@
printf("[ERROR:Engine::%s:%3d]"info"\n", __func__, __LINE__, ##__VA_ARGS__);\
} while (0);
+#define WHITELIST_FILE "/etc/qtfs/whitelist"
+
+struct whitelist *whitelist[QTFS_WHITELIST_MAX];
+
struct engine_arg {
int psize;
int fd;
@@ -171,6 +178,46 @@ int qtfs_epoll_init(int fd)
return epfd;
}
+static int qtfs_whitelist_transfer(int fd, GKeyFile *config, int type)
+{
+ int64_t i, len;
+ char **items = g_key_file_get_string_list(config,wl_type_str[type],"Path",&len,NULL);
+ if (len == 0) {
+ engine_out("Can't find whitelist item %s", wl_type_str[type]);
+ return 0;
+ }
+ whitelist[type] = (struct whitelist *)malloc(sizeof(struct whitelist) + sizeof(struct wl_item) * len);
+ g_print("%s:\n", wl_type_str[type]);
+ whitelist[type]->len = len;
+ whitelist[type]->type = type;
+ for(i = 0; i < len;i++){
+ printf("%s\n", items[i]);
+ whitelist[type]->wl[i].len = strlen(items[i]);
+ strcpy(whitelist[type]->wl[i].path, items[i]);
+ }
+ int ret = ioctl(fd, QTFS_IOCTL_WHITELIST, whitelist[type]);
+ free(items);
+ return ret;
+}
+
+int qtfs_whitelist_init(int fd)
+{
+ int ret, i;
+ GKeyFile *config = g_key_file_new();
+ g_key_file_load_from_file(config, WHITELIST_FILE, G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL);
+ for (i = 0; i < QTFS_WHITELIST_MAX; i++) {
+ ret = qtfs_whitelist_transfer(fd, config, i);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ g_key_file_free(config);
+ for (i = 0; i < QTFS_WHITELIST_MAX; i++) {
+ free(whitelist[i]);
+ }
+ return 0;
+}
+
int main(int argc, char *argv[])
{
if (argc != 3) {
@@ -192,6 +239,9 @@ int main(int argc, char *argv[])
close(fd);
return -1;
}
+ if (qtfs_whitelist_init(fd)) {
+ goto end;
+ }
umask(0);
@@ -212,7 +262,6 @@ int main(int argc, char *argv[])
engine_out("qtfs engine userp init failed.");
goto end;
}
-
struct engine_arg arg[QTFS_MAX_THREADS];
for (int i = 0; i < thread_nums; i++) {
arg[i].psize = psize;
diff --git a/qtfs/req.h b/qtfs/req.h
index 0208667..3bcfa77 100644
--- a/qtfs/req.h
+++ b/qtfs/req.h
@@ -12,29 +12,29 @@ enum qtreq_type {
QTFS_REQ_OPEN,
QTFS_REQ_CLOSE,
QTFS_REQ_READ,
- QTFS_REQ_READITER, //5
+ QTFS_REQ_READITER, // 5
QTFS_REQ_WRITE,
QTFS_REQ_LOOKUP,
QTFS_REQ_READDIR,
QTFS_REQ_MKDIR,
- QTFS_REQ_RMDIR, //10
+ QTFS_REQ_RMDIR, // 10
QTFS_REQ_GETATTR,
QTFS_REQ_SETATTR,
QTFS_REQ_ICREATE,
QTFS_REQ_MKNOD,
- QTFS_REQ_UNLINK, //15
+ QTFS_REQ_UNLINK, // 15
QTFS_REQ_SYMLINK,
QTFS_REQ_LINK,
QTFS_REQ_GETLINK,
QTFS_REQ_READLINK,
- QTFS_REQ_RENAME, //20
+ QTFS_REQ_RENAME, // 20
QTFS_REQ_XATTRLIST,
QTFS_REQ_XATTRGET,
QTFS_REQ_XATTRSET,
QTFS_REQ_SYSMOUNT,
- QTFS_REQ_SYSUMOUNT, //25
+ QTFS_REQ_SYSUMOUNT, // 25
QTFS_REQ_FIFOPOLL,
QTFS_REQ_STATFS,
@@ -117,11 +117,11 @@ static inline void qtfs_nbytes_print(unsigned char *buf, int bytes)
#define QTFS_SEND_SIZE(stru, tailstr) sizeof(stru) - sizeof(tailstr) + strlen(tailstr) + 1
struct qtreq {
- unsigned int type; // operation type
+ unsigned int type; // operation type
unsigned int err;
unsigned long seq_num; // check code
size_t len;
- char data[QTFS_REQ_MAX_LEN]; // operation's private data
+ char data[QTFS_REQ_MAX_LEN]; // operation's private data
};
#define QTFS_MSG_LEN sizeof(struct qtreq)
@@ -169,7 +169,6 @@ struct qtreq_open {
};
struct qtrsp_open {
- __u64 file;
int fd;
int ret;
};
@@ -182,25 +181,10 @@ struct qtrsp_close {
int ret;
};
-struct qtreq_read {
- size_t len;
- long long pos;
- __u64 file;
-};
-
-struct qtrsp_read {
- struct qtrsp_read_len {
- int ret;
- ssize_t len;
- int errno;
- } d;
- char readbuf[QTFS_TAIL_LEN(struct qtrsp_read_len)];
-};
-
struct qtreq_readiter {
size_t len;
long long pos;
- __u64 file;
+ int fd;
};
struct qtrsp_readiter {
@@ -216,7 +200,7 @@ struct qtreq_write {
struct qtreq_write_len {
int buflen;
long long pos;
- __u64 file;
+ int fd;
long long flags;
long long mode;
} d;
@@ -505,7 +489,6 @@ struct qtrsp_sysumount {
struct qtreq_poll {
int fd;
- __u64 file;
int qproc;
};
@@ -516,7 +499,6 @@ struct qtrsp_poll {
struct qtreq_epollctl {
- __u64 file;
int fd;
int op;
struct qtreq_epoll_event event;
diff --git a/usecases/transparent-offload/whitelist/libvirt/qtfs_whitelist b/usecases/transparent-offload/whitelist/libvirt/qtfs_whitelist
new file mode 100644
index 0000000..d6e14ae
--- /dev/null
+++ b/usecases/transparent-offload/whitelist/libvirt/qtfs_whitelist
@@ -0,0 +1,35 @@
+[Open]
+Path=/proc/sys/kernel/sched_autogroup_enabled;/proc/sys/vm;/sys/bus/pci;/sys/devices/pic;/sys/devices/system/node;/sys/kernel/mm;/sys/fs/cgroup;/home/VMs;/sys/fs/cgroup;/var/lib/libvirt/qemu;/sys/devices/system/cpu/online;/sys/module/kvm;/proc;/sys
+
+[Write]
+Path=/proc/sys/kernel/sched_autogroup_enabled;/proc/sys/vm;/sys/bus/pci;/sys/devices/pic;/sys/devices/system/node;/sys/kernel/mm;/sys/fs/cgroup;/home/VMs;/sys/fs/cgroup;/var/lib/libvirt/qemu
+
+[Readiter]
+Path=/sys/module/kvm;/proc;/home/VMs;/sys/kernel/mm/transparent_hugepage;/sys/devices/system/cpu/online;/sys/devices/system/node;/sys/devices;/sys/firmware;/var/lib/libvirt/qemu;/sys/fs/cgroup
+
+[Readdir]
+Path=/proc;/sys/bus;/sys/kernel/iommu_groups;/sys/kernel/mm/hugepages;/sys/class;/sys/bus;/sys/class;/sys/devices/system;/var/lib/libvirt;/sys/fs/cgroup;/root/test;/sys/devices/system/node;/dev/pts;/home/VMs
+
+[Mkdir]
+Path=/var/lib/libvirt/qemu;/home/VMs;/sys/fs/cgroup
+
+[Rmdir]
+Path=/var/lib/libvirt/qemu;/home/VMs;/sys/fs/cgroup
+
+[Create]
+Path=/var/lib/libvirt/qemu;/home/VMs;/sys/fs/cgroup
+
+[Unlink]
+Path=/var/lib/libvirt/qemu;/home/VMs;/sys/fs/cgroup
+
+[Rename]
+Path=/var/lib/libvirt/qemu;/home/VMs;/sys/fs/cgroup
+
+[Setattr]
+Path=/sys/bus/pci/drivers/pcieport/unbind;/sys/bus/pci/drivers_probe;/sys/devices/pci0000:00/0000:00:08.0/driver_override;/root/test;/var/lib/libvirt/qemu;/sys/fs/cgroup;/home/VMs
+
+[Setxattr]
+Path=/sys/bus/pci/drivers/pcieport/unbind;/sys/bus/pci/drivers_probe;/sys/devices/pci0000:00/0000:00:08.0/driver_override;/root/test;/var/lib/libvirt/qemu;/sys/fs/cgroup;/home/VMs
+
+[Mount]
+Path=/home/VMs;/var/lib/libvirt;/proc;/sys;/dev/pts;/dev/vfio
\ No newline at end of file
--
2.33.0