]> git.proxmox.com Git - mirror_libseccomp.git/commitdiff
api: make TSYNC and NOTIFY mutually exclusive
authorPaul Moore <paul@paul-moore.com>
Thu, 2 May 2019 23:29:59 +0000 (19:29 -0400)
committerPaul Moore <paul@paul-moore.com>
Thu, 2 May 2019 23:29:59 +0000 (19:29 -0400)
The kernel explicitly disallows setting both TSYNC and NEW_LISTENER
at the same time, so catch this and block it in libseccomp.

Signed-off-by: Paul Moore <paul@paul-moore.com>
include/seccomp.h.in
src/api.c
src/db.c
src/db.h

index d2fde3af83f24c63dd29526d41fe3aff53a469fa..b29c6954c3c6af07d4c1dd2d983de2ae53abe5a0 100644 (file)
@@ -719,6 +719,7 @@ int seccomp_notify_alloc(struct seccomp_notif **req,
  */
 void seccomp_notify_free(struct seccomp_notif *req,
                         struct seccomp_notif_resp *resp);
+
 /**
  * Receive a notification from a seccomp notification fd.
  * @param fd the notification fd
index e2b6c00bf66e9babdc87c5933c34e2e913caafbf..81f4612a03d04beb56fed86c4dac7fbf82b6c27e 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -190,7 +190,7 @@ API int seccomp_api_set(unsigned int level)
 /* NOTE - function header comment in include/seccomp.h */
 API scmp_filter_ctx seccomp_init(uint32_t def_action)
 {
-       if (db_action_valid(def_action) < 0)
+       if (db_col_action_valid(NULL, def_action) < 0)
                return NULL;
 
        return db_col_init(def_action);
@@ -201,7 +201,8 @@ API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)
 {
        struct db_filter_col *col = (struct db_filter_col *)ctx;
 
-       if (ctx == NULL || db_action_valid(def_action) < 0)
+       /* use a NULL filter collection here since we are resetting it */
+       if (ctx == NULL || db_col_action_valid(NULL, def_action) < 0)
                return -EINVAL;
 
        return db_col_reset(col, def_action);
@@ -441,7 +442,7 @@ API int seccomp_rule_add_array(scmp_filter_ctx ctx,
        if (db_col_valid(col) || _syscall_valid(col, syscall))
                return -EINVAL;
 
-       rc = db_action_valid(action);
+       rc = db_col_action_valid(col, action);
        if (rc < 0)
                return rc;
        if (action == col->attr.act_default)
@@ -490,7 +491,7 @@ API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
        if (db_col_valid(col) || _syscall_valid(col, syscall))
                return -EINVAL;
 
-       rc = db_action_valid(action);
+       rc = db_col_action_valid(col, action);
        if (rc < 0)
                return rc;
        if (action == col->attr.act_default)
index 1b2c549a3785f3dd92da4cc9301d239881df886f..03e1ba376ec1285a5fa7c216b7dfc99d727411da 100644 (file)
--- a/src/db.c
+++ b/src/db.c
@@ -1069,6 +1069,10 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
 
        /* set the state */
        col->state = _DB_STA_VALID;
+       if (def_action == SCMP_ACT_NOTIFY)
+               col->notify_used = true;
+       else
+               col->notify_used = false;
 
        /* reset the initial db */
        db = _db_init(arch_def_native);
@@ -1150,30 +1154,40 @@ void db_col_release(struct db_filter_col *col)
 }
 
 /**
- * Validate the seccomp action
- * @param action the seccomp action
+ * Validate a filter collection
+ * @param col the seccomp filter collection
+ *
+ * This function validates a seccomp filter collection.  Returns zero if the
+ * collection is valid, negative values on failure.
  *
- * Verify that the given action is a valid seccomp action; return zero if
- * valid, -EINVAL if invalid.
  */
-int db_action_valid(uint32_t action)
+int db_col_valid(struct db_filter_col *col)
 {
-       if (sys_chk_seccomp_action(action) == 1)
+       if (col != NULL && col->state == _DB_STA_VALID && col->filter_cnt > 0)
                return 0;
        return -EINVAL;
 }
 
 /**
- * Validate a filter collection
+ * Validate the seccomp action
  * @param col the seccomp filter collection
+ * @param action the seccomp action
  *
- * This function validates a seccomp filter collection.  Returns zero if the
- * collection is valid, negative values on failure.
- *
+ * Verify that the given action is a valid seccomp action; return zero if
+ * valid, -EINVAL if invalid.
  */
-int db_col_valid(struct db_filter_col *col)
+int db_col_action_valid(const struct db_filter_col *col, uint32_t action)
 {
-       if (col != NULL && col->state == _DB_STA_VALID && col->filter_cnt > 0)
+       if (col != NULL) {
+               /* NOTE: in some cases we don't have a filter collection yet,
+                *       but when we do we need to do the following checks */
+
+               /* kernel disallows TSYNC and NOTIFY in one filter */
+               if (col->attr.tsync_enable && action == SCMP_ACT_NOTIFY)
+                       return -EINVAL;
+       }
+
+       if (sys_chk_seccomp_action(action) == 1)
                return 0;
        return -EINVAL;
 }
@@ -1315,7 +1329,7 @@ int db_col_attr_set(struct db_filter_col *col,
                return -EACCES;
                break;
        case SCMP_FLTATR_ACT_BADARCH:
-               if (db_action_valid(value) == 0)
+               if (db_col_action_valid(col, value) == 0)
                        col->attr.act_badarch = value;
                else
                        return -EINVAL;
@@ -1328,6 +1342,9 @@ int db_col_attr_set(struct db_filter_col *col,
                if (rc == 1) {
                        /* supported */
                        rc = 0;
+                       /* kernel disallows TSYNC and NOTIFY in one filter */
+                       if (value && col->notify_used)
+                               return -EINVAL;
                        col->attr.tsync_enable = (value ? 1 : 0);
                } else if (rc == 0)
                        /* unsupported */
@@ -2281,6 +2298,9 @@ add_arch_fail:
                db_col_transaction_abort(col);
 
 add_return:
+       /* update the misc state */
+       if (rc == 0 && action == SCMP_ACT_NOTIFY)
+               col->notify_used = true;
        if (chain != NULL)
                free(chain);
        return rc;
index 7967c479612cb274036e839dc4cd2a7e42d68f8c..c1810387ef6190fe672cee6fc24cbd2deabe88f9 100644 (file)
--- a/src/db.h
+++ b/src/db.h
@@ -156,6 +156,7 @@ struct db_filter_col {
 
        /* notification fd that was returned from seccomp() */
        int notify_fd;
+       bool notify_used;
 };
 
 /**
@@ -170,8 +171,6 @@ struct db_filter_col {
 #define db_list_foreach(iter,list) \
        for (iter = (list); iter != NULL; iter = iter->next)
 
-int db_action_valid(uint32_t action);
-
 struct db_api_rule_list *db_rule_dup(const struct db_api_rule_list *src);
 
 struct db_filter_col *db_col_init(uint32_t def_action);
@@ -180,6 +179,8 @@ void db_col_release(struct db_filter_col *col);
 
 int db_col_valid(struct db_filter_col *col);
 
+int db_col_action_valid(const struct db_filter_col *col, uint32_t action);
+
 int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src);
 
 int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token);