"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-key.c" (15 Mar 2019, 5561 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-key.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    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_KEYUTILS_H) && \
   28     defined(HAVE_ADD_KEY) && \
   29     defined(HAVE_KEYCTL)
   30 
   31 #define MAX_KEYS    (256)
   32 #define KEYCTL_TIMEOUT  (2)
   33 
   34 static long sys_keyctl(int cmd, ...)
   35 {
   36     va_list args;
   37     long int arg0, arg1, arg2, ret;
   38 
   39     va_start(args, cmd);
   40     arg0 = va_arg(args, long int);
   41     arg1 = va_arg(args, long int);
   42     arg2 = va_arg(args, long int);
   43     ret = syscall(__NR_keyctl, cmd, arg0, arg1, arg2);
   44     va_end(args);
   45 
   46     return ret;
   47 }
   48 
   49 static key_serial_t sys_add_key(
   50     const char *type,
   51     const char *description,
   52     const void *payload,
   53     size_t plen,
   54     key_serial_t keyring)
   55 {
   56     return (key_serial_t)syscall(__NR_add_key, type,
   57         description, payload, plen, keyring);
   58 }
   59 
   60 #if defined(HAVE_REQUEST_KEY)
   61 static key_serial_t sys_request_key(
   62     const char *type,
   63     const char *description,
   64     const char *callout_info,
   65     key_serial_t keyring)
   66 {
   67     return (key_serial_t)syscall(__NR_request_key,
   68         type, description, callout_info, keyring);
   69 }
   70 #endif
   71 
   72 /*
   73  *  stress_key
   74  *  stress key operations
   75  */
   76 static int stress_key(const args_t *args)
   77 {
   78     key_serial_t keys[MAX_KEYS];
   79     pid_t ppid = getppid();
   80     int rc = EXIT_SUCCESS;
   81     bool timeout_supported = true;
   82     bool no_error = true;
   83 
   84     do {
   85         size_t i = 0, n = 0;
   86         char description[64];
   87         char payload[64];
   88 
   89         /* Add as many keys as we are allowed */
   90         for (n = 0; n < MAX_KEYS; n++) {
   91             (void)snprintf(description, sizeof(description),
   92                 "stress-ng-key-%u-%" PRIu32
   93                 "-%zu", ppid, args->instance, n);
   94             (void)snprintf(payload, sizeof(payload),
   95                 "somedata-%zu", n);
   96 
   97             keys[n] = sys_add_key("user", description,
   98                 payload, strlen(payload),
   99                 KEY_SPEC_PROCESS_KEYRING);
  100             if (keys[n] < 0) {
  101                 if (errno == ENOSYS) {
  102                     pr_inf("%s: skipping stressor, add_key not implemented\n",
  103                         args->name);
  104                     no_error = false;
  105                     rc = EXIT_NOT_IMPLEMENTED;
  106                     goto tidy;
  107                 }
  108                 if ((errno == ENOMEM) || (errno == EDQUOT))
  109                     break;
  110                 pr_fail_err("add_key");
  111                 goto tidy;
  112             }
  113 #if defined(KEYCTL_SET_TIMEOUT)
  114             if (timeout_supported) {
  115                 if (sys_keyctl(KEYCTL_SET_TIMEOUT, keys[n], KEYCTL_TIMEOUT) < 0) {
  116                     /* Some platforms don't support this */
  117                     if (errno == ENOSYS) {
  118                         timeout_supported = false;
  119                     } else {
  120                         pr_fail_err("keyctl KEYCTL_SET_TIMEOUT");
  121                     }
  122                 }
  123             }
  124             if (!g_keep_stressing_flag)
  125                 goto tidy;
  126 #endif
  127         }
  128 
  129         /* And manipulate the keys */
  130         for (i = 0; i < n; i++) {
  131             (void)snprintf(description, sizeof(description),
  132                 "stress-ng-key-%u-%" PRIu32
  133                 "-%zu", ppid, args->instance, i);
  134 #if defined(KEYCTL_DESCRIBE)
  135             if (sys_keyctl(KEYCTL_DESCRIBE, keys[i], description) < 0)
  136                 pr_fail_err("keyctl KEYCTL_DESCRIBE");
  137             if (!g_keep_stressing_flag)
  138                 goto tidy;
  139 #endif
  140 
  141             (void)snprintf(payload, sizeof(payload),
  142                 "somedata-%zu", n);
  143 #if defined(KEYCTL_UPDATE)
  144             if (sys_keyctl(KEYCTL_UPDATE, keys[i],
  145                 payload, strlen(payload)) < 0) {
  146                 if ((errno != ENOMEM) && (errno != EDQUOT))
  147                     pr_fail_err("keyctl KEYCTL_UPDATE");
  148             }
  149             if (!g_keep_stressing_flag)
  150                 goto tidy;
  151 #endif
  152 
  153 #if defined(KEYCTL_READ)
  154             (void)memset(payload, 0, sizeof(payload));
  155             if (sys_keyctl(KEYCTL_READ, keys[i],
  156                 payload, sizeof(payload)) < 0)
  157                 pr_fail_err("keyctl KEYCTL_READ");
  158             if (!g_keep_stressing_flag)
  159                 goto tidy;
  160 #endif
  161 
  162 #if defined(HAVE_REQUEST_KEY)
  163             (void)snprintf(description, sizeof(description),
  164                 "stress-ng-key-%u-%" PRIu32
  165                 "-%zu", ppid, args->instance, i);
  166             if (sys_request_key("user", description, NULL,
  167                 KEY_SPEC_PROCESS_KEYRING) < 0) {
  168                 pr_fail_err("request_key");
  169             }
  170             if (!g_keep_stressing_flag)
  171                 goto tidy;
  172 #endif
  173 
  174 
  175 #if defined(KEYCTL_CHOWN)
  176             (void)sys_keyctl(KEYCTL_CHOWN, keys[i], getuid(), -1);
  177             (void)sys_keyctl(KEYCTL_CHOWN, keys[i], -1, getgid());
  178 #endif
  179 
  180 #if defined(KEYCTL_SETPERM)
  181             (void)sys_keyctl(KEYCTL_SETPERM, keys[i], KEY_USR_ALL);
  182 #endif
  183 #if defined(KEYCTL_REVOKE)
  184             if (mwc1())
  185                 (void)sys_keyctl(KEYCTL_REVOKE, keys[i]);
  186 #endif
  187 #if defined(KEYCTL_INVALIDATE)
  188             (void)sys_keyctl(KEYCTL_INVALIDATE, keys[i]);
  189 #endif
  190         }
  191 tidy:
  192         inc_counter(args);
  193         /* If we hit too many errors and bailed out early, clean up */
  194         for (i = 0; i < n; i++) {
  195             if (keys[i] >= 0) {
  196 #if defined(KEYCTL_INVALIDATE)
  197                 (void)sys_keyctl(KEYCTL_INVALIDATE, keys[i]);
  198 #endif
  199             }
  200         }
  201     } while (no_error && keep_stressing());
  202 
  203     return rc;
  204 }
  205 
  206 stressor_info_t stress_key_info = {
  207     .stressor = stress_key,
  208     .class = CLASS_OS
  209 };
  210 #else
  211 stressor_info_t stress_key_info = {
  212     .stressor = stress_not_implemented,
  213     .class = CLASS_OS
  214 };
  215 #endif