(root)/
strace-6.5/
tests-mx32/
sched_xetattr.c
       1  /*
       2   * Check decoding of sched_getattr and sched_setattr syscalls.
       3   *
       4   * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2015-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  
      14  #include <inttypes.h>
      15  #include <stdio.h>
      16  #include <sched.h>
      17  #include <unistd.h>
      18  #include "pidns.h"
      19  #include "sched_attr.h"
      20  #include "xlat.h"
      21  #include "xlat/schedulers.h"
      22  
      23  static const char *errstr;
      24  
      25  static long
      26  sys_sched_getattr(kernel_ulong_t pid, kernel_ulong_t attr,
      27  		  kernel_ulong_t size, kernel_ulong_t flags)
      28  {
      29  	long rc = syscall(__NR_sched_getattr, pid, attr, size, flags);
      30  	errstr = sprintrc(rc);
      31  	return rc;
      32  }
      33  
      34  static long
      35  sys_sched_setattr(kernel_ulong_t pid, kernel_ulong_t attr, kernel_ulong_t flags)
      36  {
      37  	long rc = syscall(__NR_sched_setattr, pid, attr, flags);
      38  	errstr = sprintrc(rc);
      39  	return rc;
      40  }
      41  
      42  int
      43  main(void)
      44  {
      45  	PIDNS_TEST_INIT;
      46  
      47  	static const kernel_ulong_t bogus_pid =
      48  		(kernel_ulong_t) 0xdefacedfacefeedULL;
      49  	static const kernel_ulong_t bogus_size =
      50  		(kernel_ulong_t) 0xdefacedcafef00dULL;
      51  	static const kernel_ulong_t bogus_flags =
      52  		(kernel_ulong_t) 0xdefaceddeadc0deULL;
      53  
      54  	const int pid = getpid();
      55  	const char *pid_str = pidns_pid2str(PT_TGID);
      56  
      57  	TAIL_ALLOC_OBJECT_CONST_PTR(struct sched_attr, attr);
      58  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, psize);
      59  	void *const efault = attr + 1;
      60  
      61  	sys_sched_getattr(pid, 0, 0, 0);
      62  	pidns_print_leader();
      63  	printf("sched_getattr(%d%s, NULL, 0, 0) = %s\n",
      64  		pid, pid_str, errstr);
      65  
      66  	sys_sched_getattr(0, (unsigned long) attr, 0, 0);
      67  	pidns_print_leader();
      68  	printf("sched_getattr(0, %p, 0, 0) = %s\n", attr, errstr);
      69  
      70  	sys_sched_getattr(bogus_pid, 0, 0, 0);
      71  	pidns_print_leader();
      72  	printf("sched_getattr(%d, NULL, 0, 0) = %s\n", (int) bogus_pid, errstr);
      73  
      74  	sys_sched_getattr(-1U, (unsigned long) attr, bogus_size, bogus_flags);
      75  	pidns_print_leader();
      76  	printf("sched_getattr(-1, %p, %s%u, %u) = %s\n",
      77  	       attr,
      78  #if defined __arm64__ || defined __aarch64__
      79  	       "0xdefaced<<32|",
      80  #else
      81  	       "",
      82  #endif
      83  	       (unsigned) bogus_size, (unsigned) bogus_flags, errstr);
      84  
      85  	sys_sched_getattr(0, (unsigned long) efault, SCHED_ATTR_MIN_SIZE, 0);
      86  	pidns_print_leader();
      87  	printf("sched_getattr(0, %p, %u, 0) = %s\n",
      88  	       efault, (unsigned) SCHED_ATTR_MIN_SIZE, errstr);
      89  
      90  	if (sys_sched_getattr(0, (unsigned long) attr, SCHED_ATTR_MIN_SIZE, 0))
      91  		perror_msg_and_skip("sched_getattr");
      92  	pidns_print_leader();
      93  	printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
      94  	printxval(schedulers, attr->sched_policy, NULL);
      95  	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
      96  	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
      97  	       ", sched_period=%" PRIu64 "}, %u, 0) = 0\n",
      98  	       attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
      99  	       attr->sched_nice,
     100  	       attr->sched_priority,
     101  	       attr->sched_runtime,
     102  	       attr->sched_deadline,
     103  	       attr->sched_period,
     104  	       (unsigned) SCHED_ATTR_MIN_SIZE);
     105  
     106  	sys_sched_getattr(0, (unsigned long) efault, sizeof(*attr), 0);
     107  	pidns_print_leader();
     108  	printf("sched_getattr(0, %p, %u, 0) = %s\n",
     109  	       efault, (unsigned) sizeof(*attr), errstr);
     110  
     111  	if (sys_sched_getattr(0, (unsigned long) attr, sizeof(*attr), 0))
     112  		perror_msg_and_skip("sched_getattr");
     113  	pidns_print_leader();
     114  	printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
     115  	printxval(schedulers, attr->sched_policy, NULL);
     116  	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
     117  	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
     118  	       ", sched_period=%" PRIu64,
     119  	       attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
     120  	       attr->sched_nice,
     121  	       attr->sched_priority,
     122  	       attr->sched_runtime,
     123  	       attr->sched_deadline,
     124  	       attr->sched_period);
     125  	if (attr->size >= SCHED_ATTR_SIZE_VER1) {
     126  		printf(", sched_util_min=%u, sched_util_max=%u",
     127  		       attr->sched_util_min,
     128  		       attr->sched_util_max);
     129  	}
     130  	printf("}, %u, 0) = 0\n", (unsigned) sizeof(*attr));
     131  
     132  #if defined __arm64__ || defined __aarch64__
     133  	long rc =
     134  #endif
     135  	sys_sched_getattr(F8ILL_KULONG_MASK, (unsigned long) attr,
     136  			  F8ILL_KULONG_MASK | sizeof(*attr), F8ILL_KULONG_MASK);
     137  #if defined __arm64__ || defined __aarch64__
     138  	if (rc) {
     139  		pidns_print_leader();
     140  		printf("sched_getattr(0, %p, 0xffffffff<<32|%u, 0) = %s\n",
     141  		       attr, (unsigned) sizeof(*attr), errstr);
     142  	} else
     143  #endif
     144  	{
     145  		pidns_print_leader();
     146  		printf("sched_getattr(0, {size=%u, sched_policy=", attr->size);
     147  		printxval(schedulers, attr->sched_policy, NULL);
     148  		printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
     149  		       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
     150  		       ", sched_period=%" PRIu64,
     151  		       attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
     152  		       attr->sched_nice,
     153  		       attr->sched_priority,
     154  		       attr->sched_runtime,
     155  		       attr->sched_deadline,
     156  		       attr->sched_period);
     157  		if (attr->size >= SCHED_ATTR_SIZE_VER1) {
     158  			printf(", sched_util_min=%u, sched_util_max=%u",
     159  			       attr->sched_util_min,
     160  			       attr->sched_util_max);
     161  		}
     162  		printf("}, %u, 0) = 0\n", (unsigned) sizeof(*attr));
     163  	}
     164  
     165  	sys_sched_setattr(bogus_pid, 0, 0);
     166  	pidns_print_leader();
     167  	printf("sched_setattr(%d, NULL, 0) = %s\n", (int) bogus_pid, errstr);
     168  
     169  	attr->sched_flags |= 1;
     170  
     171  	if (sys_sched_setattr(pid, (unsigned long) attr, 0))
     172  		perror_msg_and_skip("sched_setattr");
     173  	pidns_print_leader();
     174  	printf("sched_setattr(%d%s, {size=%u, sched_policy=",
     175  		pid, pid_str, attr->size);
     176  	printxval(schedulers, attr->sched_policy, NULL);
     177  	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
     178  	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
     179  	       ", sched_period=%" PRIu64,
     180  	       "SCHED_FLAG_RESET_ON_FORK",
     181  	       attr->sched_nice,
     182  	       attr->sched_priority,
     183  	       attr->sched_runtime,
     184  	       attr->sched_deadline,
     185  	       attr->sched_period);
     186  	if (attr->size >= SCHED_ATTR_SIZE_VER1) {
     187  		printf(", sched_util_min=%u, sched_util_max=%u",
     188  		       attr->sched_util_min,
     189  		       attr->sched_util_max);
     190  	}
     191  	printf("}, 0) = 0\n");
     192  
     193  	sys_sched_setattr(F8ILL_KULONG_MASK, (unsigned long) attr,
     194  			  F8ILL_KULONG_MASK);
     195  	pidns_print_leader();
     196  	printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
     197  	printxval(schedulers, attr->sched_policy, NULL);
     198  	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
     199  	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
     200  	       ", sched_period=%" PRIu64,
     201  	       "SCHED_FLAG_RESET_ON_FORK",
     202  	       attr->sched_nice,
     203  	       attr->sched_priority,
     204  	       attr->sched_runtime,
     205  	       attr->sched_deadline,
     206  	       attr->sched_period);
     207  	if (attr->size >= SCHED_ATTR_SIZE_VER1) {
     208  		printf(", sched_util_min=%u, sched_util_max=%u",
     209  		       attr->sched_util_min,
     210  		       attr->sched_util_max);
     211  	}
     212  	printf("}, 0) = 0\n");
     213  
     214  	*psize = attr->size;
     215  
     216  	sys_sched_setattr(0, (unsigned long) psize, 0);
     217  	pidns_print_leader();
     218  	printf("sched_setattr(0, %p, 0) = %s\n", psize, errstr);
     219  
     220  	attr->size = 0;
     221  
     222  	sys_sched_setattr(0, (unsigned long) attr, 0);
     223  	pidns_print_leader();
     224  	printf("sched_setattr(0, {size=%u, sched_policy=", attr->size);
     225  	printxval(schedulers, attr->sched_policy, NULL);
     226  	printf(", sched_flags=%s, sched_nice=%d, sched_priority=%u"
     227  	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
     228  	       ", sched_period=%" PRIu64 "}, 0) = 0\n",
     229  	       "SCHED_FLAG_RESET_ON_FORK",
     230  	       attr->sched_nice,
     231  	       attr->sched_priority,
     232  	       attr->sched_runtime,
     233  	       attr->sched_deadline,
     234  	       attr->sched_period);
     235  
     236  	attr->size = 1;
     237  
     238  	sys_sched_setattr(0, (unsigned long) attr, 0);
     239  	pidns_print_leader();
     240  	printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
     241  	       1, attr->size, errstr);
     242  
     243  	attr->size = SCHED_ATTR_MIN_SIZE - 1;
     244  
     245  	sys_sched_setattr(0, (unsigned long) attr, 0);
     246  	pidns_print_leader();
     247  	printf("sched_setattr(0, {size=%u} => {size=%u}, 0) = %s\n",
     248  	       SCHED_ATTR_MIN_SIZE - 1, attr->size, errstr);
     249  
     250  	attr->size = 0x90807060;
     251  	attr->sched_policy = 0xca7faced;
     252  	attr->sched_flags = 0xbadc0ded1057da80ULL;
     253  	attr->sched_nice = 0xafbfcfdf;
     254  	attr->sched_priority = 0xb8c8d8e8;
     255  	attr->sched_runtime = 0xbadcaffedeadf157ULL;
     256  	attr->sched_deadline = 0xc0de70a57badac75ULL;
     257  	attr->sched_period = 0xded1ca7edda7aca7ULL;
     258  
     259  	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
     260  	pidns_print_leader();
     261  	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
     262  	       "sched_flags=%#" PRIx64 " /* SCHED_FLAG_??? */, "
     263  	       "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
     264  	       "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 ", "
     265  	       "sched_util_min=%u, sched_util_max=%u, ...}, %u) = %s\n",
     266  	       (int) bogus_pid,
     267  	       attr->size,
     268  	       attr->sched_policy,
     269  	       attr->sched_flags,
     270  	       attr->sched_nice,
     271  	       attr->sched_priority,
     272  	       attr->sched_runtime,
     273  	       attr->sched_deadline,
     274  	       attr->sched_period,
     275  	       attr->sched_util_min,
     276  	       attr->sched_util_max,
     277  	       (unsigned) bogus_flags, errstr);
     278  
     279  	if (F8ILL_KULONG_SUPPORTED) {
     280  		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
     281  
     282  		sys_sched_getattr(0, ill, sizeof(*attr), 0);
     283  		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
     284  		       (unsigned long long) ill, (unsigned) sizeof(*attr),
     285  		       errstr);
     286  
     287  		sys_sched_setattr(0, ill, 0);
     288  		printf("sched_setattr(0, %#llx, 0) = %s\n",
     289  		       (unsigned long long) ill, errstr);
     290  	}
     291  
     292  
     293  	attr->size = 0x90807060;
     294  	attr->sched_policy = 0xca7faced;
     295  	attr->sched_flags = 0x87ULL;
     296  	attr->sched_nice = 0xafbfcfdf;
     297  	attr->sched_priority = 0xb8c8d8e8;
     298  	attr->sched_runtime = 0xbadcaffedeadf157ULL;
     299  	attr->sched_deadline = 0xc0de70a57badac75ULL;
     300  	attr->sched_period = 0xded1ca7edda7aca7ULL;
     301  
     302  	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
     303  	pidns_print_leader();
     304  	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
     305  	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
     306  	       "SCHED_FLAG_DL_OVERRUN|0x80, "
     307  	       "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
     308  	       "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 ", "
     309  	       "sched_util_min=%u, sched_util_max=%u, ...}, %u) = %s\n",
     310  	       (int) bogus_pid,
     311  	       attr->size,
     312  	       attr->sched_policy,
     313  	       attr->sched_nice,
     314  	       attr->sched_priority,
     315  	       attr->sched_runtime,
     316  	       attr->sched_deadline,
     317  	       attr->sched_period,
     318  	       attr->sched_util_min,
     319  	       attr->sched_util_max,
     320  	       (unsigned) bogus_flags, errstr);
     321  
     322  	if (F8ILL_KULONG_SUPPORTED) {
     323  		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
     324  
     325  		sys_sched_getattr(0, ill, sizeof(*attr), 0);
     326  		pidns_print_leader();
     327  		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
     328  		       (unsigned long long) ill, (unsigned) sizeof(*attr),
     329  		       errstr);
     330  
     331  		sys_sched_setattr(0, ill, 0);
     332  		pidns_print_leader();
     333  		printf("sched_setattr(0, %#llx, 0) = %s\n",
     334  		       (unsigned long long) ill, errstr);
     335  	}
     336  
     337  	attr->size = SCHED_ATTR_MIN_SIZE;
     338  	attr->sched_policy = 0xdefaced;
     339  	attr->sched_flags = 0x8fULL;
     340  
     341  	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
     342  	pidns_print_leader();
     343  	printf("sched_setattr(%d, {size=%u, "
     344  	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
     345  	       "SCHED_FLAG_DL_OVERRUN|SCHED_FLAG_KEEP_POLICY|0x80, "
     346  	       "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
     347  	       "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 "}, %u)"
     348  	       " = %s\n",
     349  	       (int) bogus_pid,
     350  	       attr->size,
     351  	       attr->sched_nice,
     352  	       attr->sched_priority,
     353  	       attr->sched_runtime,
     354  	       attr->sched_deadline,
     355  	       attr->sched_period,
     356  	       (unsigned) bogus_flags, errstr);
     357  
     358  	if (F8ILL_KULONG_SUPPORTED) {
     359  		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
     360  
     361  		sys_sched_getattr(0, ill, sizeof(*attr), 0);
     362  		pidns_print_leader();
     363  		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
     364  		       (unsigned long long) ill, (unsigned) sizeof(*attr),
     365  		       errstr);
     366  
     367  		sys_sched_setattr(0, ill, 0);
     368  		pidns_print_leader();
     369  		printf("sched_setattr(0, %#llx, 0) = %s\n",
     370  		       (unsigned long long) ill, errstr);
     371  	}
     372  
     373  	attr->size = SCHED_ATTR_SIZE_VER1;
     374  	attr->sched_flags = 0xe7ULL;
     375  
     376  	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
     377  	pidns_print_leader();
     378  	printf("sched_setattr(%d, {size=%u, sched_policy=%#x /* SCHED_??? */, "
     379  	       "sched_flags=SCHED_FLAG_RESET_ON_FORK|SCHED_FLAG_RECLAIM|"
     380  	       "SCHED_FLAG_DL_OVERRUN|SCHED_FLAG_UTIL_CLAMP_MIN"
     381  	       "|SCHED_FLAG_UTIL_CLAMP_MAX|0x80, "
     382  	       "sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
     383  	       "sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 ", "
     384  	       "sched_util_min=%u, sched_util_max=%u}, %u) = %s\n",
     385  	       (int) bogus_pid,
     386  	       attr->size,
     387  	       attr->sched_policy,
     388  	       attr->sched_nice,
     389  	       attr->sched_priority,
     390  	       attr->sched_runtime,
     391  	       attr->sched_deadline,
     392  	       attr->sched_period,
     393  	       attr->sched_util_min,
     394  	       attr->sched_util_max,
     395  	       (unsigned) bogus_flags, errstr);
     396  
     397  	if (F8ILL_KULONG_SUPPORTED) {
     398  		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
     399  
     400  		sys_sched_getattr(0, ill, sizeof(*attr), 0);
     401  		pidns_print_leader();
     402  		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
     403  		       (unsigned long long) ill, (unsigned) sizeof(*attr),
     404  		       errstr);
     405  
     406  		sys_sched_setattr(0, ill, 0);
     407  		pidns_print_leader();
     408  		printf("sched_setattr(0, %#llx, 0) = %s\n",
     409  		       (unsigned long long) ill, errstr);
     410  	}
     411  
     412  	attr->sched_flags = 0xcaffee90LL;
     413  
     414  	sys_sched_setattr(bogus_pid, (unsigned long) attr, bogus_flags);
     415  	pidns_print_leader();
     416  	printf("sched_setattr(%d, {size=%u, sched_flags=SCHED_FLAG_KEEP_PARAMS"
     417  	       "|0xcaffee80, sched_util_min=%u, sched_util_max=%u}, %u) = %s\n",
     418  	       (int) bogus_pid,
     419  	       attr->size,
     420  	       attr->sched_util_min,
     421  	       attr->sched_util_max,
     422  	       (unsigned) bogus_flags, errstr);
     423  
     424  	if (F8ILL_KULONG_SUPPORTED) {
     425  		const kernel_ulong_t ill = f8ill_ptr_to_kulong(attr);
     426  
     427  		sys_sched_getattr(0, ill, sizeof(*attr), 0);
     428  		pidns_print_leader();
     429  		printf("sched_getattr(0, %#llx, %u, 0) = %s\n",
     430  		       (unsigned long long) ill, (unsigned) sizeof(*attr),
     431  		       errstr);
     432  
     433  		sys_sched_setattr(0, ill, 0);
     434  		pidns_print_leader();
     435  		printf("sched_setattr(0, %#llx, 0) = %s\n",
     436  		       (unsigned long long) ill, errstr);
     437  	}
     438  
     439  	pidns_print_leader();
     440  	puts("+++ exited with 0 +++");
     441  	return 0;
     442  }