Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools: add deny_sched_setattr #378

Merged
merged 1 commit into from
Apr 24, 2024
Merged
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
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;
}
Loading