From 59f7f7c241253293c25e001c9340f1deeb138311 Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Fri, 1 Sep 2023 10:16:36 +0200 Subject: cooker, seitan: add sched_setscheduler The sched_setscheduler requires to set the pid of the process we want to change the priority, this adds a new metadata for getting the target pid at runtime. Add a couple of syscalls for the scheduler in the string parsing. Signed-off-by: Alice Frosi --- common/gluten.h | 3 ++- common/util.c | 34 ++++++++++++++++++++++------------ cooker/Makefile | 2 ++ cooker/call.c | 19 ++++++++++++++----- cooker/calls.c | 3 ++- cooker/calls/scheduler.c | 41 +++++++++++++++++++++++++++++++++++++++++ cooker/calls/scheduler.h | 12 ++++++++++++ demo/scheduler.hjson | 24 ++++++++++++++++++++++++ operations.c | 3 +++ 9 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 cooker/calls/scheduler.c create mode 100644 cooker/calls/scheduler.h create mode 100644 demo/scheduler.hjson diff --git a/common/gluten.h b/common/gluten.h index 6414e20..1f06221 100644 --- a/common/gluten.h +++ b/common/gluten.h @@ -147,7 +147,8 @@ BUILD_BUG_ON(BITS_PER_NUM(CONTEXT_TYPE_MAX) + \ enum metadata_type { UID_TARGET = 0, GID_TARGET = 1, - METADATA_MAX = GID_TARGET, + PID_TARGET = 2, + METADATA_MAX = PID_TARGET, }; extern const char *metadata_type_str[METADATA_MAX + 1]; diff --git a/common/util.c b/common/util.c index 8815ecb..3e81a1c 100644 --- a/common/util.c +++ b/common/util.c @@ -55,17 +55,27 @@ const char *cmp_type_str[CMP_MAX + 1] = { "EQ", "NE", "GT", "GE", "LT", "LE", }; -const char *metadata_type_str[METADATA_MAX + 1] = { "uid", "gid" }; +const char *metadata_type_str[METADATA_MAX + 1] = { "uid", "gid", "pid" }; const char *syscall_name_str[N_SYSCALL + 1] = { - [__NR_chown] = "chown", - [__NR_connect] = "connect", - [__NR_ioctl] = "ioctl", - [__NR_lchown] = "lchown", - [__NR_mknod] = "mknod", - [__NR_mknodat] = "mknodat", - [__NR_read] = "read", - [__NR_socket] = "socket", - [__NR_unshare] = "unshare", - [__NR_open] = "open", - + [__NR_chown] = "chown", + [__NR_connect] = "connect", + [__NR_ioctl] = "ioctl", + [__NR_lchown] = "lchown", + [__NR_mknod] = "mknod", + [__NR_mknodat] = "mknodat", + [__NR_open] = "open", + [__NR_read] = "read", + [__NR_sched_get_priority_max] = "sched_get_priority_max", + [__NR_sched_get_priority_min] = "sched_get_priority_min", + [__NR_sched_getaffinity] = "sched_getaffinity", + [__NR_sched_getattr] = "sched_getattr", + [__NR_sched_getparam] = "sched_getparam", + [__NR_sched_getscheduler] = "sched_getscheduler", + [__NR_sched_setaffinity] = "sched_setaffinity", + [__NR_sched_setattr] = "sched_setattr", + [__NR_sched_setparam] = "sched_setparam", + [__NR_sched_setscheduler] = "sched_setscheduler", + [__NR_sched_yield] = "sched_yield", + [__NR_socket] = "socket", + [__NR_unshare] = "unshare", }; diff --git a/cooker/Makefile b/cooker/Makefile index 8cf8691..12b9c1d 100644 --- a/cooker/Makefile +++ b/cooker/Makefile @@ -33,11 +33,13 @@ SRCS := call.c calls.c emit.c gluten.c filter.c main.c match.c \ parse.c parson.c \ $(COMMON)/util.c \ calls/net.c calls/ioctl.c calls/process.c calls/fs.c calls/io.c \ + calls/scheduler.c \ seccomp_profile.c HEADERS := call.h calls.h cooker.h emit.h filter.h gluten.h match.h \ parse.h parson.h \ $(COMMON)/gluten.h $(COMMON)/util.h \ calls/net.h calls/ioctl.h calls/process.h calls/fs.h calls/io.h \ + calls/scheduler.h \ seccomp_profile.h $(BIN): $(SRCS) $(HEADERS) diff --git a/cooker/call.c b/cooker/call.c index 173bdb4..a09194a 100644 --- a/cooker/call.c +++ b/cooker/call.c @@ -16,6 +16,15 @@ #include "parse.h" #include "util.h" +static bool is_metadata_obj(JSON_Object *metadata) +{ + if (!metadata) + return false; + return ((!json_object_get_string(metadata, "caller")) || + (!json_object_get_string(metadata, "set")) || + (!json_object_get_string(metadata, "get"))); +} + /* TODO: refactor and simplify this horrible function */ static union value parse_metadata(struct gluten_ctx *g, struct field *f, struct gluten_offset **base_offset, @@ -29,10 +38,12 @@ static union value parse_metadata(struct gluten_ctx *g, struct field *f, if ((tag = json_object_get_string(metadata, "caller"))) { debug(" args reference value at runtime '%s' with metadata %s", tag, tag); (*base_offset)->type = OFFSET_METADATA; - if (strcmp(tag, "uid") == 0) { + if (!strcmp(tag, "uid")) { (*base_offset)->offset = UID_TARGET; - } else if (strcmp(tag, "gid") == 0) { + } else if (!strcmp(tag, "gid")) { (*base_offset)->offset = GID_TARGET; + } else if (!strcmp(tag, "pid")) { + (*base_offset)->offset = PID_TARGET; } else { die(" unrecognized metadata tag: %s", tag); } @@ -151,9 +162,7 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args, if (offset.type != OFFSET_NULL) offset.offset += f->offset; - - if (json_value_get_type(jvalue) == JSONObject && - (tmp1 = json_value_get_object(jvalue))) + if (!(tmp1 = json_value_get_object(jvalue)) && is_metadata_obj(tmp1)) v = parse_metadata(g, f, &base_offset, offset, tmp1, dry_run, add); if (v.v_num == 0) diff --git a/cooker/calls.c b/cooker/calls.c index f486777..f4e7d49 100644 --- a/cooker/calls.c +++ b/cooker/calls.c @@ -16,9 +16,10 @@ #include "calls/process.h" #include "calls/fs.h" #include "calls/io.h" +#include "calls/scheduler.h" struct call *call_sets[] = { syscalls_net, syscalls_ioctl, syscalls_process, syscalls_fs, - syscalls_io, + syscalls_io, syscalls_scheduler, NULL, }; diff --git a/cooker/calls/scheduler.c b/cooker/calls/scheduler.c new file mode 100644 index 0000000..436d3c2 --- /dev/null +++ b/cooker/calls/scheduler.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Red Hat GmbH + * Author: Alice Frosi + */ +#define _GNU_SOURCE +#include +#include + +#include "../cooker.h" +#include "../calls.h" + +static struct num sched_policy[] = { + { "SCHED_OTHER", SCHED_OTHER }, + { "SCHED_BATCH", SCHED_BATCH }, + { "SCHED_IDLE", SCHED_IDLE }, + { "SCHED_FIFO", SCHED_FIFO }, + { "SCHED_RR", SCHED_RR }, + { "SCHED_RESET_ON_FORK", SCHED_RESET_ON_FORK }, /* ORed in policy */ + { 0 }, +}; + +static struct field sched_param[] = { + { "sched_priority", + INT, + 0, + offsetof(struct sched_param, sched_priority), + sizeof(int), + { 0 } }, + { 0 }, +}; + +static struct arg sched_setscheduler_args[] = { + { 0, { "pid", PID, 0, 0, 0, { 0 } } }, + { 1, { "policy", INT, FLAGS, 0, 0, { .d_num = sched_policy } } }, + { 2, { "param", STRUCT, 0, 0, 0, { .d_struct = sched_param } } } +}; + +struct call syscalls_scheduler[] = { + { __NR_sched_setscheduler, "sched_setscheduler", sched_setscheduler_args }, + { 0 }, +}; diff --git a/cooker/calls/scheduler.h b/cooker/calls/scheduler.h new file mode 100644 index 0000000..751d65b --- /dev/null +++ b/cooker/calls/scheduler.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Red Hat GmbH + * Author: Alice Frosi + */ + +#ifndef CALLS_SCHEDULER_H +#define CALLS_SCHEDULER_H + +extern struct call syscalls_scheduler[]; + +#endif /* CALLS_IO_H */ + diff --git a/demo/scheduler.hjson b/demo/scheduler.hjson new file mode 100644 index 0000000..29c7d31 --- /dev/null +++ b/demo/scheduler.hjson @@ -0,0 +1,24 @@ +[ + { + "match": [ + { + "sched_setscheduler": { + "policy": "SCHED_FIFO", + "param": { "priority": 1 } + } + } + ], + "call": [ + { + "sched_setscheduler": { + "pid": { "caller": "pid" }, + "policy": "SCHED_FIFO", + "param": { "priority": 1 } + } + } + ], + "return": { + "value": 0 + } + } +] diff --git a/operations.c b/operations.c index 0121023..cfb3a9c 100644 --- a/operations.c +++ b/operations.c @@ -130,6 +130,9 @@ static int get_metadata_value(uint32_t offset, pid_t pid) case GID_TARGET: return proc_state("Gid", pid); break; + case PID_TARGET: + return pid; + break; default: err("unrecognize metadata type"); } -- cgit v1.2.3