Line data Source code
1 : #define _GNU_SOURCE
2 : #include "../tiles.h"
3 :
4 : #include "generated/fd_sign_tile_seccomp.h"
5 :
6 : #include "../keyguard/fd_keyguard.h"
7 : #include "../keyguard/fd_keyload.h"
8 : #include "../keyguard/fd_keyswitch.h"
9 : #include "../../ballet/base58/fd_base58.h"
10 : #include "../metrics/fd_metrics.h"
11 :
12 : #include "../../util/hist/fd_histf.h"
13 :
14 : #include <errno.h>
15 : #include <sys/mman.h>
16 :
17 0 : #define MAX_IN (32UL)
18 :
19 : /* fd_sign_in_ctx_t is a context object for each in (producer) mcache
20 : connected to the sign tile. */
21 :
22 : struct fd_sign_out_ctx {
23 : fd_wksp_t * out_mem;
24 : ulong out_chunk0;
25 : ulong out_wmark;
26 : ulong out_chunk;
27 : };
28 : typedef struct fd_sign_out_ctx fd_sign_out_ctx_t;
29 :
30 : struct fd_sign_in_ctx {
31 : int role;
32 : fd_wksp_t * mem;
33 : ulong chunk0;
34 : ulong wmark;
35 : ulong mtu;
36 : };
37 : typedef struct fd_sign_in_ctx fd_sign_in_ctx_t;
38 :
39 : typedef struct {
40 : uchar _data[ FD_KEYGUARD_SIGN_REQ_MTU ];
41 :
42 : /* Pre-staged with the public key base58 encoded, followed by "-" in the first bytes */
43 : ulong public_key_base58_sz;
44 : uchar concat[ FD_BASE58_ENCODED_32_SZ+1UL+9UL ];
45 :
46 : fd_sign_in_ctx_t in[ MAX_IN ];
47 : fd_sign_out_ctx_t out[ MAX_IN ];
48 :
49 : fd_sha512_t sha512 [ 1 ];
50 :
51 : fd_keyswitch_t * keyswitch;
52 :
53 : fd_keyswitch_t * av_keyswitch; /* authorized voters */
54 :
55 : uchar * public_key;
56 : uchar * private_key;
57 :
58 : ulong authorized_voters_cnt;
59 : uchar authorized_voter_pubkeys[ 16UL ][ 32UL ];
60 : uchar authorized_voter_private_keys[ 16UL ][ 32UL ];
61 :
62 : fd_histf_t sign_duration[1];
63 : } fd_sign_ctx_t;
64 :
65 : FD_FN_CONST static inline ulong
66 0 : scratch_align( void ) {
67 0 : return alignof( fd_sign_ctx_t );
68 0 : }
69 :
70 : FD_FN_PURE static inline ulong
71 0 : scratch_footprint( fd_topo_tile_t const * tile ) {
72 0 : (void)tile;
73 0 : ulong l = FD_LAYOUT_INIT;
74 0 : l = FD_LAYOUT_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
75 0 : return FD_LAYOUT_FINI( l, scratch_align() );
76 0 : }
77 :
78 : static void FD_FN_SENSITIVE
79 0 : derive_fields( fd_sign_ctx_t * ctx ) {
80 0 : uchar check_public_key[ 32 ];
81 0 : fd_ed25519_public_from_private( check_public_key, ctx->private_key, ctx->sha512 );
82 0 : if( FD_UNLIKELY( memcmp( check_public_key, ctx->public_key, 32UL ) ) )
83 0 : FD_LOG_EMERG(( "The public key in the identity key file does not match the public key derived from the private key. "
84 0 : "Firedancer will not use the key pair to sign as it might leak the private key." ));
85 :
86 0 : fd_base58_encode_32( ctx->public_key, &ctx->public_key_base58_sz, (char *)ctx->concat );
87 0 : ctx->concat[ ctx->public_key_base58_sz ] = '-';
88 0 : }
89 :
90 : static void FD_FN_SENSITIVE
91 0 : during_housekeeping_sensitive( fd_sign_ctx_t * ctx ) {
92 0 : if( FD_UNLIKELY( fd_keyswitch_state_query( ctx->keyswitch )==FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
93 0 : memcpy( ctx->private_key, ctx->keyswitch->bytes, 32UL );
94 0 : fd_memzero_explicit( ctx->keyswitch->bytes, 32UL );
95 0 : FD_COMPILER_MFENCE();
96 0 : memcpy( ctx->public_key, ctx->keyswitch->bytes+32UL, 32UL );
97 :
98 0 : derive_fields( ctx );
99 0 : fd_keyswitch_state( ctx->keyswitch, FD_KEYSWITCH_STATE_COMPLETED );
100 0 : }
101 :
102 : /* firedancer only */
103 :
104 0 : if( FD_UNLIKELY( ctx->av_keyswitch && fd_keyswitch_state_query( ctx->av_keyswitch )==FD_KEYSWITCH_STATE_SWITCH_PENDING ) ) {
105 0 : if( FD_UNLIKELY( ctx->authorized_voters_cnt==16UL ) ) {
106 0 : FD_LOG_WARNING(( "keyswitch failed: maximum number of authorized voters reached" ));
107 0 : fd_memzero_explicit( ctx->av_keyswitch->bytes, 64UL );
108 0 : fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_FAILED );
109 0 : return;
110 0 : }
111 0 : for( ulong i=0UL; i<ctx->authorized_voters_cnt; i++ ) {
112 0 : if( FD_UNLIKELY( !memcmp( ctx->authorized_voter_pubkeys[ i ], ctx->av_keyswitch->bytes+32UL, 32UL ) ) ) {
113 0 : FD_BASE58_ENCODE_32_BYTES( ctx->authorized_voter_pubkeys[ i ], pubkey_b58 );
114 0 : FD_LOG_WARNING(( "keyswitch failed: authorized voter key duplicate (%s)", pubkey_b58 ));
115 0 : fd_memzero_explicit( ctx->av_keyswitch->bytes, 64UL );
116 0 : fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_FAILED );
117 0 : return;
118 0 : }
119 0 : }
120 :
121 0 : memcpy( ctx->authorized_voter_private_keys[ ctx->authorized_voters_cnt ], ctx->av_keyswitch->bytes, 32UL );
122 0 : fd_memzero_explicit( ctx->av_keyswitch->bytes, 32UL );
123 0 : FD_COMPILER_MFENCE();
124 0 : memcpy( ctx->authorized_voter_pubkeys[ ctx->authorized_voters_cnt ], ctx->av_keyswitch->bytes + 32UL, 32UL );
125 0 : ctx->authorized_voters_cnt++;
126 0 : fd_keyswitch_state( ctx->av_keyswitch, FD_KEYSWITCH_STATE_COMPLETED );
127 0 : }
128 0 : }
129 :
130 : static inline void
131 0 : during_housekeeping( fd_sign_ctx_t * ctx ) {
132 0 : during_housekeeping_sensitive( ctx );
133 0 : }
134 :
135 : static inline void
136 0 : metrics_write( fd_sign_ctx_t * ctx ) {
137 0 : FD_MHIST_COPY( SIGN, SIGN_DURATION_SECONDS, ctx->sign_duration );
138 0 : }
139 :
140 : /* during_frag is called between pairs for sequence number checks, as
141 : we are reading incoming frags. We don't actually need to copy the
142 : fragment here, see fd_dedup.c for why we do this.*/
143 :
144 : static void FD_FN_SENSITIVE
145 : during_frag_sensitive( void * _ctx,
146 : ulong in_idx,
147 : ulong seq,
148 : ulong sig,
149 : ulong chunk,
150 0 : ulong sz ) {
151 0 : (void)seq;
152 0 : (void)sig;
153 :
154 0 : fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
155 0 : FD_TEST( in_idx<MAX_IN );
156 :
157 0 : int role = ctx->in[ in_idx ].role;
158 0 : ulong mtu = ctx->in[ in_idx ].mtu;
159 :
160 0 : if( chunk<ctx->in[ in_idx ].chunk0 || chunk>ctx->in[ in_idx ].wmark || sz>mtu ) {
161 0 : FD_LOG_EMERG(( "oversz or out of bounds signing request (role=%d chunk=%lu sz=%lu mtu=%lu, chunk0=%lu, wmark=%lu)", role, chunk, sz, mtu, ctx->in[ in_idx ].chunk0, ctx->in[ in_idx ].wmark ));
162 0 : }
163 :
164 0 : void * src = fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk );
165 0 : fd_memcpy( ctx->_data, src, sz );
166 0 : }
167 :
168 :
169 : static void
170 : during_frag( void * _ctx,
171 : ulong in_idx,
172 : ulong seq,
173 : ulong sig,
174 : ulong chunk,
175 : ulong sz,
176 0 : ulong ctl FD_PARAM_UNUSED ) {
177 0 : during_frag_sensitive( _ctx, in_idx, seq, sig, chunk, sz );
178 0 : }
179 :
180 : static void FD_FN_SENSITIVE
181 : after_frag_sensitive( void * _ctx,
182 : ulong in_idx,
183 : ulong seq,
184 : ulong sig,
185 : ulong sz,
186 : ulong tsorig,
187 : ulong tspub,
188 0 : fd_stem_context_t * stem ) {
189 0 : (void)seq;
190 0 : (void)tspub;
191 :
192 0 : fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
193 :
194 : /* The lower 32 bits are used to specify the sign type.
195 :
196 : If the frag is coming from the repair tile, then the upper 32 bits
197 : contain the repair tile nonce to identify the request.
198 :
199 : If the frag is coming from the send tile, then the upper 32 bits
200 : contain the index of the authorized voter that needs to sign the
201 : vote transaction. The least significant bit of the upper 32 is
202 : used to indicate if a second signature is needed. The next 4 least
203 : significant bits are used to encode the index of the authorized
204 : voter that a signature is needed from. */
205 0 : int sign_type = (int)(uint)(sig);
206 0 : int needs_second_sign = ctx->in[ in_idx ].role==FD_KEYGUARD_ROLE_TXSEND && ((sig>>32) & 1UL);
207 :
208 0 : FD_TEST( in_idx<MAX_IN );
209 :
210 0 : int role = ctx->in[ in_idx ].role;
211 :
212 0 : fd_keyguard_authority_t authority = {0};
213 0 : memcpy( authority.identity_pubkey, ctx->public_key, 32 );
214 :
215 0 : if( FD_UNLIKELY( !fd_keyguard_payload_authorize( &authority, ctx->_data, sz, role, sign_type ) ) ) {
216 0 : FD_LOG_EMERG(( "fd_keyguard_payload_authorize failed (role=%d sign_type=%d)", role, sign_type ));
217 0 : }
218 :
219 0 : long sign_duration = -fd_tickcount();
220 :
221 0 : uchar * dst = fd_chunk_to_laddr( ctx->out[ in_idx ].out_mem, ctx->out[ in_idx ].out_chunk );
222 :
223 0 : switch( sign_type ) {
224 0 : case FD_KEYGUARD_SIGN_TYPE_ED25519: {
225 0 : fd_ed25519_sign( dst, ctx->_data, sz, ctx->public_key, ctx->private_key, ctx->sha512 );
226 0 : if( needs_second_sign ) {
227 0 : ulong authority_idx = (sig >> 33) & 0xFUL;
228 0 : if( FD_UNLIKELY( authority_idx>=ctx->authorized_voters_cnt ) )
229 0 : FD_LOG_CRIT(( "invalid sign request from in_idx=%lu: authority_idx=%lu out of range (authorized_voters_cnt=%lu)", in_idx, authority_idx, ctx->authorized_voters_cnt ));
230 0 : fd_ed25519_sign( dst+64UL, ctx->_data, sz, ctx->authorized_voter_pubkeys[ authority_idx ], ctx->authorized_voter_private_keys[ authority_idx ], ctx->sha512 );
231 0 : }
232 0 : break;
233 0 : }
234 0 : case FD_KEYGUARD_SIGN_TYPE_SHA256_ED25519: {
235 0 : uchar hash[ 32 ];
236 0 : fd_sha256_hash( ctx->_data, sz, hash );
237 0 : fd_ed25519_sign( dst, hash, 32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
238 0 : break;
239 0 : }
240 0 : case FD_KEYGUARD_SIGN_TYPE_PUBKEY_CONCAT_ED25519: {
241 0 : memcpy( ctx->concat+ctx->public_key_base58_sz+1UL, ctx->_data, 9UL );
242 0 : fd_ed25519_sign( dst, ctx->concat, ctx->public_key_base58_sz+1UL+9UL, ctx->public_key, ctx->private_key, ctx->sha512 );
243 0 : break;
244 0 : }
245 0 : default:
246 0 : FD_LOG_EMERG(( "invalid sign type: %d", sign_type ));
247 0 : }
248 :
249 0 : sign_duration += fd_tickcount();
250 0 : fd_histf_sample( ctx->sign_duration, (ulong)sign_duration );
251 :
252 0 : ulong out_sz = fd_ulong_if( (sign_type==FD_KEYGUARD_SIGN_TYPE_ED25519) && needs_second_sign, 128UL, 64UL );
253 0 : fd_stem_publish( stem, in_idx, sig, ctx->out[ in_idx ].out_chunk, out_sz, 0UL, tsorig, 0UL );
254 0 : ctx->out[ in_idx ].out_chunk = fd_dcache_compact_next( ctx->out[ in_idx ].out_chunk, out_sz, ctx->out[ in_idx ].out_chunk0, ctx->out[ in_idx ].out_wmark );
255 0 : }
256 :
257 : static void
258 : after_frag( void * _ctx,
259 : ulong in_idx,
260 : ulong seq,
261 : ulong sig,
262 : ulong sz,
263 : ulong tsorig,
264 : ulong tspub,
265 0 : fd_stem_context_t * stem ) {
266 0 : after_frag_sensitive( _ctx, in_idx, seq, sig, sz, tsorig, tspub, stem );
267 0 : }
268 :
269 : static void FD_FN_SENSITIVE
270 : privileged_init_sensitive( fd_topo_t const * topo,
271 0 : fd_topo_tile_t const * tile ) {
272 0 : void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
273 0 : FD_SCRATCH_ALLOC_INIT( l, scratch );
274 0 : fd_sign_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
275 :
276 0 : uchar * identity_key = fd_keyload_mprotect_wr( fd_keyload_load( tile->sign.identity_key_path, /* pubkey only: */ 0 ), /* public_key_only: */ 0 );
277 0 : ctx->private_key = identity_key;
278 0 : ctx->public_key = identity_key + 32UL;
279 :
280 0 : ctx->authorized_voters_cnt = tile->sign.authorized_voter_paths_cnt;
281 0 : for( ulong i=0UL; i<tile->sign.authorized_voter_paths_cnt; i++ ) {
282 0 : uchar const * authorized_voter_key = fd_keyload_load( tile->sign.authorized_voter_paths[ i ], /* pubkey only: */ 0 );
283 0 : memcpy( ctx->authorized_voter_private_keys[ i ], authorized_voter_key, 32UL );
284 0 : memcpy( ctx->authorized_voter_pubkeys[ i ], authorized_voter_key + 32UL, 32UL );
285 0 : }
286 :
287 : /* The stack can be taken over and reorganized by under AddressSanitizer,
288 : which causes this code to fail. */
289 : #if FD_HAS_ASAN
290 : FD_LOG_WARNING(( "!!! SECURITY WARNING !!! YOU ARE RUNNING THE SIGNING TILE "
291 : "WITH ADDRESS SANITIZER ENABLED. THIS CAN LEAK SENSITIVE "
292 : "DATA INCLUDING YOUR PRIVATE KEYS INTO CORE DUMPS IF THIS "
293 : "PROCESS ABORTS. IT IS HIGHLY ADVISED TO NOT TO RUN IN THIS "
294 : "MODE IN PRODUCTION!" ));
295 : #else
296 : /* Prevent the stack from showing up in core dumps just in case the
297 : private key somehow ends up in there. */
298 0 : FD_TEST( fd_tile_stack0() );
299 0 : FD_TEST( fd_tile_stack_sz() );
300 0 : if( FD_UNLIKELY( madvise( (void*)fd_tile_stack0(), fd_tile_stack_sz(), MADV_DONTDUMP ) ) )
301 0 : FD_LOG_ERR(( "madvise failed (%i-%s)", errno, fd_io_strerror( errno ) ));
302 0 : #endif
303 0 : }
304 :
305 : static void
306 : privileged_init( fd_topo_t const * topo,
307 0 : fd_topo_tile_t const * tile ) {
308 0 : privileged_init_sensitive( topo, tile );
309 0 : }
310 :
311 : static void FD_FN_SENSITIVE
312 : unprivileged_init_sensitive( fd_topo_t const * topo,
313 0 : fd_topo_tile_t const * tile ) {
314 0 : void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id );
315 :
316 0 : FD_SCRATCH_ALLOC_INIT( l, scratch );
317 0 : fd_sign_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_sign_ctx_t ), sizeof( fd_sign_ctx_t ) );
318 0 : FD_TEST( fd_sha512_join( fd_sha512_new( ctx->sha512 ) ) );
319 :
320 0 : FD_TEST( tile->in_cnt<=MAX_IN );
321 0 : FD_TEST( tile->in_cnt==tile->out_cnt );
322 :
323 0 : fd_histf_join( fd_histf_new( ctx->sign_duration, FD_MHIST_SECONDS_MIN( SIGN, SIGN_DURATION_SECONDS ),
324 0 : FD_MHIST_SECONDS_MAX( SIGN, SIGN_DURATION_SECONDS ) ) );
325 :
326 0 : ctx->keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->id_keyswitch_obj_id ) );
327 0 : derive_fields( ctx );
328 :
329 0 : if( FD_LIKELY( tile->av_keyswitch_obj_id!=ULONG_MAX ) ) {
330 0 : ctx->av_keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->av_keyswitch_obj_id ) );
331 0 : FD_TEST( ctx->av_keyswitch );
332 0 : } else {
333 0 : ctx->av_keyswitch = NULL;
334 0 : }
335 :
336 0 : for( ulong i=0UL; i<MAX_IN; i++ ) ctx->in[ i ].role = -1;
337 :
338 0 : for( ulong i=0UL; i<tile->in_cnt; i++ ) {
339 0 : fd_topo_link_t const * in_link = &topo->links[ tile->in_link_id[ i ] ];
340 0 : fd_topo_link_t const * out_link = &topo->links[ tile->out_link_id[ i ] ];
341 :
342 0 : if( in_link->mtu > FD_KEYGUARD_SIGN_REQ_MTU ) FD_LOG_CRIT(( "oversz link[%lu].mtu=%lu", i, in_link->mtu ));
343 0 : ctx->in[ i ].mem = fd_wksp_containing( in_link->dcache );
344 0 : ctx->in[ i ].mtu = in_link->mtu;
345 0 : ctx->in[ i ].chunk0 = fd_dcache_compact_chunk0( ctx->in[ i ].mem, in_link->dcache );
346 0 : ctx->in[ i ].wmark = fd_dcache_compact_wmark( ctx->in[ i ].mem, in_link->dcache, in_link->mtu );
347 :
348 0 : ctx->out[ i ].out_mem = fd_wksp_containing( out_link->dcache );
349 0 : ctx->out[ i ].out_chunk0 = fd_dcache_compact_chunk0( ctx->out[ i ].out_mem, out_link->dcache );
350 0 : ctx->out[ i ].out_wmark = fd_dcache_compact_wmark( ctx->out[ i ].out_mem, out_link->dcache, 64UL );
351 0 : ctx->out[ i ].out_chunk = ctx->out[ i ].out_chunk0;
352 :
353 0 : if( !strcmp( in_link->name, "shred_sign" ) ) {
354 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_LEADER;
355 0 : FD_TEST( !strcmp( out_link->name, "sign_shred" ) );
356 0 : FD_TEST( in_link->mtu==32UL );
357 0 : FD_TEST( out_link->mtu==64UL );
358 0 : } else if ( !strcmp( in_link->name, "gossip_sign" ) ) {
359 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_GOSSIP;
360 0 : FD_TEST( !strcmp( out_link->name, "sign_gossip" ) );
361 0 : FD_TEST( in_link->mtu==2048UL );
362 0 : FD_TEST( out_link->mtu==64UL );
363 0 : } else if ( !strcmp( in_link->name, "repair_sign" ) ) {
364 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_REPAIR;
365 0 : FD_TEST( !strcmp( out_link->name, "sign_repair" ) );
366 0 : FD_TEST( in_link->mtu==96UL ); // FD_REPAIR_MAX_PREIMAGE_SZ
367 0 : FD_TEST( out_link->mtu==64UL );
368 0 : } else if ( !strcmp(in_link->name, "txsend_sign" ) ) {
369 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_TXSEND;
370 0 : FD_TEST( !strcmp( out_link->name, "sign_txsend" ) );
371 0 : FD_TEST( in_link->mtu==FD_TXN_MTU );
372 0 : FD_TEST( out_link->mtu==64UL*2UL );
373 0 : } else if( !strcmp(in_link->name, "bundle_sign" ) ) {
374 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE;
375 0 : FD_TEST( !strcmp( out_link->name, "sign_bundle" ) );
376 0 : FD_TEST( in_link->mtu==9UL );
377 0 : FD_TEST( out_link->mtu==64UL );
378 0 : } else if( !strcmp(in_link->name, "event_sign" ) ) {
379 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_EVENT;
380 0 : FD_TEST( !strcmp( out_link->name, "sign_event" ) );
381 0 : FD_TEST( in_link->mtu==317UL );
382 0 : FD_TEST( out_link->mtu==64UL );
383 0 : } else if( !strcmp(in_link->name, "pack_sign" ) ) {
384 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE_CRANK;
385 0 : FD_TEST( !strcmp( out_link->name, "sign_pack" ) );
386 0 : FD_TEST( in_link->mtu==1232UL );
387 0 : FD_TEST( out_link->mtu==64UL );
388 0 : } else if( !strcmp(in_link->name, "rserve_sign" ) ) {
389 0 : ctx->in[ i ].role = FD_KEYGUARD_ROLE_RSERVE;
390 0 : FD_TEST( !strcmp( out_link->name, "sign_rserve" ) );
391 0 : FD_TEST( in_link->mtu==68UL );
392 0 : FD_TEST( out_link->mtu==64UL );
393 0 : } else {
394 0 : FD_LOG_CRIT(( "unexpected link %s", in_link->name ));
395 0 : }
396 0 : }
397 :
398 0 : ulong scratch_top = FD_SCRATCH_ALLOC_FINI( l, scratch_align() );
399 0 : if( FD_UNLIKELY( scratch_top > (ulong)scratch + scratch_footprint( tile ) ) )
400 0 : FD_LOG_ERR(( "scratch overflow %lu %lu %lu", scratch_top - (ulong)scratch - scratch_footprint( tile ), scratch_top, (ulong)scratch + scratch_footprint( tile ) ));
401 0 : }
402 :
403 : static void
404 : unprivileged_init( fd_topo_t const * topo,
405 0 : fd_topo_tile_t const * tile ) {
406 0 : unprivileged_init_sensitive( topo, tile );
407 0 : }
408 :
409 : static ulong
410 : populate_allowed_seccomp( fd_topo_t const * topo,
411 : fd_topo_tile_t const * tile,
412 : ulong out_cnt,
413 0 : struct sock_filter * out ) {
414 0 : (void)topo;
415 0 : (void)tile;
416 :
417 0 : populate_sock_filter_policy_fd_sign_tile( out_cnt, out, (uint)fd_log_private_logfile_fd() );
418 0 : return sock_filter_policy_fd_sign_tile_instr_cnt;
419 0 : }
420 :
421 : static ulong
422 : populate_allowed_fds( fd_topo_t const * topo,
423 : fd_topo_tile_t const * tile,
424 : ulong out_fds_cnt,
425 0 : int * out_fds ) {
426 0 : (void)topo;
427 0 : (void)tile;
428 :
429 0 : if( FD_UNLIKELY( out_fds_cnt<2UL ) ) FD_LOG_ERR(( "out_fds_cnt %lu", out_fds_cnt ));
430 :
431 0 : ulong out_cnt = 0;
432 0 : out_fds[ out_cnt++ ] = 2; /* stderr */
433 0 : if( FD_LIKELY( -1!=fd_log_private_logfile_fd() ) )
434 0 : out_fds[ out_cnt++ ] = fd_log_private_logfile_fd(); /* logfile */
435 0 : return out_cnt;
436 0 : }
437 :
438 0 : #define STEM_BURST (1UL)
439 :
440 : /* See explanation in fd_pack */
441 0 : #define STEM_LAZY (128L*3000L)
442 :
443 0 : #define STEM_CALLBACK_CONTEXT_TYPE fd_sign_ctx_t
444 0 : #define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_sign_ctx_t)
445 :
446 0 : #define STEM_CALLBACK_DURING_HOUSEKEEPING during_housekeeping
447 0 : #define STEM_CALLBACK_METRICS_WRITE metrics_write
448 0 : #define STEM_CALLBACK_DURING_FRAG during_frag
449 0 : #define STEM_CALLBACK_AFTER_FRAG after_frag
450 :
451 : #include "../../disco/stem/fd_stem.c"
452 :
453 : fd_topo_run_tile_t fd_tile_sign = {
454 : .name = "sign",
455 : .populate_allowed_seccomp = populate_allowed_seccomp,
456 : .populate_allowed_fds = populate_allowed_fds,
457 : .scratch_align = scratch_align,
458 : .scratch_footprint = scratch_footprint,
459 : .privileged_init = privileged_init,
460 : .unprivileged_init = unprivileged_init,
461 : .run = stem_run,
462 : };
|