NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
app_shield_agent.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <assert.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include <doca_apsh.h>
34 #include <doca_argp.h>
35 #include <doca_log.h>
37 
38 #include "app_shield_agent_core.h"
39 
41 
42 /*
43  * APSH agent application main function
44  *
45  * @argc [in]: command line arguments size
46  * @argv [in]: array of command line arguments
47  * @return: EXIT_SUCCESS on success and EXIT_FAILURE otherwise
48  */
49 int main(int argc, char **argv)
50 {
52  int exit_status = EXIT_SUCCESS;
53  struct doca_apsh_process **processes;
54  struct doca_apsh_process *process = NULL;
55  struct doca_apsh_attestation **attestation;
56  int att_failure = 0, att_count;
58  struct apsh_config apsh_conf;
59  int runtime_file_ind;
60  struct event_indexes indexes;
61  struct attestation_event attest_event;
62  struct doca_telemetry_exporter_schema *telemetry_schema;
63  struct doca_telemetry_exporter_source *telemetry_source;
64  const char *process_path;
65  bool telemetry_enabled;
67  struct doca_log_backend *sdk_log;
68 
69  /* Register a logger backend */
71  if (result != DOCA_SUCCESS)
72  return EXIT_FAILURE;
73 
74  /* Register a logger backend for internal SDK errors and warnings */
76  if (result != DOCA_SUCCESS)
77  return EXIT_FAILURE;
79  if (result != DOCA_SUCCESS)
80  return EXIT_FAILURE;
81 
82  /* Parse cmdline/json arguments */
83  result = doca_argp_init(NULL, &apsh_conf);
84  if (result != DOCA_SUCCESS) {
85  DOCA_LOG_ERR("Failed to init ARGP resources: %s", doca_error_get_descr(result));
86  return EXIT_FAILURE;
87  }
89  if (result != DOCA_SUCCESS) {
90  DOCA_LOG_ERR("Failed to parse application input: %s", doca_error_get_descr(result));
92  return EXIT_FAILURE;
93  }
94  result = doca_argp_start(argc, argv);
95  if (result != DOCA_SUCCESS) {
96  DOCA_LOG_ERR("Failed to parse application input: %s", doca_error_get_descr(result));
98  return EXIT_FAILURE;
99  }
100 
101  /* Init the app shield agent app */
102  result = app_shield_agent_init(&apsh_conf, &resources);
103  if (result != DOCA_SUCCESS) {
104  DOCA_LOG_ERR("Failed to init application: %s", doca_error_get_descr(result));
106  return EXIT_FAILURE;
107  }
108 
109  /* Get process with 'pid' */
110  result = get_process_by_pid(&resources, &apsh_conf, &processes, &process);
111  if (result != DOCA_SUCCESS) {
112  DOCA_LOG_ERR("Apsh init was successful but failed to read process %d information: %s",
113  apsh_conf.pid,
115  exit_status = EXIT_FAILURE;
116  goto apsh_cleanup;
117  }
118 
119  /* Creating telemetry schema */
120  telemetry_enabled = (telemetry_start(&telemetry_schema, &telemetry_source, &indexes) == DOCA_SUCCESS);
121 
122  /* Set const values of the telemetry data */
123  attest_event.pid = apsh_conf.pid;
124  attest_event.scan_count = 0;
125  process_path = doca_apsh_process_info_get(process, DOCA_APSH_PROCESS_COMM);
126  assert(process_path != NULL); /* Should never happen, but will catch this error here instead of in strncpy */
127  /* Copy string & pad with '\0' until MAX_PATH_LEN bytes were written. this clean the telemetry message */
128  strncpy(attest_event.path, process_path, MAX_PATH_LEN);
129  attest_event.path[MAX_PATH_LEN] = '\0';
130 
131  /* Get attestation */
132  result = doca_apsh_attestation_get(process, apsh_conf.exec_hash_map_path, &attestation, &att_count);
133  if (result != DOCA_SUCCESS) {
134  DOCA_LOG_ERR("Attestation init failed: %s", doca_error_get_descr(result));
135  exit_status = EXIT_FAILURE;
136  goto telemetry_cleanup;
137  }
138 
139  /* Start attestation on loop with time_interval */
140  DOCA_LOG_INFO("Start attestation on pid=%d", apsh_conf.pid);
141  do {
142  /* Refresh attestation */
143  result = doca_apsh_attst_refresh(&attestation, &att_count);
144  if (result != DOCA_SUCCESS) {
145  DOCA_LOG_ERR("Failed to create a new attestation, error code: %d", result);
146  att_failure = true;
147  }
148 
149  /* Check attestation */
150  for (runtime_file_ind = 0; runtime_file_ind < att_count && !att_failure; runtime_file_ind++) {
151  att_failure = doca_apsh_attst_info_get(attestation[runtime_file_ind],
153  doca_apsh_attst_info_get(attestation[runtime_file_ind],
155  }
156 
157  /* Send telemetry data */
158  if (telemetry_enabled) {
160  if (result != DOCA_SUCCESS)
161  DOCA_LOG_ERR("Failed to get timestamp, error code: %d", result);
162  attest_event.timestamp = timestamp;
163  attest_event.result = att_failure;
164  if (doca_telemetry_exporter_source_report(telemetry_source,
165  indexes.attest_index,
166  &attest_event,
167  1) != DOCA_SUCCESS)
168  DOCA_LOG_ERR("Cannot report to telemetry");
169  ++attest_event.scan_count;
170  }
171 
172  /* Check attestation attempt status */
173  if (att_failure) {
174  DOCA_LOG_INFO("Attestation failed");
175  exit_status = EXIT_FAILURE;
176  break;
177  }
178  DOCA_LOG_INFO("Attestation pass");
179  sleep(apsh_conf.time_interval);
180  } while (true);
181 
182  /* Destroy */
183  doca_apsh_attestation_free(attestation);
184 telemetry_cleanup:
185  if (telemetry_enabled)
186  telemetry_destroy(telemetry_schema, telemetry_source);
187  doca_apsh_processes_free(processes);
188 apsh_cleanup:
191 
192  return exit_status;
193 }
#define NULL
Definition: __stddef_null.h:26
DOCA_LOG_REGISTER(APSH_APP)
int main(int argc, char **argv)
doca_error_t get_process_by_pid(struct apsh_resources *resources, struct apsh_config *apsh_conf, struct doca_apsh_process ***pslist, struct doca_apsh_process **process)
doca_error_t app_shield_agent_init(struct apsh_config *conf, struct apsh_resources *resources)
doca_error_t telemetry_start(struct doca_telemetry_exporter_schema **telemetry_schema, struct doca_telemetry_exporter_source **telemetry_source, struct event_indexes *indexes)
void app_shield_agent_cleanup(struct apsh_resources *resources)
doca_error_t register_apsh_params(void)
void telemetry_destroy(struct doca_telemetry_exporter_schema *telemetry_schema, struct doca_telemetry_exporter_source *telemetry_source)
doca_telemetry_exporter_timestamp_t timestamp
int32_t result
#define MAX_PATH_LEN
struct rdma_resources resources
@ DOCA_APSH_ATTESTATION_PAGES_PRESENT
@ DOCA_APSH_ATTESTATION_MATCHING_HASHES
@ DOCA_APSH_PROCESS_COMM
DOCA_EXPERIMENTAL void doca_apsh_attestation_free(struct doca_apsh_attestation **attestation)
Destroys a attestation context.
DOCA_EXPERIMENTAL doca_error_t doca_apsh_attestation_get(struct doca_apsh_process *process, const char *exec_hash_map_path, struct doca_apsh_attestation ***attestation, int *attestation_size)
Get current process attestation.
#define doca_apsh_process_info_get(process, attr)
Get attribute value for a process.
Definition: doca_apsh.h:618
DOCA_EXPERIMENTAL void doca_apsh_processes_free(struct doca_apsh_process **processes)
Destroys a process context.
#define doca_apsh_attst_info_get(attestation, attr)
Get attribute value for a attestation.
Definition: doca_apsh.h:884
DOCA_EXPERIMENTAL doca_error_t doca_apsh_attst_refresh(struct doca_apsh_attestation ***attestation, int *attestation_size)
refresh single attestation handler of a process with new snapshot
DOCA_EXPERIMENTAL doca_error_t doca_argp_start(int argc, char **argv)
Parse incoming arguments (cmd line/json).
DOCA_EXPERIMENTAL doca_error_t doca_argp_init(const char *program_name, void *program_config)
Initialize the parser interface.
DOCA_EXPERIMENTAL doca_error_t doca_argp_destroy(void)
ARG Parser destroy.
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_SUCCESS
Definition: doca_error.h:38
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_create_standard(void)
Create default, non configurable backend for application messages.
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_create_with_file_sdk(FILE *fptr, struct doca_log_backend **backend)
Create a logging backend with a FILE* stream for SDK messages.
DOCA_EXPERIMENTAL doca_error_t doca_log_backend_set_sdk_level(struct doca_log_backend *backend, uint32_t level)
Set the log level limit for SDK logging backends.
@ DOCA_LOG_LEVEL_WARNING
Definition: doca_log.h:47
uint64_t doca_telemetry_exporter_timestamp_t
DOCA schema type index type.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_get_timestamp(doca_telemetry_exporter_timestamp_t *timestamp)
Get timestamp in the proper format.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_source_report(struct doca_telemetry_exporter_source *doca_source, doca_telemetry_exporter_type_index_t index, void *data, int count)
Report events data of the same type via DOCA source.
char exec_hash_map_path[MAX_PATH_LEN]
DOCA_APSH_PROCESS_PID_TYPE pid
doca_telemetry_exporter_timestamp_t timestamp
char path[MAX_PATH_LEN+1]
doca_telemetry_exporter_type_index_t attest_index