0001
0002
0003
0004
0005
0006
0007
0008 #include "target.h"
0009
0010 #include <pwd.h>
0011 #include <stdio.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <linux/kernel.h>
0015 #include <linux/string.h>
0016
0017 enum target_errno target__validate(struct target *target)
0018 {
0019 enum target_errno ret = TARGET_ERRNO__SUCCESS;
0020
0021 if (target->pid)
0022 target->tid = target->pid;
0023
0024
0025 if (target->tid && target->cpu_list) {
0026 target->cpu_list = NULL;
0027 if (ret == TARGET_ERRNO__SUCCESS)
0028 ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
0029 }
0030
0031
0032 if (target->tid && target->uid_str) {
0033 target->uid_str = NULL;
0034 if (ret == TARGET_ERRNO__SUCCESS)
0035 ret = TARGET_ERRNO__PID_OVERRIDE_UID;
0036 }
0037
0038
0039 if (target->uid_str && target->cpu_list) {
0040 target->cpu_list = NULL;
0041 if (ret == TARGET_ERRNO__SUCCESS)
0042 ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
0043 }
0044
0045
0046 if (target->tid && target->system_wide) {
0047 target->system_wide = false;
0048 if (ret == TARGET_ERRNO__SUCCESS)
0049 ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
0050 }
0051
0052
0053 if (target->uid_str && target->system_wide) {
0054 target->system_wide = false;
0055 if (ret == TARGET_ERRNO__SUCCESS)
0056 ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
0057 }
0058
0059
0060 if (target->bpf_str && target->cpu_list) {
0061 target->cpu_list = NULL;
0062 if (ret == TARGET_ERRNO__SUCCESS)
0063 ret = TARGET_ERRNO__BPF_OVERRIDE_CPU;
0064 }
0065
0066
0067 if (target->bpf_str && target->tid) {
0068 target->tid = NULL;
0069 if (ret == TARGET_ERRNO__SUCCESS)
0070 ret = TARGET_ERRNO__BPF_OVERRIDE_PID;
0071 }
0072
0073
0074 if (target->bpf_str && target->uid_str) {
0075 target->uid_str = NULL;
0076 if (ret == TARGET_ERRNO__SUCCESS)
0077 ret = TARGET_ERRNO__BPF_OVERRIDE_UID;
0078 }
0079
0080
0081 if (target->bpf_str && target->per_thread) {
0082 target->per_thread = false;
0083 if (ret == TARGET_ERRNO__SUCCESS)
0084 ret = TARGET_ERRNO__BPF_OVERRIDE_THREAD;
0085 }
0086
0087
0088 if (target->per_thread && (target->system_wide || target->cpu_list)) {
0089 target->per_thread = false;
0090 if (ret == TARGET_ERRNO__SUCCESS)
0091 ret = TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD;
0092 }
0093
0094 return ret;
0095 }
0096
0097 enum target_errno target__parse_uid(struct target *target)
0098 {
0099 struct passwd pwd, *result;
0100 char buf[1024];
0101 const char *str = target->uid_str;
0102
0103 target->uid = UINT_MAX;
0104 if (str == NULL)
0105 return TARGET_ERRNO__SUCCESS;
0106
0107
0108 getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
0109
0110 if (result == NULL) {
0111
0112
0113
0114 char *endptr;
0115 int uid = strtol(str, &endptr, 10);
0116
0117 if (*endptr != '\0')
0118 return TARGET_ERRNO__INVALID_UID;
0119
0120 getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
0121
0122 if (result == NULL)
0123 return TARGET_ERRNO__USER_NOT_FOUND;
0124 }
0125
0126 target->uid = result->pw_uid;
0127 return TARGET_ERRNO__SUCCESS;
0128 }
0129
0130
0131
0132
0133 static const char *target__error_str[] = {
0134 "PID/TID switch overriding CPU",
0135 "PID/TID switch overriding UID",
0136 "UID switch overriding CPU",
0137 "PID/TID switch overriding SYSTEM",
0138 "UID switch overriding SYSTEM",
0139 "SYSTEM/CPU switch overriding PER-THREAD",
0140 "BPF switch overriding CPU",
0141 "BPF switch overriding PID/TID",
0142 "BPF switch overriding UID",
0143 "BPF switch overriding THREAD",
0144 "Invalid User: %s",
0145 "Problems obtaining information for user %s",
0146 };
0147
0148 int target__strerror(struct target *target, int errnum,
0149 char *buf, size_t buflen)
0150 {
0151 int idx;
0152 const char *msg;
0153
0154 BUG_ON(buflen == 0);
0155
0156 if (errnum >= 0) {
0157 str_error_r(errnum, buf, buflen);
0158 return 0;
0159 }
0160
0161 if (errnum < __TARGET_ERRNO__START || errnum >= __TARGET_ERRNO__END)
0162 return -1;
0163
0164 idx = errnum - __TARGET_ERRNO__START;
0165 msg = target__error_str[idx];
0166
0167 switch (errnum) {
0168 case TARGET_ERRNO__PID_OVERRIDE_CPU ...
0169 TARGET_ERRNO__BPF_OVERRIDE_THREAD:
0170 snprintf(buf, buflen, "%s", msg);
0171 break;
0172
0173 case TARGET_ERRNO__INVALID_UID:
0174 case TARGET_ERRNO__USER_NOT_FOUND:
0175 snprintf(buf, buflen, msg, target->uid_str);
0176 break;
0177
0178 default:
0179
0180 break;
0181 }
0182
0183 return 0;
0184 }