DF-2794 / rtprio_tid.c
/* DF-2794: sys_lwp_rtprio() with tid == -1 ignores the target pid and * always operates on the caller's own lwp. * * Run as root: fork a child; RTP_SET(pid=child, tid=-1, prio). * expect (vulnerable): set succeeds; the CALLER's rtprio changed to * what was intended for the child, the child's rtprio unchanged. * expect (patched): the CHILD's first lwp gets the rtprio; caller unchanged. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <signal.h> #include <sys/rtprio.h> #include <sys/types.h> /* libc provides lwp_rtprio(3): int lwp_rtprio(int, pid_t, lwpid_t, struct rtprio *) */ static void show(const char *who) { struct rtprio rt; rt.type = 0; if (lwp_rtprio(RTP_LOOKUP, 0, -1, &rt) < 0) printf("DF2794 %-7s RTP_LOOKUP errno=%d\n", who, errno); else printf("DF2794 %-7s type=%d prio=%d\n", who, rt.type, rt.prio); } int main(void) { struct rtprio rt; pid_t pid; int st; show("parent"); pid = fork(); if (pid == 0) { pause(); _exit(0); } sleep(1); rt.type = RTP_PRIO_REALTIME; rt.prio = 31; printf("DF2794 RTP_SET(pid=child=%d, tid=-1, RTP_PRIO_REALTIME/31)\n", (int)pid); if (lwp_rtprio(RTP_SET, pid, -1, &rt) < 0) printf("DF2794 RTP_SET errno=%d (%s)\n", errno, strerror(errno)); else printf("DF2794 RTP_SET rv=0 (success)\n"); show("parent"); /* caller after the set */ kill(pid, SIGKILL); waitpid(pid, &st, 0); /* the child's rtprio can no longer be read after exit; the parent's * own rtprio changing from the child-directed call IS the demo */ return 0; } |