Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,9 @@ API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)
API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
{
int rc;
ssize_t n;
size_t len;
const char *buf;
struct db_filter_col *col;
struct bpf_program *program;

Expand All @@ -766,9 +769,22 @@ API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
if (rc < 0)
return _rc_filter(rc);
program = col->prgm_bpf;
rc = write(fd, program->blks, BPF_PGM_SIZE(program));
if (rc < 0)
return _rc_filter_sys(col, -errno);

/* handle short writes and EINTR */
buf = (const char *)program->blks;
len = BPF_PGM_SIZE(program);
while (len > 0) {
n = write(fd, buf, len);
if (n < 0) {
if (errno == EINTR)
continue;
return _rc_filter_sys(col, -errno);
}
if (n == 0)
return _rc_filter_sys(col, -EIO);
buf += n;
len -= n;
}

return 0;
}
Expand Down
27 changes: 27 additions & 0 deletions tests/11-basic-basic_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
* along with this library; if not, see <http://www.gnu.org/licenses>.
*/

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <seccomp.h>
Expand All @@ -32,6 +34,8 @@ int main(int argc, char *argv[])
unsigned int api;
struct seccomp_notif *req = NULL;
struct seccomp_notif_resp *resp = NULL;
int pipefd[2];
int i;

/* get the api level */
api = seccomp_api_get();
Expand Down Expand Up @@ -179,6 +183,29 @@ int main(int argc, char *argv[])
seccomp_release(ctx);
ctx = NULL;

/* seccomp_export_bpf short write */
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL)
return -1;
for (i = 0; i < 1024; i++) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(1), SCMP_SYS(write), 1,
SCMP_A0(SCMP_CMP_EQ, i));
if (rc != 0)
return -1;
}
if (pipe2(pipefd, O_NONBLOCK) < 0)
return -1;
/* a pipe smaller than the filter only takes a part of it */
if (fcntl(pipefd[1], F_SETPIPE_SZ, getpagesize()) < 0)
return -1;
rc = seccomp_export_bpf(ctx, pipefd[1]);
if (rc != -ECANCELED)
return -1;
close(pipefd[0]);
close(pipefd[1]);
seccomp_release(ctx);
ctx = NULL;

/* seccomp_export_bpf_mem errors */
char buf[1024];
size_t buf_len = sizeof(buf);
Expand Down
Loading