From 685a5109cdc22f213f793b282efff74a171f3a97 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 7 Feb 2019 07:42:39 -0700 Subject: [PATCH] api: implement user notification in libseccomp Kernel 5.0 includes the new user notification return code. Here's all the infrastructure to handle that. The idea behind the user notification return code is that the filter stops the syscall, and forwards it to a "listener fd" that is created when installing a filter. Then then some userspace task can listen and process events accordingly by taking some (or no) action in userspace, and then returning a value from the command. Signed-off-by: Tycho Andersen Signed-off-by: Tom Hromatka --- doc/man/man3/seccomp_api_get.3 | 4 + doc/man/man3/seccomp_attr_set.3 | 6 ++ include/seccomp.h.in | 108 ++++++++++++++++++++++++++ src/api.c | 66 ++++++++++++++++ src/db.c | 14 ++++ src/db.h | 5 ++ src/python/libseccomp.pxd | 3 +- src/system.c | 90 ++++++++++++++++++++- src/system.h | 8 +- tests/.gitignore | 1 + tests/13-basic-attrs.c | 16 +++- tests/50-live-user_notification.c | 84 ++++++++++++++++++++ tests/50-live-user_notification.tests | 11 +++ tests/Makefile.am | 6 +- tests/regression | 5 ++ 15 files changed, 421 insertions(+), 6 deletions(-) create mode 100644 tests/50-live-user_notification.c create mode 100644 tests/50-live-user_notification.tests diff --git a/doc/man/man3/seccomp_api_get.3 b/doc/man/man3/seccomp_api_get.3 index ac3c2ff8..c2fba8c1 100644 --- a/doc/man/man3/seccomp_api_get.3 +++ b/doc/man/man3/seccomp_api_get.3 @@ -53,6 +53,10 @@ The SCMP_FLTATR_CTL_LOG filter attribute and the SCMP_ACT_LOG action are support .TP .B 4 The SCMP_FLTATR_SPEC_ALLOW filter attribute is supported. +.TP +.B 5 +The SCMP_FLTATR_NEW_LISTENER filter attribute and the SCMP_ACT_NEW_LISTENER +action are is supported. .\" ////////////////////////////////////////////////////////////////////////// .SH RETURN VALUE .\" ////////////////////////////////////////////////////////////////////////// diff --git a/doc/man/man3/seccomp_attr_set.3 b/doc/man/man3/seccomp_attr_set.3 index 11320043..473c91ab 100644 --- a/doc/man/man3/seccomp_attr_set.3 +++ b/doc/man/man3/seccomp_attr_set.3 @@ -100,6 +100,12 @@ A flag to disable Speculative Store Bypass mitigations for this filter. Defaults to off ( .I value == 0). +.TP +.B SCMP_FLTATR_NEW_LISTENER +Generate a userspace listener file descriptor when this filter is installed. +Defaults to off ( +.I value +== 0). .\" ////////////////////////////////////////////////////////////////////////// .SH RETURN VALUE .\" ////////////////////////////////////////////////////////////////////////// diff --git a/include/seccomp.h.in b/include/seccomp.h.in index eaa56740..df3b2a5b 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -66,6 +67,7 @@ enum scmp_filter_attr { SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */ SCMP_FLTATR_CTL_LOG = 6, /**< log not-allowed actions */ SCMP_FLTATR_SPEC_ALLOW = 7, /**< disable SSB mitigation */ + SCMP_FLTATR_NEW_LISTENER = 8, /**< returns a listener fd */ _SCMP_FLTATR_MAX, }; @@ -319,6 +321,10 @@ struct scmp_arg_cmp { * Throw a SIGSYS signal */ #define SCMP_ACT_TRAP 0x00030000U +/** + * Notifies userspace + */ +#define SCMP_ACT_USER_NOTIF 0x7fc00000U /** * Return the specified error code */ @@ -336,6 +342,46 @@ struct scmp_arg_cmp { */ #define SCMP_ACT_ALLOW 0x7fff0000U +/* + * User notification bits. It's a little unfortunate that we don't export + * system.h, so we end up having to define all these structures again. + * SECCOMP_RET_USER_NOTIF was added in kernel 5.0. + */ +#ifndef SECCOMP_RET_USER_NOTIF +#define SECCOMP_RET_USER_NOTIF 0x7fc00000U + +struct seccomp_notif_sizes { + __u16 seccomp_notif; + __u16 seccomp_notif_resp; + __u16 seccomp_data; +}; + +struct seccomp_notif { + __u64 id; + __u32 pid; + __u32 flags; + struct seccomp_data data; +}; + +struct seccomp_notif_resp { + __u64 id; + __s64 val; + __s32 error; + __u32 flags; +}; +#define SECCOMP_IOC_MAGIC '!' +#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) +#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) + +/* Flags for seccomp notification fd ioctl. */ +#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) +#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ + struct seccomp_notif_resp) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64) +#endif + /* * functions */ @@ -369,6 +415,7 @@ const struct scmp_version *seccomp_version(void); * support for the SCMP_ACT_LOG action * support for the SCMP_ACT_KILL_PROCESS action * 4 : support for the SCMP_FLTATR_SPEC_ALLOW filter attrbute + * 5 : support for the SCMP_FLTATR_NEW_LISTENER filter attribute * */ unsigned int seccomp_api_get(void); @@ -695,6 +742,67 @@ int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd); */ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd); +/** + * Allocate a pair of notification request/response structures. + * @param req the request location + * @param resp the response location + * + * This function allocates a pair of request/response structure by computing + * the correct sized based on the currently running kernel. It returns zero on + * success, and negative values on failure. + */ +int seccomp_notif_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp); + +/** + * Free a pair of notification request/response structures. + * @param req the request location + * @param resp the response location + */ +void seccomp_notif_free(struct seccomp_notif *req, + struct seccomp_notif_resp *resp); +/** + * Receive a notification from a seccomp notification fd. + * @param fd the notification fd + * @param req the request buffer to save into + * + * Blocks waiting for a notification on this fd. This function is thread safe + * (synchronization is performed in the kernel). Returns zero on success, + * negative values on error. + */ +int seccomp_notif_receive(int fd, struct seccomp_notif *req); + +/** + * Send a notification response to a seccomp notification fd. + * @param fd the notification fd + * @param resp the response buffer to use + * + * Sends a notification response on this fd. This function is thread safe + * (synchronization is performed in the kernel). Returns zero on success, + * negative values on error. + */ +int seccomp_notif_send_resp(int fd, struct seccomp_notif_resp *resp); + +/** + * Check if a notification id is still valid. + * @param fd the notification fd + * @param id the id to test + * + * Checks to see if a notification id is still valid. Returns 0 on success, and + * negative values on failure. + */ +int seccomp_notif_id_valid(int fd, uint64_t id); + +/** + * Return the notification fd from a filter that has already been loaded. + * @param ctx the filter context + * + * This returns the listener fd that was generated when the seccomp policy was + * loaded. This is only valid after seccomp_load() with + * SCMP_FLTATR_NEW_LISTENER set. + */ +int seccomp_notif_get_fd(const scmp_filter_ctx ctx); + /* * pseudo syscall definitions */ diff --git a/src/api.c b/src/api.c index 34fd9c71..ff96e6fb 100644 --- a/src/api.c +++ b/src/api.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -34,6 +35,7 @@ #include "db.h" #include "gen_pfc.h" #include "gen_bpf.h" +#include "helper.h" #include "system.h" #define API __attribute__((visibility("default"))) @@ -112,6 +114,10 @@ static unsigned int _seccomp_api_update(void) sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 1) level = 4; + if (level == 4 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER) == 1) + level = 5; + /* update the stored api level and return */ seccomp_api_level = level; return seccomp_api_level; @@ -163,6 +169,16 @@ API int seccomp_api_set(unsigned int level) sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); break; + case 5: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true); + sys_set_seccomp_action(SCMP_ACT_USER_NOTIF, true); + break; default: return -EINVAL; } @@ -538,3 +554,53 @@ API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd) return 0; } + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notif_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp) +{ + return sys_notif_alloc(req, resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API void seccomp_notif_free(struct seccomp_notif *req, + struct seccomp_notif_resp *resp) +{ + if (req) + free(req); + if (resp) + free(resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notif_receive(int fd, struct seccomp_notif *req) +{ + return sys_notif_receive(fd, req); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notif_send_resp(int fd, struct seccomp_notif_resp *resp) +{ + return sys_notif_send_resp(fd, resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notif_id_valid(int fd, uint64_t id) +{ + return sys_notif_id_valid(fd, id); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notif_get_fd(const scmp_filter_ctx ctx) +{ + struct db_filter_col *col; + + if (_ctx_valid(ctx)) + return -EINVAL; + col = (struct db_filter_col *)ctx; + + if (!col->attr.new_listener) + return -EINVAL; + + return col->notif_fd; +} diff --git a/src/db.c b/src/db.c index 064f343a..752fc6dd 100644 --- a/src/db.c +++ b/src/db.c @@ -1283,6 +1283,9 @@ int db_col_attr_get(const struct db_filter_col *col, case SCMP_FLTATR_SPEC_ALLOW: *value = col->attr.spec_allow; break; + case SCMP_FLTATR_NEW_LISTENER: + *value = col->attr.new_listener; + break; default: rc = -EEXIST; break; @@ -1355,6 +1358,17 @@ int db_col_attr_set(struct db_filter_col *col, rc = -EOPNOTSUPP; } break; + case SCMP_FLTATR_NEW_LISTENER: + rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER); + if (rc == 1) { + /* supported */ + rc = 0; + col->attr.new_listener = (value ? 1 : 0); + } else if (rc == 0) { + /* unsupported */ + rc = -EOPNOTSUPP; + } + break; default: rc = -EEXIST; break; diff --git a/src/db.h b/src/db.h index fa9c0850..d7386178 100644 --- a/src/db.h +++ b/src/db.h @@ -118,6 +118,8 @@ struct db_filter_attr { uint32_t log_enable; /* SPEC_ALLOW related attributes */ uint32_t spec_allow; + /* SECCOMP_FILTER_FLAG_NEW_LISTENER attributes */ + uint32_t new_listener; }; struct db_filter { @@ -153,6 +155,9 @@ struct db_filter_col { /* transaction snapshots */ struct db_filter_snap *snapshots; + + /* notification fd that was returned from seccomp() */ + int notif_fd; }; /** diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index 1293208a..43cd246c 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -59,6 +59,7 @@ cdef extern from "seccomp.h": SCMP_FLTATR_API_TSKIP SCMP_FLTATR_CTL_LOG SCMP_FLTATR_SPEC_ALLOW + SCMP_FITATR_NEW_LISTENER cdef enum scmp_compare: SCMP_CMP_NE @@ -75,6 +76,7 @@ cdef extern from "seccomp.h": SCMP_ACT_TRAP SCMP_ACT_LOG SCMP_ACT_ALLOW + SCMP_ACT_USER_NOTIF unsigned int SCMP_ACT_ERRNO(int errno) unsigned int SCMP_ACT_TRACE(int value) @@ -132,6 +134,5 @@ cdef extern from "seccomp.h": int seccomp_export_pfc(scmp_filter_ctx ctx, int fd) int seccomp_export_bpf(scmp_filter_ctx ctx, int fd) - # kate: syntax python; # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/src/system.c b/src/system.c index f45379c1..a90ef358 100644 --- a/src/system.c +++ b/src/system.c @@ -32,6 +32,7 @@ #include "db.h" #include "gen_bpf.h" #include "system.h" +#include "helper.h" /* NOTE: the seccomp syscall whitelist is currently disabled for testing * purposes, but unless we can verify all of the supported ABIs before @@ -45,6 +46,8 @@ static int _support_seccomp_flag_log = -1; static int _support_seccomp_action_log = -1; static int _support_seccomp_kill_process = -1; static int _support_seccomp_flag_spec_allow = -1; +static int _support_seccomp_flag_new_listener = -1; +static int _support_seccomp_action_user_notif = -1; /** * Check to see if the seccomp() syscall is supported @@ -158,6 +161,17 @@ int sys_chk_seccomp_action(uint32_t action) return _support_seccomp_action_log; } else if (action == SCMP_ACT_ALLOW) { return 1; + } else if (action == SCMP_ACT_USER_NOTIF) { + if (_support_seccomp_action_user_notif < 0) { + struct seccomp_notif_sizes sizes; + if (sys_chk_seccomp_syscall() == 1 && + syscall(_nr_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, + &sizes) == 0) + _support_seccomp_action_user_notif = 1; + else + _support_seccomp_action_user_notif = 0; + } + return 1; } return 0; @@ -227,6 +241,11 @@ int sys_chk_seccomp_flag(int flag) _support_seccomp_flag_spec_allow = _sys_chk_seccomp_flag_kernel(flag); return _support_seccomp_flag_spec_allow; + case SECCOMP_FILTER_FLAG_NEW_LISTENER: + if (_support_seccomp_flag_new_listener < 0) + _support_seccomp_flag_new_listener = _sys_chk_seccomp_flag_kernel(flag); + + return _support_seccomp_flag_new_listener; } return -EOPNOTSUPP; @@ -253,6 +272,9 @@ void sys_set_seccomp_flag(int flag, bool enable) case SECCOMP_FILTER_FLAG_SPEC_ALLOW: _support_seccomp_flag_spec_allow = (enable ? 1 : 0); break; + case SECCOMP_FILTER_FLAG_NEW_LISTENER: + _support_seccomp_flag_new_listener = (enable ? 1 : 0); + break; } } @@ -266,7 +288,7 @@ void sys_set_seccomp_flag(int flag, bool enable) * error. * */ -int sys_filter_load(const struct db_filter_col *col) +int sys_filter_load(struct db_filter_col *col) { int rc; struct bpf_program *prgm = NULL; @@ -291,10 +313,17 @@ int sys_filter_load(const struct db_filter_col *col) flgs |= SECCOMP_FILTER_FLAG_LOG; if (col->attr.spec_allow) flgs |= SECCOMP_FILTER_FLAG_SPEC_ALLOW; + if (col->attr.new_listener) + flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER; rc = syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flgs, prgm); if (rc > 0 && col->attr.tsync_enable) /* always return -ESRCH if we fail to sync threads */ errno = ESRCH; + if (rc > 0 && col->attr.new_listener) { + /* return 0 on NEW_LISTENER success, but save the fd */ + col->notif_fd = rc; + rc = 0; + } } else rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prgm); @@ -303,5 +332,64 @@ int sys_filter_load(const struct db_filter_col *col) gen_bpf_release(prgm); if (rc < 0) return -errno; + return rc; +} + +int sys_notif_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp) +{ + static struct seccomp_notif_sizes sizes = {}; + + if (_support_seccomp_syscall <= 0) + return -EOPNOTSUPP; + + if (sizes.seccomp_notif == 0) { + int ret = syscall(__NR_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, &sizes); + if (ret < 0) + return errno; + } else { + return -1; + } + + *req = zmalloc(sizes.seccomp_notif); + if (!*req) + return -ENOMEM; + + *resp = zmalloc(sizes.seccomp_notif_resp); + if (!*resp) { + free(req); + return -ENOMEM; + } + + return 0; +} + +int sys_notif_receive(int fd, struct seccomp_notif *req) +{ + if (_support_seccomp_action_user_notif <= 0) + return -EOPNOTSUPP; + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0) + return errno; + return 0; +} + +int sys_notif_send_resp(int fd, struct seccomp_notif_resp *resp) +{ + if (_support_seccomp_action_user_notif <= 0) + return -EOPNOTSUPP; + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) + return errno; + return 0; +} + +int sys_notif_id_valid(int fd, uint64_t id) +{ + if (_support_seccomp_action_user_notif <= 0) + return -EOPNOTSUPP; + + if (ioctl(fd, SECCOMP_IOCTL_NOTIF_ID_VALID, id) < 0) + return errno; return 0; } diff --git a/src/system.h b/src/system.h index 875cf0f3..0071ab91 100644 --- a/src/system.h +++ b/src/system.h @@ -24,6 +24,7 @@ #include #include +#include #include "configure.h" @@ -226,6 +227,11 @@ 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(const struct db_filter_col *col); +int sys_filter_load(struct db_filter_col *col); +int sys_notif_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp); +int sys_notif_receive(int fd, struct seccomp_notif *req); +int sys_notif_send_resp(int fd, struct seccomp_notif_resp *resp); +int sys_notif_id_valid(int fd, uint64_t id); #endif diff --git a/tests/.gitignore b/tests/.gitignore index 6d150433..7b5e02df 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -55,3 +55,4 @@ util.pyc 47-live-kill_process 48-sim-32b_args 49-sim-64b_comparisons +50-live-user_notification diff --git a/tests/13-basic-attrs.c b/tests/13-basic-attrs.c index 6985ec9f..0c1af22c 100644 --- a/tests/13-basic-attrs.c +++ b/tests/13-basic-attrs.c @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) uint32_t val = (uint32_t)(-1); scmp_filter_ctx ctx = NULL; - rc = seccomp_api_set(4); + rc = seccomp_api_set(5); if (rc != 0) return EOPNOTSUPP; @@ -123,6 +123,20 @@ int main(int argc, char *argv[]) goto out; } + expected = 1; + rc = seccomp_attr_set(ctx, SCMP_FLTATR_NEW_LISTENER, expected); + if (rc == -EOPNOTSUPP) + expected = 0; + else if (rc != 0) + goto out; + rc = seccomp_attr_get(ctx, SCMP_FLTATR_NEW_LISTENER, &val); + if (rc != 0) + goto out; + if (val != expected) { + rc = -1; + goto out; + } + rc = 0; out: seccomp_release(ctx); diff --git a/tests/50-live-user_notification.c b/tests/50-live-user_notification.c new file mode 100644 index 00000000..b6f3d761 --- /dev/null +++ b/tests/50-live-user_notification.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int rc, fd = -1, status; + struct seccomp_notif *req = NULL; + struct seccomp_notif_resp *resp = NULL; + scmp_filter_ctx ctx = NULL; + pid_t pid = 0; + + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) + return ENOMEM; + + rc = seccomp_attr_set(ctx, SCMP_FLTATR_NEW_LISTENER, 1); + if (rc) + goto out; + + rc = seccomp_rule_add_exact(ctx, SCMP_ACT_USER_NOTIF, SCMP_SYS(getpid), 0, NULL); + if (rc) + goto out; + + rc = seccomp_load(ctx); + if (rc < 0) + goto out; + + rc = fd = seccomp_notif_get_fd(ctx); + if (fd < 0) + goto out; + +#define MAGIC 0x1122334455667788UL + pid = fork(); + if (pid == 0) + exit(syscall(SCMP_SYS(getpid)) != MAGIC); + + rc = seccomp_notif_alloc(&req, &resp); + if (rc) + goto out; + + rc = seccomp_notif_receive(fd, req); + if (rc) + goto out; + + if (req->data.nr != SCMP_SYS(getpid)) { + rc = -EINVAL; + goto out; + } + + resp->id = req->id; + resp->val = MAGIC; + resp->error = 0; + + rc = seccomp_notif_send_resp(fd, resp); + if (rc) + goto out; + + rc = -EINVAL; + if (waitpid(pid, &status, 0) != pid) + goto out; + + if (!WIFEXITED(status)) + goto out; + + if (WEXITSTATUS(status)) + goto out; + + rc = 165; +out: + if (req) + seccomp_notif_free(req, resp); + if (pid) + kill(pid, SIGKILL); + seccomp_release(ctx); + if (fd >= 0) + close(fd); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/50-live-user_notification.tests b/tests/50-live-user_notification.tests new file mode 100644 index 00000000..c67f033a --- /dev/null +++ b/tests/50-live-user_notification.tests @@ -0,0 +1,11 @@ +# +# libseccomp regression test automation data +# +# Copyright Cisco Systems 2019 +# Author: Tycho Andersen +# + +test type: live + +# Testname API Result +50-live-user_notification 5 USER_NOTIF diff --git a/tests/Makefile.am b/tests/Makefile.am index c89fe74a..859dc79f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -88,7 +88,8 @@ check_PROGRAMS = \ 46-sim-kill_process \ 47-live-kill_process \ 48-sim-32b_args \ - 49-sim-64b_comparisons + 49-sim-64b_comparisons \ + 50-live-user_notification EXTRA_DIST_TESTPYTHON = \ util.py \ @@ -190,7 +191,8 @@ EXTRA_DIST_TESTCFGS = \ 46-sim-kill_process.tests \ 47-live-kill_process.tests \ 48-sim-32b_args.tests \ - 49-sim-64b_comparisons.tests + 49-sim-64b_comparisons.tests \ + 50-live-user_notification.tests EXTRA_DIST_TESTSCRIPTS = \ 38-basic-pfc_coverage.sh 38-basic-pfc_coverage.pfc diff --git a/tests/regression b/tests/regression index ec487d17..79892da0 100755 --- a/tests/regression +++ b/tests/regression @@ -784,6 +784,7 @@ function run_test_live() { rc_trace=162 rc_errno=163 rc_log=164 + rc_user_notif=165 ;; mips|mipsel|mips64|mips64n32|mipsel64|mipsel64n32) rc_kill_process=140 @@ -793,6 +794,7 @@ function run_test_live() { rc_trace=162 rc_errno=163 rc_log=164 + rc_user_notif=165 ;; *) print_result $testnumstr "ERROR" "arch $arch not supported" @@ -823,6 +825,9 @@ function run_test_live() { elif [[ $line_act == "LOG" && $rc -eq $rc_log ]]; then print_result $1 "SUCCESS" "" stats_success=$(($stats_success+1)) + elif [[ $line_act == "USER_NOTIF" && $rc -eq $rc_user_notif ]]; then + print_result $1 "SUCCESS" "" + stats_success=$(($stats_success+1)) else print_result $1 "FAILURE" "$line_test rc=$rc" stats_failure=$(($stats_failure+1))