github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/exec_state_workload.cc (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <signal.h>
    16  #include <stdint.h>
    17  #include <stdio.h>
    18  #include <stdlib.h>
    19  #include <sys/auxv.h>
    20  #include <sys/prctl.h>
    21  #include <sys/time.h>
    22  
    23  #include <iostream>
    24  #include <ostream>
    25  #include <string>
    26  
    27  #include "absl/strings/numbers.h"
    28  
    29  #ifndef ANDROID  // Conflicts with existing operator<< on Android.
    30  
    31  // Pretty-print a sigset_t.
    32  std::ostream& operator<<(std::ostream& out, const sigset_t& s) {
    33    out << "{ ";
    34  
    35    for (int i = 0; i < NSIG; i++) {
    36      if (sigismember(&s, i)) {
    37        out << i << " ";
    38      }
    39    }
    40  
    41    out << "}";
    42    return out;
    43  }
    44  
    45  #endif
    46  
    47  // Verify that the signo handler is handler.
    48  int CheckSigHandler(uint32_t signo, uintptr_t handler) {
    49    struct sigaction sa;
    50    int ret = sigaction(signo, nullptr, &sa);
    51    if (ret < 0) {
    52      perror("sigaction");
    53      return 1;
    54    }
    55  
    56    if (reinterpret_cast<void (*)(int)>(handler) != sa.sa_handler) {
    57      std::cerr << "signo " << signo << " handler got: " << sa.sa_handler
    58                << " expected: " << std::hex << handler;
    59      return 1;
    60    }
    61    return 0;
    62  }
    63  
    64  // Verify that the signo is blocked.
    65  int CheckSigBlocked(uint32_t signo) {
    66    sigset_t s;
    67    int ret = sigprocmask(SIG_SETMASK, nullptr, &s);
    68    if (ret < 0) {
    69      perror("sigprocmask");
    70      return 1;
    71    }
    72  
    73    if (!sigismember(&s, signo)) {
    74      std::cerr << "signal " << signo << " not blocked in signal mask: " << s
    75                << std::endl;
    76      return 1;
    77    }
    78    return 0;
    79  }
    80  
    81  // Verify that the itimer is enabled.
    82  int CheckItimerEnabled(uint32_t timer) {
    83    struct itimerval itv;
    84    int ret = getitimer(timer, &itv);
    85    if (ret < 0) {
    86      perror("getitimer");
    87      return 1;
    88    }
    89  
    90    if (!itv.it_value.tv_sec && !itv.it_value.tv_usec &&
    91        !itv.it_interval.tv_sec && !itv.it_interval.tv_usec) {
    92      std::cerr << "timer " << timer
    93                << " not enabled. value sec: " << itv.it_value.tv_sec
    94                << " usec: " << itv.it_value.tv_usec
    95                << " interval sec: " << itv.it_interval.tv_sec
    96                << " usec: " << itv.it_interval.tv_usec << std::endl;
    97      return 1;
    98    }
    99    return 0;
   100  }
   101  
   102  int PrintExecFn() {
   103    unsigned long execfn = getauxval(AT_EXECFN);
   104    if (!execfn) {
   105      std::cerr << "AT_EXECFN missing" << std::endl;
   106      return 1;
   107    }
   108  
   109    std::cerr << reinterpret_cast<const char*>(execfn) << std::endl;
   110    return 0;
   111  }
   112  
   113  int PrintExecName() {
   114    const size_t name_length = 20;
   115    char name[name_length] = {0};
   116    if (prctl(PR_GET_NAME, name) < 0) {
   117      std::cerr << "prctl(PR_GET_NAME) failed" << std::endl;
   118      return 1;
   119    }
   120  
   121    std::cerr << name << std::endl;
   122    return 0;
   123  }
   124  
   125  void usage(const std::string& prog) {
   126    std::cerr << "usage:\n"
   127              << "\t" << prog << " CheckSigHandler <signo> <handler addr (hex)>\n"
   128              << "\t" << prog << " CheckSigBlocked <signo>\n"
   129              << "\t" << prog << " CheckTimerDisabled <timer>\n"
   130              << "\t" << prog << " PrintExecFn\n"
   131              << "\t" << prog << " PrintExecName" << std::endl;
   132  }
   133  
   134  int main(int argc, char** argv) {
   135    if (argc < 2) {
   136      usage(argv[0]);
   137      return 1;
   138    }
   139  
   140    std::string func(argv[1]);
   141  
   142    if (func == "CheckSigHandler") {
   143      if (argc != 4) {
   144        usage(argv[0]);
   145        return 1;
   146      }
   147  
   148      uint32_t signo;
   149      if (!absl::SimpleAtoi(argv[2], &signo)) {
   150        std::cerr << "invalid signo: " << argv[2] << std::endl;
   151        return 1;
   152      }
   153  
   154      uintptr_t handler;
   155      if (!absl::numbers_internal::safe_strtoi_base(argv[3], &handler, 16)) {
   156        std::cerr << "invalid handler: " << std::hex << argv[3] << std::endl;
   157        return 1;
   158      }
   159  
   160      return CheckSigHandler(signo, handler);
   161    }
   162  
   163    if (func == "CheckSigBlocked") {
   164      if (argc != 3) {
   165        usage(argv[0]);
   166        return 1;
   167      }
   168  
   169      uint32_t signo;
   170      if (!absl::SimpleAtoi(argv[2], &signo)) {
   171        std::cerr << "invalid signo: " << argv[2] << std::endl;
   172        return 1;
   173      }
   174  
   175      return CheckSigBlocked(signo);
   176    }
   177  
   178    if (func == "CheckItimerEnabled") {
   179      if (argc != 3) {
   180        usage(argv[0]);
   181        return 1;
   182      }
   183  
   184      uint32_t timer;
   185      if (!absl::SimpleAtoi(argv[2], &timer)) {
   186        std::cerr << "invalid signo: " << argv[2] << std::endl;
   187        return 1;
   188      }
   189  
   190      return CheckItimerEnabled(timer);
   191    }
   192  
   193    if (func == "PrintExecFn") {
   194      // N.B. This will be called as an interpreter script, with the script passed
   195      // as the third argument. We don't care about that script.
   196      return PrintExecFn();
   197    }
   198  
   199    if (func == "PrintExecName") {
   200      // N.B. This may be called as an interpreter script like PrintExecFn.
   201      return PrintExecName();
   202    }
   203  
   204    std::cerr << "Invalid function: " << func << std::endl;
   205    return 1;
   206  }