summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2020-06-06 16:36:38 -0400
committerPaul Moore <paul@paul-moore.com>2020-06-16 11:22:29 -0400
commit34bf78abc9567b66c72dbe67e7f243072162a25f (patch)
tree5687b1d38934d4d592f02ce0efb7eca791fa59af /src
parent047a591721631e5da13de7038680ba4000f4365b (diff)
downloadlibseccomp-34bf78abc9567b66c72dbe67e7f243072162a25f.tar.gz
api: add the SCMP_FLTATR_API_SYSRAWRC filter attribute
See the manpage additions as part of this patch, but the basic idea is that when this attribute is non-zero we make every effort to convey the system's errno value back to the caller when something goes wrong in libc or the kernel. It is important to note from a support perspective that our ability to support callers who make use of this attribute will be diminished as the libc and kernel errno values are beyond libseccomp's control. If the attribute is zero, the library hides all of the system failures under -ECANCELED. Acked-by: Tom Hromatka <tom.hromatka@oracle.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src')
-rw-r--r--src/api.c40
-rw-r--r--src/db.c26
-rw-r--r--src/db.h4
-rw-r--r--src/gen_pfc.c6
-rw-r--r--src/python/libseccomp.pxd1
-rw-r--r--src/python/seccomp.pyx6
-rw-r--r--src/system.c5
-rw-r--r--src/system.h2
8 files changed, 79 insertions, 11 deletions
diff --git a/src/api.c b/src/api.c
index e01b196..b4f0c64 100644
--- a/src/api.c
+++ b/src/api.c
@@ -94,6 +94,27 @@ static int _rc_filter(int err)
}
/**
+ * Filter the system error codes we send back to callers
+ * @param col the filter collection
+ * @param err the error code
+ *
+ * This is similar to _rc_filter(), but it first checks the filter attribute
+ * to determine if we should be filtering the return codes.
+ *
+ */
+static int _rc_filter_sys(struct db_filter_col *col, int err)
+{
+ /* pass through success values */
+ if (err >= 0)
+ return err;
+
+ /* pass the return code if the SCMP_FLTATR_API_SYSRAWRC is true */
+ if (db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC))
+ return err;
+ return -ECANCELED;
+}
+
+/**
* Validate a filter context
* @param ctx the filter context
*
@@ -355,12 +376,14 @@ API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token)
API int seccomp_load(const scmp_filter_ctx ctx)
{
struct db_filter_col *col;
+ bool rawrc;
if (_ctx_valid(ctx))
return _rc_filter(-EINVAL);
col = (struct db_filter_col *)ctx;
- return _rc_filter(sys_filter_load(col));
+ rawrc = db_col_attr_read(col, SCMP_FLTATR_API_SYSRAWRC);
+ return _rc_filter(sys_filter_load(col, rawrc));
}
/* NOTE - function header comment in include/seccomp.h */
@@ -638,28 +661,35 @@ API int seccomp_notify_fd(const scmp_filter_ctx ctx)
/* NOTE - function header comment in include/seccomp.h */
API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)
{
+ int rc;
+ struct db_filter_col *col;
+
if (_ctx_valid(ctx))
return _rc_filter(-EINVAL);
+ col = (struct db_filter_col *)ctx;
- return _rc_filter(gen_pfc_generate((struct db_filter_col *)ctx, fd));
+ rc = gen_pfc_generate(col, fd);
+ return _rc_filter_sys(col, rc);
}
/* NOTE - function header comment in include/seccomp.h */
API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
{
int rc;
+ struct db_filter_col *col;
struct bpf_program *program;
if (_ctx_valid(ctx))
return _rc_filter(-EINVAL);
+ col = (struct db_filter_col *)ctx;
- rc = gen_bpf_generate((struct db_filter_col *)ctx, &program);
+ rc = gen_bpf_generate(col, &program);
if (rc < 0)
return _rc_filter(rc);
rc = write(fd, program->blks, BPF_PGM_SIZE(program));
gen_bpf_release(program);
if (rc < 0)
- return _rc_filter(-ECANCELED);
+ return _rc_filter_sys(col, -errno);
- return _rc_filter(0);
+ return 0;
}
diff --git a/src/db.c b/src/db.c
index ebf6ad0..f0e0006 100644
--- a/src/db.c
+++ b/src/db.c
@@ -1071,6 +1071,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
col->attr.log_enable = 0;
col->attr.spec_allow = 0;
col->attr.optimize = 1;
+ col->attr.api_sysrawrc = 0;
/* set the state */
col->state = _DB_STA_VALID;
@@ -1316,6 +1317,9 @@ int db_col_attr_get(const struct db_filter_col *col,
case SCMP_FLTATR_CTL_OPTIMIZE:
*value = col->attr.optimize;
break;
+ case SCMP_FLTATR_API_SYSRAWRC:
+ *value = col->attr.api_sysrawrc;
+ break;
default:
rc = -EINVAL;
break;
@@ -1325,6 +1329,25 @@ int db_col_attr_get(const struct db_filter_col *col,
}
/**
+ * Get a filter attribute
+ * @param col the seccomp filter collection
+ * @param attr the filter attribute
+ *
+ * Returns the requested filter attribute value with zero on any error.
+ * Special care must be given with this function as error conditions can be
+ * hidden from the caller.
+ *
+ */
+uint32_t db_col_attr_read(const struct db_filter_col *col,
+ enum scmp_filter_attr attr)
+{
+ uint32_t value = 0;
+
+ db_col_attr_get(col, attr, &value);
+ return value;
+}
+
+/**
* Set a filter attribute
* @param col the seccomp filter collection
* @param attr the filter attribute
@@ -1402,6 +1425,9 @@ int db_col_attr_set(struct db_filter_col *col,
break;
}
break;
+ case SCMP_FLTATR_API_SYSRAWRC:
+ col->attr.api_sysrawrc = (value ? 1 : 0);
+ break;
default:
rc = -EINVAL;
break;
diff --git a/src/db.h b/src/db.h
index ae485ee..b96b104 100644
--- a/src/db.h
+++ b/src/db.h
@@ -120,6 +120,8 @@ struct db_filter_attr {
uint32_t spec_allow;
/* SCMP_FLTATR_CTL_OPTIMIZE related attributes */
uint32_t optimize;
+ /* return the raw system return codes */
+ uint32_t api_sysrawrc;
};
struct db_filter {
@@ -191,6 +193,8 @@ int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token);
int db_col_attr_get(const struct db_filter_col *col,
enum scmp_filter_attr attr, uint32_t *value);
+uint32_t db_col_attr_read(const struct db_filter_col *col,
+ enum scmp_filter_attr attr);
int db_col_attr_set(struct db_filter_col *col,
enum scmp_filter_attr attr, uint32_t value);
diff --git a/src/gen_pfc.c b/src/gen_pfc.c
index 9d86e06..405f080 100644
--- a/src/gen_pfc.c
+++ b/src/gen_pfc.c
@@ -464,7 +464,7 @@ arch_return:
*
* This function generates a pseudo filter code representation of the given
* filter collection and writes it to the given fd. Returns zero on success,
- * negative values on failure.
+ * negative errno values on failure.
*
*/
int gen_pfc_generate(const struct db_filter_col *col, int fd)
@@ -475,11 +475,11 @@ int gen_pfc_generate(const struct db_filter_col *col, int fd)
newfd = dup(fd);
if (newfd < 0)
- return -ECANCELED;
+ return -errno;
fds = fdopen(newfd, "a");
if (fds == NULL) {
close(newfd);
- return -ECANCELED;
+ return -errno;
}
/* generate the pfc */
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index b970318..0629bf1 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -62,6 +62,7 @@ cdef extern from "seccomp.h":
SCMP_FLTATR_CTL_LOG
SCMP_FLTATR_CTL_SSB
SCMP_FLTATR_CTL_OPTIMIZE
+ SCMP_FLTATR_API_SYSRAWRC
cdef enum scmp_compare:
SCMP_CMP_NE
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index d7c1bb1..13aa669 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -318,6 +318,11 @@ cdef class Attr:
CTL_TSKIP - allow rules with a -1 syscall number
CTL_LOG - log not-allowed actions
CTL_SSB - disable SSB mitigations
+ CTL_OPTIMIZE - the filter's optimization level:
+ 0: currently unused
+ 1: rules weighted by priority and complexity (DEFAULT)
+ 2: binary tree sorted by syscall number
+ API_SYSRAWRC - return the raw syscall codes
"""
ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT
ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH
@@ -327,6 +332,7 @@ cdef class Attr:
CTL_LOG = libseccomp.SCMP_FLTATR_CTL_LOG
CTL_SSB = libseccomp.SCMP_FLTATR_CTL_SSB
CTL_OPTIMIZE = libseccomp.SCMP_FLTATR_CTL_OPTIMIZE
+ API_SYSRAWRC = libseccomp.SCMP_FLTATR_API_SYSRAWRC
cdef class Arg:
""" Python object representing a SyscallFilter syscall argument.
diff --git a/src/system.c b/src/system.c
index 737558e..741a74e 100644
--- a/src/system.c
+++ b/src/system.c
@@ -291,6 +291,7 @@ void sys_set_seccomp_flag(int flag, bool enable)
/**
* Loads the filter into the kernel
* @param col the filter collection
+ * @param rawrc pass the raw return code if true
*
* This function loads the given seccomp filter context into the kernel. If
* the filter was loaded correctly, the kernel will be enforcing the filter
@@ -298,7 +299,7 @@ void sys_set_seccomp_flag(int flag, bool enable)
* error.
*
*/
-int sys_filter_load(struct db_filter_col *col)
+int sys_filter_load(struct db_filter_col *col, bool rawrc)
{
int rc;
struct bpf_program *prgm = NULL;
@@ -343,7 +344,7 @@ filter_load_out:
if (rc == -ESRCH)
return -ESRCH;
if (rc < 0)
- return -ECANCELED;
+ return (rawrc ? -errno : -ECANCELED);
return rc;
}
diff --git a/src/system.h b/src/system.h
index d183b5e..7517c71 100644
--- a/src/system.h
+++ b/src/system.h
@@ -188,7 +188,7 @@ void sys_set_seccomp_action(uint32_t action, bool enable);
int sys_chk_seccomp_flag(int flag);
void sys_set_seccomp_flag(int flag, bool enable);
-int sys_filter_load(struct db_filter_col *col);
+int sys_filter_load(struct db_filter_col *col, bool rawrc);
int sys_notify_alloc(struct seccomp_notif **req,
struct seccomp_notif_resp **resp);