Skip to content

Commit

Permalink
tools: add deny_sched_setattr
Browse files Browse the repository at this point in the history
A tool to test if inside QM it's possible to use the
deny_sched_setattr() syscall to set SCHED_DEADLINE.

Fixes: #376

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
  • Loading branch information
dougsland committed Apr 24, 2024
1 parent 1eb55c4 commit a81c6ef
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
23 changes: 23 additions & 0 deletions tests/e2e/tools/FFI/deny_sched_setattr/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# What is execute_sched_setattr ?

A test tool to validate if SCHED_DEADLINE can be set via sched_setattr() syscall.

## Why?
QM environment should not allow SCHED_DEADLINE be set via sched_setattr() syscall
and must validated via FFI tests.

## How to deny is made?
During the QM service startup it passes arguments to Podman. One of these arguments is `seccomp=/usr/share/qm/seccomp.json` which contains rules that deny the `sched_setattr()`.

## How to test?

```
host> gcc -o execute_sched_setattr execute_sched_setattr.c -Wall # build the bin
host> cp execute_sched_setattr /usr/lib/qm/rootfs/root/ # copy the bin to QM partition

# podman exec -it qm bash # Execute the test, it must fail in recent versions of QM
bash-5.1# cd /root && ./execute_sched_setattr
Current Scheduling Policy: SCHED_OTHER
Current Priority: 0
sched_setattr failed: Operation not permitted
```
91 changes: 91 additions & 0 deletions tests/e2e/tools/FFI/deny_sched_setattr/execute_sched_setattr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <linux/types.h>
#include <sched.h>

struct sched_attr {
__u32 size;

__u32 sched_policy;
__u64 sched_flags;

// SCHED_NORMAL, SCHED_BATCH
__s32 sched_nice;

// SCHED_FIFO, SCHED_RR
__u32 sched_priority;

// SCHED_DEADLINE
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
};

int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags) {
return syscall(SYS_sched_setattr, pid, attr, flags);
}

// Function to get the scheduling policy and priority of the current process
void get_sched() {
int policy;
struct sched_param param;

// Get current scheduling policy
policy = sched_getscheduler(0);
if (policy == -1) {
perror("sched_getscheduler");
exit(EXIT_FAILURE);
}

// Get the current priority
if (sched_getparam(0, &param) == -1) {
perror("sched_getparam");
exit(EXIT_FAILURE);
}

printf("Current Scheduling Policy: ");
switch (policy) {
case SCHED_OTHER:
printf("SCHED_OTHER\n");
break;
case SCHED_FIFO:
printf("SCHED_FIFO\n");
break;
case SCHED_RR:
printf("SCHED_RR\n");
break;
case SCHED_DEADLINE:
printf("SCHED_DEADLINE\n");
break;
default:
printf("Unknown\n");
}

printf("Current Priority: %d\n", param.sched_priority);
}

int main() {
struct sched_attr attr;
memset(&attr, 0, sizeof(attr)); // initialization
attr.size = sizeof(attr);
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 10 * 1000 * 1000; // 10 ms
attr.sched_deadline = 20 * 1000 * 1000; // 20 ms
attr.sched_period = 30 * 1000 * 1000; // 30 ms

get_sched();

if (sched_setattr(0, &attr, 0) == -1) {
perror("sched_setattr failed");
return 1;
}

// Now the thread should be running under SCHED_DEADLINE
get_sched();

return 0;
}

0 comments on commit a81c6ef

Please sign in to comment.