"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-prctl.c" (15 Mar 2019, 9190 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-prctl.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.50_vs_0.09.51.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 #if defined(HAVE_SYS_PRCTL_H) &&        \
   28     defined(HAVE_PRCTL) &&          \
   29     (defined(PR_CAP_AMBIENT) ||         \
   30      defined(PR_CAPBSET_READ) ||        \
   31      defined(PR_CAPBSET_DROP) ||        \
   32      defined(PR_SET_CHILD_SUBREAPER) ||     \
   33      defined(PR_GET_CHILD_SUBREAPER) ||     \
   34      defined(PR_SET_DUMPABLE) ||        \
   35      defined(PR_GET_DUMPABLE) ||        \
   36      defined(PR_SET_ENDIAN) ||          \
   37      defined(PR_GET_ENDIAN) ||          \
   38      defined(PR_SET_FP_MODE) ||         \
   39      defined(PR_GET_FP_MODE) ||         \
   40      defined(PR_SET_FPEMU) ||           \
   41      defined(PR_GET_FPEMU) ||           \
   42      defined(PR_SET_FPEXC) ||           \
   43      defined(PR_GET_FPEXC) ||           \
   44      defined(PR_SET_KEEPCAPS) ||        \
   45      defined(PR_GET_KEEPCAPS) ||        \
   46      defined(PR_MCE_KILL) ||            \
   47      defined(PR_MCE_KILL_GET) ||        \
   48      defined(PR_SET_MM) ||          \
   49      defined(PR_MPX_ENABLE_MANAGEMENT) ||   \
   50      defined(PR_MPX_DISABLE_MANAGEMENT) ||  \
   51      defined(PR_SET_NAME) ||            \
   52      defined(PR_GET_NAME) ||            \
   53      defined(PR_SET_NO_NEW_PRIVS) ||        \
   54      defined(PR_GET_NO_NEW_PRIVS) ||        \
   55      defined(PR_SET_PDEATHSIG) ||       \
   56      defined(PR_GET_PDEATHSIG) ||       \
   57      defined(PR_SET_PTRACER) ||         \
   58      defined(PR_SET_SECCOMP) ||         \
   59      defined(PR_GET_SECCOMP) ||         \
   60      defined(PR_SET_SECUREBITS) ||      \
   61      defined(PR_GET_SECUREBITS) ||      \
   62      defined(PR_SET_THP_DISABLE) ||     \
   63      defined(PR_TASK_PERF_EVENTS_DISABLE) ||    \
   64      defined(PR_TASK_PERF_EVENTS_ENABLE) || \
   65      defined(PR_GET_THP_DISABLE) ||     \
   66      defined(PR_GET_TID_ADDRESS) ||     \
   67      defined(PR_SET_TIMERSLACK) ||      \
   68      defined(PR_GET_TIMERSLACK) ||      \
   69      defined(PR_SET_TIMING) ||          \
   70      defined(PR_GET_TIMING) ||          \
   71      defined(PR_SET_TSC) ||         \
   72      defined(PR_GET_TSC) ||         \
   73      defined(PR_SET_UNALIGN) ||         \
   74      defined(PR_GET_UNALIGN))
   75 
   76 static int stress_prctl_child(const args_t *args)
   77 {
   78     int ret;
   79 
   80     (void)args;
   81 
   82 #if defined(PR_CAP_AMBIENT)
   83     /* skip for now */
   84 #endif
   85 #if defined(PR_CAPBSET_READ) && defined(CAP_CHOWN)
   86     ret = prctl(PR_CAPBSET_READ, CAP_CHOWN);
   87     (void)ret;
   88 #endif
   89 
   90 #if defined(PR_CAPBSET_DROP) && defined(CAP_CHOWN)
   91     ret = prctl(PR_CAPBSET_DROP, CAP_CHOWN);
   92     (void)ret;
   93 #endif
   94 
   95 #if defined(PR_GET_CHILD_SUBREAPER)
   96     {
   97         int reaper;
   98 
   99         ret = prctl(PR_GET_CHILD_SUBREAPER, &reaper);
  100         (void)ret;
  101 
  102 #if defined(PR_SET_CHILD_SUBREAPER)
  103         if (ret == 0) {
  104             ret = prctl(PR_SET_CHILD_SUBREAPER, reaper);
  105             (void)ret;
  106         }
  107 #endif
  108     }
  109 #endif
  110 
  111 #if defined(PR_GET_DUMPABLE)
  112     {
  113         ret = prctl(PR_GET_DUMPABLE);
  114         (void)ret;
  115 
  116 #if defined(PR_SET_DUMPABLE)
  117         if (ret >= 0) {
  118             ret = prctl(PR_SET_DUMPABLE, ret);
  119             (void)ret;
  120         }
  121 #endif
  122     }
  123 #endif
  124 
  125 #if defined(PR_GET_ENDIAN)
  126     /* PowerPC only, but try it on all arches */
  127     {
  128         int endian;
  129 
  130         ret = prctl(PR_GET_ENDIAN, &endian);
  131         (void)ret;
  132 
  133 #if defined(PR_SET_ENDIAN)
  134         if (ret == 0) {
  135             ret = prctl(PR_SET_ENDIAN, endian);
  136             (void)ret;
  137         }
  138 #endif
  139     }
  140 #endif
  141 
  142 #if defined(PR_GET_FP_MODE)
  143     /* MIPS only, but try it on all arches */
  144     {
  145         unsigned int mode;
  146 
  147         ret = prctl(PR_GET_FP_MODE, &mode);
  148         (void)ret;
  149 
  150 #if defined(PR_SET_FP_MODE)
  151         if (ret == 0) {
  152             ret = prctl(PR_SET_FP_MODE, mode);
  153             (void)ret;
  154         }
  155 #endif
  156     }
  157 #endif
  158 
  159 #if defined(PR_GET_FPEMU)
  160     /* ia64 only, but try it on all arches */
  161     {
  162         int control;
  163 
  164         ret = prctl(PR_GET_FPEMU, &control);
  165         (void)ret;
  166 
  167 #if defined(PR_SET_FPEMU)
  168         if (ret == 0) {
  169             ret = prctl(PR_SET_FPEMU, control);
  170             (void)ret;
  171         }
  172 #endif
  173     }
  174 #endif
  175 
  176 #if defined(PR_GET_FPEXC)
  177     /* PowerPC only, but try it on all arches */
  178     {
  179         int mode;
  180 
  181         ret = prctl(PR_GET_FPEXC, &mode);
  182         (void)ret;
  183 
  184 #if defined(PR_SET_FPEXC)
  185         if (ret == 0) {
  186             ret = prctl(PR_SET_FPEXC, mode);
  187             (void)ret;
  188         }
  189 #endif
  190     }
  191 #endif
  192 
  193 #if defined(PR_GET_KEEPCAPS)
  194     {
  195         int flag;
  196 
  197         ret = prctl(PR_GET_KEEPCAPS, &flag);
  198         (void)ret;
  199 
  200 #if defined(PR_SET_KEEPCAPS)
  201         if (ret == 0) {
  202             ret = prctl(PR_SET_KEEPCAPS, flag);
  203             (void)ret;
  204         }
  205 #endif
  206     }
  207 #endif
  208 
  209 #if defined(PR_MCE_KILL_GET)
  210     ret = prctl(PR_MCE_KILL_GET, 0, 0, 0, 0);
  211     (void)ret;
  212 #endif
  213 
  214 #if defined(PR_MCE_KILL)
  215     ret = prctl(PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0, 0);
  216     (void)ret;
  217 #endif
  218 
  219 #if defined(PR_SET_MM) && defined(PR_SET_MM_BRK)
  220     ret = prctl(PR_SET_MM, PR_SET_MM_BRK, sbrk(0));
  221     (void)ret;
  222 #endif
  223 
  224 #if defined(PR_MPX_ENABLE_MANAGEMENT)
  225     /* skip this for now */
  226 #endif
  227 
  228 #if defined(PR_MPX_DISABLE_MANAGEMENT)
  229     /* skip this for now */
  230 #endif
  231 
  232 #if defined(PR_GET_NAME)
  233     {
  234         char name[17];
  235 
  236         (void)memset(name, 0, sizeof name);
  237 
  238         ret = prctl(PR_GET_NAME, name);
  239         (void)ret;
  240 
  241 #if defined(PR_SET_NAME)
  242         if (ret == 0) {
  243             ret = prctl(PR_SET_NAME, name);
  244             (void)ret;
  245         }
  246 #endif
  247     }
  248 #endif
  249 
  250 #if defined(PR_GET_NO_NEW_PRIVS)
  251     {
  252         ret = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
  253         (void)ret;
  254 
  255 #if defined(PR_SET_NO_NEW_PRIVS)
  256         if (ret >= 0) {
  257             ret = prctl(PR_SET_NO_NEW_PRIVS, ret, 0, 0, 0);
  258             (void)ret;
  259         }
  260 #endif
  261     }
  262 #endif
  263 
  264 #if defined(PR_GET_PDEATHSIG)
  265     {
  266         int sig;
  267 
  268         ret = prctl(PR_GET_PDEATHSIG, &sig);
  269         (void)ret;
  270 
  271 #if defined(PR_SET_PDEATHSIG)
  272         if (ret == 0) {
  273             ret = prctl(PR_SET_PDEATHSIG, sig);
  274             (void)ret;
  275         }
  276 #endif
  277     }
  278 #endif
  279 
  280 #if defined(PR_SET_PTRACER)
  281     /* skip this for the moment */
  282 #endif
  283 
  284 #if defined(PR_GET_SECCOMP)
  285     {
  286         ret = prctl(PR_GET_SECCOMP);
  287         (void)ret;
  288 
  289 #if defined(PR_SET_SECCOMP)
  290     /* skip this for the moment */
  291 #endif
  292     }
  293 #endif
  294 
  295 #if defined(PR_GET_SECUREBITS)
  296     {
  297         ret = prctl(PR_GET_SECUREBITS, 0, 0, 0, 0);
  298         (void)ret;
  299 
  300 #if defined(PR_SET_SECUREBITS)
  301         if (ret >= 0) {
  302             ret = prctl(PR_SET_SECUREBITS, ret, 0, 0, 0);
  303             (void)ret;
  304         }
  305 #endif
  306     }
  307 #endif
  308 
  309 #if defined(PR_GET_THP_DISABLE)
  310     {
  311         ret = prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0);
  312         (void)ret;
  313 
  314 #if defined(PR_SET_THP_DISABLE)
  315         if (ret >= 0) {
  316             ret = prctl(PR_SET_THP_DISABLE, 0, 0, 0, 0);
  317             (void)ret;
  318         }
  319 #endif
  320     }
  321 #endif
  322 
  323 #if defined(PR_TASK_PERF_EVENTS_DISABLE)
  324     ret = prctl(PR_TASK_PERF_EVENTS_DISABLE);
  325     (void)ret;
  326 #endif
  327 
  328 #if defined(PR_TASK_PERF_EVENTS_ENABLE)
  329     ret = prctl(PR_TASK_PERF_EVENTS_ENABLE);
  330     (void)ret;
  331 #endif
  332 
  333 #if defined(PR_GET_TID_ADDRESS)
  334     {
  335         uint64_t val;
  336 
  337         ret = prctl(PR_GET_TID_ADDRESS, &val);
  338         (void)ret;
  339     }
  340 #endif
  341 
  342 #if defined(PR_GET_TIMERSLACK)
  343     {
  344         ret = prctl(PR_GET_TIMERSLACK, 0, 0, 0, 0);
  345         (void)ret;
  346 
  347 #if defined(PR_SET_TIMERSLACK)
  348         if (ret >= 0) {
  349             ret = prctl(PR_SET_TIMERSLACK, ret, 0, 0, 0);
  350             (void)ret;
  351         }
  352 #endif
  353     }
  354 #endif
  355 
  356 #if defined(PR_GET_TIMING)
  357     {
  358         ret = prctl(PR_GET_TIMING, 0, 0, 0, 0);
  359         (void)ret;
  360 
  361 #if defined(PR_SET_TIMING)
  362         if (ret >= 0) {
  363             ret = prctl(PR_SET_TIMING, ret, 0, 0, 0);
  364             (void)ret;
  365         }
  366 #endif
  367     }
  368 #endif
  369 
  370 #if defined(PR_GET_TSC)
  371     {
  372         /* x86 only, but try it on all arches */
  373         int state;
  374 
  375         ret = prctl(PR_GET_TSC, &state, 0, 0, 0);
  376         (void)ret;
  377 
  378 #if defined(PR_SET_TSC)
  379         if (ret == 0) {
  380             ret = prctl(PR_SET_TSC, state, 0, 0, 0);
  381             (void)ret;
  382         }
  383 #endif
  384     }
  385 #endif
  386 
  387 #if defined(PR_GET_UNALIGN)
  388     {
  389         /* ia64, parisc, powerpc, alpha, sh, tile, but try it on all arches */
  390         unsigned int control;
  391 
  392         ret = prctl(PR_GET_UNALIGN, &control, 0, 0, 0);
  393         (void)ret;
  394 
  395 #if defined(PR_SET_UNALIGN)
  396         if (ret == 0) {
  397             ret = prctl(PR_SET_UNALIGN, control, 0, 0, 0);
  398             (void)ret;
  399         }
  400 #endif
  401     }
  402 #endif
  403     (void)ret;
  404 
  405     return 0;
  406 }
  407 
  408 /*
  409  *  stress_prctl()
  410  *  stress seccomp
  411  */
  412 static int stress_prctl(const args_t *args)
  413 {
  414     do {
  415         pid_t pid;
  416 
  417         pid = fork();
  418         if (pid == -1) {
  419             pr_fail_err("fork");
  420             break;
  421         }
  422         if (pid == 0) {
  423             int rc;
  424 
  425             rc = stress_prctl_child(args);
  426             _exit(rc);
  427         }
  428         if (pid > 0) {
  429             int status;
  430 
  431             /* Wait for child to exit or get killed by seccomp */
  432             if (waitpid(pid, &status, 0) < 0) {
  433                 if (errno != EINTR)
  434                     pr_dbg("%s: waitpid failed, errno = %d (%s)\n",
  435                         args->name, errno, strerror(errno));
  436             } else {
  437                 /* Did the child hit a weird error? */
  438                 if (WIFEXITED(status) &&
  439                     (WEXITSTATUS(status) != EXIT_SUCCESS)) {
  440                     pr_fail("%s: aborting because of unexpected "
  441                         "failure in child process\n", args->name);
  442                     return EXIT_FAILURE;
  443                 }
  444             }
  445         }
  446         inc_counter(args);
  447     } while (keep_stressing());
  448 
  449     return EXIT_SUCCESS;
  450 }
  451 
  452 stressor_info_t stress_prctl_info = {
  453     .stressor = stress_prctl,
  454     .class = CLASS_OS
  455 };
  456 #else
  457 stressor_info_t stress_prctl_info = {
  458     .stressor = stress_not_implemented,
  459     .class = CLASS_OS
  460 };
  461 #endif