/* test references */ static bool test_ref3(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref3 [\nPARENT REFERENCE FREE\n]\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(root, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(p2, r1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref3", p1, 2); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_SIZE("ref3", root, 0); talloc_free(root); printf("success: ref3\n"); return true; }
void log_talloc_report(TALLOC_CTX *ctx) { FILE *fd; char const *null_ctx = NULL; int i = 0; if (ctx) { null_ctx = talloc_get_name(NULL); } fd = fdopen(default_log.fd, "w"); if (!fd) { ERROR("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno)); return; } if (!ctx) { talloc_report_full(NULL, fd); } else { do { INFO("Context level %i", i++); talloc_report_full(ctx, fd); } while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx)); /* Stop before we hit NULL ctx */ } fclose(fd); }
static bool test_loop(void) { void *top = talloc_new(NULL); char *parent; struct req1 { char *req2, *req3; } *req1; printf("test: loop\n# TALLOC LOOP DESTRUCTION\n"); parent = talloc_strdup(top, "parent"); req1 = talloc(parent, struct req1); req1->req2 = talloc_strdup(req1, "req2"); talloc_set_destructor(req1->req2, test_loop_destructor); req1->req3 = talloc_strdup(req1, "req3"); (void)talloc_reference(req1->req3, req1); talloc_report_full(top, stderr); talloc_free(parent); talloc_report_full(top, stderr); talloc_report_full(NULL, stderr); talloc_free(top); torture_assert("loop", loop_destructor_count == 1, "FAILED TO FIRE LOOP DESTRUCTOR\n"); loop_destructor_count = 0; printf("success: loop\n"); return true; }
/* test references */ static bool test_ref1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref1\n# SINGLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(p1, 1, "p2"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 2, "x2"); talloc_named_const(p1, 3, "x3"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", ref, 1); CHECK_BLOCKS("ref1", r1, 2); fprintf(stderr, "Freeing p2\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(NULL, stderr); fprintf(stderr, "Testing NULL\n"); if (talloc_reference(root, NULL)) { return false; } CHECK_BLOCKS("ref1", root, 1); CHECK_SIZE("ref1", root, 0); talloc_free(root); printf("success: ref1\n"); return true; }
/* test references */ static bool test_ref2(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 2); fprintf(stderr, "Freeing ref\n"); talloc_unlink(r1, ref); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 4); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stderr); CHECK_SIZE("ref2", root, 0); talloc_free(root); printf("success: ref2\n"); return true; }
/** Generate a talloc memory report for a context and print to stderr/stdout * * @param ctx to generate a report for, may be NULL in which case the root context is used. */ int fr_log_talloc_report(TALLOC_CTX *ctx) { #define TALLOC_REPORT_MAX_DEPTH 20 FILE *log; int fd; fd = dup(fr_fault_log_fd); if (fd < 0) { fr_strerror_printf("Couldn't write memory report, failed to dup log fd: %s", fr_syserror(errno)); return -1; } log = fdopen(fd, "w"); if (!log) { close(fd); fr_strerror_printf("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno)); return -1; } if (!ctx) { fprintf(log, "Current state of talloced memory:\n"); talloc_report_full(talloc_null_ctx, log); } else { int i; fprintf(log, "Talloc chunk lineage:\n"); fprintf(log, "%p (%s)", ctx, talloc_get_name(ctx)); i = 0; while ((i < TALLOC_REPORT_MAX_DEPTH) && (ctx = talloc_parent(ctx))) { fprintf(log, " < %p (%s)", ctx, talloc_get_name(ctx)); i++; } fprintf(log, "\n"); i = 0; do { fprintf(log, "Talloc context level %i:\n", i++); talloc_report_full(ctx, log); } while ((ctx = talloc_parent(ctx)) && (i < TALLOC_REPORT_MAX_DEPTH) && (talloc_parent(ctx) != talloc_autofree_ctx) && /* Stop before we hit the autofree ctx */ (talloc_parent(ctx) != talloc_null_ctx)); /* Stop before we hit NULL ctx */ } fclose(log); return 0; }
/* dump talloc memory hierarchy, returning it as a blob to the client */ int32_t ctdb_dump_memory(struct ctdb_context *ctdb, TDB_DATA *outdata) { /* dump to a file, then send the file as a blob */ FILE *f; long fsize; f = tmpfile(); if (f == NULL) { DEBUG(DEBUG_ERR,(__location__ " Unable to open tmpfile - %s\n", strerror(errno))); return -1; } talloc_report_full(NULL, f); fsize = ftell(f); if (fsize == -1) { DEBUG(DEBUG_ERR, (__location__ " Unable to get file size - %s\n", strerror(errno))); fclose(f); return -1; } rewind(f); outdata->dptr = talloc_size(outdata, fsize); if (outdata->dptr == NULL) { fclose(f); CTDB_NO_MEMORY(ctdb, outdata->dptr); } outdata->dsize = fread(outdata->dptr, 1, fsize, f); fclose(f); if (outdata->dsize != fsize) { DEBUG(DEBUG_ERR,(__location__ " Unable to read tmpfile\n")); return -1; } return 0; }
static void sig_handler(int signr) { switch (signr) { case SIGTERM: case SIGINT: tbus_close(); talloc_report_full(gsmd_tallocs, stderr); exit(0); break; case SIGUSR1: talloc_report_full(gsmd_tallocs, stderr); case SIGALRM: gsmd_timer_check_n_run(); break; } }
int main(void) { int number_failed; int memdebug; int error; // Check if memdebug enabled memdebug = getenv("MEMDEBUG") ? atoi(getenv("MEMDEBUG")) : 0; if( memdebug ) { talloc_enable_leak_report_full(); } // Set up test suite Suite * s = parser_suite(); SRunner * sr = srunner_create(s); if( IS_WIN || memdebug ) { srunner_set_fork_status(sr, CK_NOFORK); } srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed(sr); srunner_free(sr); error = (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; // Generate report for memdebug if( memdebug ) { talloc_report_full(NULL, stderr); } // Return return error; }
static void signal_handler(int signal) { fprintf(stdout, "signal %u received\n", signal); switch (signal) { case SIGINT: bsc_shutdown_net(bsc_gsmnet); osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); sleep(3); exit(0); break; case SIGABRT: /* in case of abort, we want to obtain a talloc report * and then return to the caller, who will abort the process */ case SIGUSR1: talloc_report(tall_vty_ctx, stderr); talloc_report_full(tall_bsc_ctx, stderr); break; case SIGUSR2: if (!bsc_gsmnet->msc_data) return; if (!bsc_gsmnet->msc_data->msc_con) return; if (!bsc_gsmnet->msc_data->msc_con->is_connected) return; bsc_msc_lost(bsc_gsmnet->msc_data->msc_con); break; default: break; } }
/* * Test activating the IWbemLevel1Login interface asynchronously. */ static void torture_wbem_login_async_cont(struct composite_context *ctx) { struct composite_context *c = NULL; BOOL *pRet = NULL; struct IUnknown **mqi = NULL; NTSTATUS status; /* retrieve the parent composite context */ c = talloc_get_type(ctx->async.private_data, struct composite_context); if (!composite_is_ok(c)) return; pRet = (BOOL *)c->private_data; status = dcom_activate_recv(ctx, c, &mqi); *pRet = NT_STATUS_IS_OK(status); talloc_report_full(c, stdout); if (*pRet) { /* * Clean up by releasing the IUnknown interface on the remote server * and also by releasing our allocated interface pointer. */ IUnknown_Release(mqi[0], c); /* really synchronous but eh */ talloc_free(mqi); } composite_done(c); }
void sighandler(int sigset) { if (sigset == SIGHUP || sigset == SIGPIPE) return; fprintf(stderr, "Signal %d received.\n", sigset); switch (sigset) { case SIGINT: case SIGTERM: /* If another signal is received afterwards, the program * is terminated without finishing shutdown process. */ signal(SIGINT, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGPIPE, SIG_DFL); signal(SIGABRT, SIG_DFL); signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); quit = 1; break; case SIGABRT: /* in case of abort, we want to obtain a talloc report * and then return to the caller, who will abort the process */ case SIGUSR1: case SIGUSR2: talloc_report_full(tall_pcu_ctx, stderr); break; } }
/* test references */ static bool test_unlink1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: unlink\n# UNLINK\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("unlink", p1, 7); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", ref, 1); CHECK_BLOCKS("unlink", r1, 2); fprintf(stderr, "Unreferencing r1\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("unlink", p1, 6); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_SIZE("unlink", root, 0); talloc_free(root); printf("success: unlink\n"); return true; }
static BOOL torture_wbem_login_async(struct torture_context *torture) { BOOL ret = True; TALLOC_CTX *mem_ctx = talloc_init("torture_wbem_login_async"); struct com_context *com_ctx = NULL; const char *binding = NULL; struct composite_context *c = NULL; struct composite_context *new_ctx = NULL; struct GUID clsid; struct GUID iid; /* * Initialize our COM and DCOM contexts. */ com_init_ctx(&com_ctx, NULL); dcom_client_init(com_ctx, cmdline_credentials); /* * Pull our needed test arguments from the torture parameters subsystem. */ binding = torture_setting_string(torture, "binding", NULL); /* * Create a new composite for our call sequence, with the private data being * our return flag. */ c = composite_create(mem_ctx, com_ctx->event_ctx); c->private_data = &ret; /* * Create the parameters needed for the activation call: we need the CLSID * and IID for the specific interface we're after. */ GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid); GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid); /* * Fire off the asynchronous activation request with all the needed * input parameters. Then wait for the composite to be done within the * context of this function, which allows all the asynchronous magic to * still happen. */ new_ctx = dcom_activate_send(c, &clsid, binding, 1, &iid, com_ctx); composite_continue(c, new_ctx, torture_wbem_login_async_cont, c); composite_wait(new_ctx); talloc_free(c); talloc_report_full(mem_ctx, stdout); return ret; }
static bool test_rusty(void) { void *root; const char *p1; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_report_full(root, stdout); talloc_free(root); CHECK_BLOCKS("null_context", NULL, 2); return true; }
static bool test_lifeless(void) { void *top = talloc_new(NULL); char *parent, *child; void *child_owner = talloc_new(NULL); printf("test: lifeless\n# TALLOC_UNLINK LOOP\n"); parent = talloc_strdup(top, "parent"); child = talloc_strdup(parent, "child"); (void)talloc_reference(child, parent); (void)talloc_reference(child_owner, child); talloc_report_full(top, stderr); talloc_unlink(top, parent); talloc_unlink(top, child); talloc_report_full(top, stderr); talloc_free(top); talloc_free(child_owner); talloc_free(child); printf("success: lifeless\n"); return true; }
int main(int argc, const char *argv[]) { TALLOC_CTX *main_ctx=talloc_new(NULL); FILE *f; char *buf; size_t buflen; TR_MSG *msg; if (argc != 2) { printf("Usage: %s <input file>\n\n", argv[0]); exit(-1); } buf=malloc(MAX_MSG_LEN); if (!buf) { printf("Allocation error.\n\n"); exit(-1); } f=fopen(argv[1], "r"); if (!f) { printf("Error opening %s for reading.\n\n", argv[1]); exit(-1); } printf("Reading from %s...\n", argv[1]); buflen=fread(buf, sizeof(char), MAX_MSG_LEN, f); if (buflen==0) { printf("File empty.\n\n"); exit(0); } if (buflen>=MAX_MSG_LEN) printf("Warning: file may exceed maximum message length (%d bytes).\n", MAX_MSG_LEN); msg= tr_msg_decode(NULL, buf, buflen); /* if (rc==TRP_SUCCESS) trp_msg_print(msg);*/ printf("\nEncoding...\n"); printf("Result: \n%s\n\n", tr_msg_encode(NULL, msg)); talloc_report_full(main_ctx, stdout); return 0; }
static void signal_handler(int signal) { fprintf(stdout, "signal %u received\n", signal); switch (signal) { case SIGINT: osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); sleep(1); exit(0); break; case SIGABRT: /* in case of abort, we want to obtain a talloc report * and then return to the caller, who will abort the process */ case SIGUSR1: talloc_report(tall_vty_ctx, stderr); talloc_report_full(tall_bsc_ctx, stderr); break; case SIGUSR2: talloc_report_full(tall_vty_ctx, stderr); break; default: break; } }
/* test steal */ static bool test_steal(void) { void *root, *p1, *p2; printf("test: steal\n# STEAL\n"); root = talloc_new(NULL); p1 = talloc_array(root, char, 10); CHECK_SIZE("steal", p1, 10); p2 = talloc_realloc(root, NULL, char, 20); CHECK_SIZE("steal", p1, 10); CHECK_SIZE("steal", root, 30); torture_assert("steal", talloc_steal(p1, NULL) == NULL, "failed: stealing NULL should give NULL\n"); torture_assert("steal", talloc_steal(p1, p1) == p1, "failed: stealing to ourselves is a nop\n"); CHECK_BLOCKS("steal", root, 3); CHECK_SIZE("steal", root, 30); talloc_steal(NULL, p1); talloc_steal(NULL, p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(p1); talloc_steal(root, p2); CHECK_BLOCKS("steal", root, 2); CHECK_SIZE("steal", root, 20); talloc_free(p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(root); p1 = talloc_size(NULL, 3); talloc_report_full(NULL, stderr); CHECK_SIZE("steal", NULL, 3); talloc_free(p1); printf("success: steal\n"); return true; }
/* * Test activating the IWbemLevel1Login interface synchronously. */ static BOOL torture_wbem_login(struct torture_context *torture) { BOOL ret = True; TALLOC_CTX *mem_ctx = talloc_init("torture_wbem_login"); struct com_context *com_ctx = NULL; const char *binding = NULL; struct IUnknown **mqi = NULL; struct GUID clsid; struct GUID iid; NTSTATUS status; /* * Initialize our COM and DCOM contexts. */ com_init_ctx(&com_ctx, NULL); dcom_client_init(com_ctx, cmdline_credentials); /* * Pull our needed test arguments from the torture parameters subsystem. */ binding = torture_setting_string(torture, "binding", NULL); /* * Create the parameters needed for the activation call: we need the CLSID * and IID for the specific interface we're after. */ GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid); GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid); /* * Activate the interface using the DCOM synchronous method call. */ status = dcom_activate(com_ctx, mem_ctx, binding, &clsid, &iid, 1, &mqi); ret = NT_STATUS_IS_OK(status); if (ret) { /* * Clean up by releasing the IUnknown interface on the remote server * and also by releasing our allocated interface pointer. */ IUnknown_Release(mqi[0], mem_ctx); talloc_free(mqi); } talloc_report_full(mem_ctx, stdout); return ret; }
bool _check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location) { size_t bytes_allocated; bytes_allocated = talloc_total_size(ctx); if (bytes_allocated != bytes) { fprintf(stderr, "Leak report for %s:\n", location); talloc_report_full(ctx, stderr); _set_leak_err_msg("%s: memory leaks detected, %zd bytes still allocated", location, bytes_allocated - bytes); return false; } return true; }
int main(void) { int number_failed; Suite * s; SRunner * sr; int memdebug = 0; int iswin = 0; int error = 0; #if defined(_WIN64) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN32__) iswin = 1; #endif memdebug = getenv("MEMDEBUG") ? atoi(getenv("MEMDEBUG")) : 0; if( memdebug ) { talloc_enable_leak_report_full(); } rootctx = talloc_new(NULL); // Load the spec spec_filename = getenv("handlebars_tokenizer_spec"); if( spec_filename == NULL ) { spec_filename = "./spec/handlebars/spec/tokenizer.json"; } error = loadSpec(spec_filename); if( error != 0 ) { goto error; } fprintf(stderr, "Loaded %lu test cases\n", tests_len); s = parser_suite(); sr = srunner_create(s); if( iswin || memdebug ) { srunner_set_fork_status(sr, CK_NOFORK); } srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed(sr); srunner_free(sr); error = (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; error: talloc_free(rootctx); if( memdebug ) { talloc_report_full(NULL, stderr); } return error; }
static void signal_handler(int signal) { fprintf(stderr, "signal %u received\n", signal); switch (signal) { case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); if (!quit) bts_shutdown(bts, "SIGINT"); quit++; break; case SIGABRT: case SIGUSR1: case SIGUSR2: talloc_report_full(tall_bts_ctx, stderr); break; default: break; } }
static void signal_handler(int signal) { fprintf(stderr, "signal %u received\n", signal); switch (signal) { case SIGINT: case SIGTERM: sysmobts_check_temp(no_eeprom_write); sysmobts_update_hours(no_eeprom_write); exit(0); break; case SIGABRT: case SIGUSR1: case SIGUSR2: talloc_report_full(tall_mgr_ctx, stderr); break; default: break; } }
static bool test_free_children(void) { void *root; const char *p1, *p2, *name, *name2; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo1"); p2 = talloc_strdup(p1, "foo2"); talloc_set_name(p1, "%s", "testname"); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); if (strcmp(talloc_get_name(p1), "testname") != 0) { return false; } talloc_set_name(p1, "%s", "testname"); name = talloc_get_name(p1); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 2); /* note that this does not free the old child name */ talloc_set_name_const(p1, "testname2"); name2 = talloc_get_name(p1); /* but this does */ talloc_free_children(p1); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 1); talloc_report_full(root, stdout); talloc_free(root); return true; }
int main(int argc, char **argv) { int quit = 0; int rc; char const * home; size_t len; const char osmocomcfg[] = ".osmocom/bb/mobile.cfg"; char *config_file = NULL; printf("%s\n", openbsc_copyright); srand(time(NULL)); INIT_LLIST_HEAD(&ms_list); log_init(&log_info, NULL); stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_all_filter(stderr_target, 1); l23_ctx = talloc_named_const(NULL, 1, "layer2 context"); msgb_set_talloc_ctx(l23_ctx); handle_options(argc, argv); if (!debug_set) log_parse_category_mask(stderr_target, debug_default); log_set_log_level(stderr_target, LOGL_DEBUG); if (gsmtap_ip) { gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1); if (!gsmtap_inst) { fprintf(stderr, "Failed during gsmtap_init()\n"); exit(1); } gsmtap_source_add_sink(gsmtap_inst); } home = getenv("HOME"); if (home != NULL) { len = strlen(home) + 1 + sizeof(osmocomcfg); config_file = talloc_size(l23_ctx, len); if (config_file != NULL) snprintf(config_file, len, "%s/%s", home, osmocomcfg); } /* save the config file directory name */ config_dir = talloc_strdup(l23_ctx, config_file); config_dir = dirname(config_dir); if (use_mncc_sock) rc = l23_app_init(mncc_recv_socket, config_file, vty_port); else rc = l23_app_init(NULL, config_file, vty_port); if (rc) exit(rc); signal(SIGINT, sighandler); signal(SIGHUP, sighandler); signal(SIGTERM, sighandler); signal(SIGPIPE, sighandler); signal(SIGABRT, sighandler); signal(SIGUSR1, sighandler); signal(SIGUSR2, sighandler); if (daemonize) { printf("Running as daemon\n"); rc = osmo_daemonize(); if (rc) fprintf(stderr, "Failed to run as daemon\n"); } while (1) { l23_app_work(&quit); if (quit && llist_empty(&ms_list)) break; osmo_select_main(0); } l23_app_exit(); talloc_free(config_file); talloc_free(config_dir); talloc_report_full(l23_ctx, stderr); return 0; }
/* miscellaneous tests to try to get a higher test coverage percentage */ static bool test_misc(void) { void *root, *p1; char *p2; double *d; const char *name; printf("test: misc\n# MISCELLANEOUS\n"); root = talloc_new(NULL); p1 = talloc_size(root, 0x7fffffff); torture_assert("misc", !p1, "failed: large talloc allowed\n"); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); p2 = talloc_strdup(p1, "foo"); torture_assert("misc", talloc_unlink(root, p2) == -1, "failed: talloc_unlink() of non-reference context should return -1\n"); torture_assert("misc", talloc_unlink(p1, p2) == 0, "failed: talloc_unlink() of parent should succeed\n"); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); name = talloc_set_name(p1, "my name is %s", "foo"); torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", "failed: wrong name after talloc_set_name(my name is foo)"); torture_assert_str_equal("misc", talloc_get_name(p1), name, "failed: wrong name after talloc_set_name(my name is foo)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_set_name_const(p1, NULL); torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", "failed: wrong name after talloc_set_name(NULL)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); torture_assert("misc", talloc_free(NULL) == -1, "talloc_free(NULL) should give -1\n"); talloc_set_destructor(p1, fail_destructor); torture_assert("misc", talloc_free(p1) == -1, "Failed destructor should cause talloc_free to fail\n"); talloc_set_destructor(p1, NULL); talloc_report(root, stderr); p2 = (char *)talloc_zero_size(p1, 20); torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); talloc_free(p2); torture_assert("misc", talloc_strdup(root, NULL) == NULL, "failed: strdup on NULL should give NULL\n"); p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); d = talloc_array(p1, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); d = talloc_realloc(p1, d, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); talloc_free(p1); CHECK_BLOCKS("misc", root, 1); p1 = talloc_named(root, 100, "%d bytes", 100); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(root, p1); p1 = talloc_init("%d bytes", 200); p2 = talloc_asprintf(p1, "my test '%s'", "string"); torture_assert_str_equal("misc", p2, "my test 'string'", "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); CHECK_BLOCKS("misc", p1, 3); CHECK_SIZE("misc", p2, 17); CHECK_BLOCKS("misc", root, 1); talloc_unlink(NULL, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(p1, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(p1, p2); talloc_unlink(root, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(NULL, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p2); talloc_unlink(root, p1); /* Test that talloc_unlink is a no-op */ torture_assert("misc", talloc_unlink(root, NULL) == -1, "failed: talloc_unlink(root, NULL) == -1\n"); talloc_report(root, stderr); talloc_report(NULL, stderr); CHECK_SIZE("misc", root, 0); talloc_free(root); CHECK_SIZE("misc", NULL, 0); talloc_enable_null_tracking_no_autofree(); talloc_enable_leak_report(); talloc_enable_leak_report_full(); printf("success: misc\n"); return true; }
/* sec_mod_server: * @config: server configuration * @socket_file: the name of the socket * @cmd_fd: socket to exchange commands with main * @cmd_fd_sync: socket to received sync commands from main * * This is the main part of the security module. * It creates the unix domain socket identified by @socket_file * and then accepts connections from the workers to it. Then * it serves commands requested on the server's private key. * * When the operation is decrypt the provided data are * decrypted and sent back to worker. The sign operation * signs the provided data. * * The security module's reply to the worker has the * following format: * byte[0-5]: length (uint32_t) * byte[5-total]: data (signature or decrypted data) * * The reason for having this as a separate process * is to avoid any bug on the workers to leak the key. * It is not part of main because workers are spawned * from main, and thus should be prevented from accessing * parts the key in stack or heap that was not zeroized. * Other than that it allows the main server to spawn * clients fast without becoming a bottleneck due to private * key operations. */ void sec_mod_server(void *main_pool, struct perm_cfg_st *perm_config, const char *socket_file, int cmd_fd, int cmd_fd_sync) { struct sockaddr_un sa; socklen_t sa_len; int cfd, ret, e, n; unsigned buffer_size; uid_t uid; uint8_t *buffer; int sd; sec_mod_st *sec; void *sec_mod_pool; fd_set rd_set; pid_t pid; #ifdef HAVE_PSELECT struct timespec ts; #else struct timeval ts; #endif sigset_t emptyset, blockset; #ifdef DEBUG_LEAKS talloc_enable_leak_report_full(); #endif sigemptyset(&blockset); sigemptyset(&emptyset); sigaddset(&blockset, SIGALRM); sigaddset(&blockset, SIGTERM); sigaddset(&blockset, SIGINT); sigaddset(&blockset, SIGHUP); sec_mod_pool = talloc_init("sec-mod"); if (sec_mod_pool == NULL) { seclog(sec, LOG_ERR, "error in memory allocation"); exit(1); } sec = talloc_zero(sec_mod_pool, sec_mod_st); if (sec == NULL) { seclog(sec, LOG_ERR, "error in memory allocation"); exit(1); } sec->perm_config = talloc_steal(sec, perm_config); sec->config = sec->perm_config->config; tls_cache_init(sec, &sec->tls_db); sup_config_init(sec); memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; strlcpy(sa.sun_path, socket_file, sizeof(sa.sun_path)); remove(socket_file); #define SOCKET_FILE sa.sun_path /* we no longer need the main pool after this point. */ talloc_free(main_pool); ocsignal(SIGHUP, handle_sighup); ocsignal(SIGINT, handle_sigterm); ocsignal(SIGTERM, handle_sigterm); ocsignal(SIGALRM, handle_alarm); sec_auth_init(sec, perm_config); sec->cmd_fd = cmd_fd; sec->cmd_fd_sync = cmd_fd_sync; #ifdef HAVE_PKCS11 ret = gnutls_pkcs11_reinit(); if (ret < 0) { seclog(sec, LOG_WARNING, "error in PKCS #11 reinitialization: %s", gnutls_strerror(ret)); } #endif if (sec_mod_client_db_init(sec) == NULL) { seclog(sec, LOG_ERR, "error in client db initialization"); exit(1); } sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd == -1) { e = errno; seclog(sec, LOG_ERR, "could not create socket '%s': %s", SOCKET_FILE, strerror(e)); exit(1); } set_cloexec_flag(sd, 1); umask(066); ret = bind(sd, (struct sockaddr *)&sa, SUN_LEN(&sa)); if (ret == -1) { e = errno; seclog(sec, LOG_ERR, "could not bind socket '%s': %s", SOCKET_FILE, strerror(e)); exit(1); } ret = chown(SOCKET_FILE, perm_config->uid, perm_config->gid); if (ret == -1) { e = errno; seclog(sec, LOG_INFO, "could not chown socket '%s': %s", SOCKET_FILE, strerror(e)); } ret = listen(sd, 1024); if (ret == -1) { e = errno; seclog(sec, LOG_ERR, "could not listen to socket '%s': %s", SOCKET_FILE, strerror(e)); exit(1); } ret = load_keys(sec, 1); if (ret < 0) { seclog(sec, LOG_ERR, "error loading private key files"); exit(1); } sigprocmask(SIG_BLOCK, &blockset, &sig_default_set); alarm(MAINTAINANCE_TIME); seclog(sec, LOG_INFO, "sec-mod initialized (socket: %s)", SOCKET_FILE); for (;;) { check_other_work(sec); FD_ZERO(&rd_set); n = 0; FD_SET(cmd_fd, &rd_set); n = MAX(n, cmd_fd); FD_SET(cmd_fd_sync, &rd_set); n = MAX(n, cmd_fd_sync); FD_SET(sd, &rd_set); n = MAX(n, sd); #ifdef HAVE_PSELECT ts.tv_nsec = 0; ts.tv_sec = 120; ret = pselect(n + 1, &rd_set, NULL, NULL, &ts, &emptyset); #else ts.tv_usec = 0; ts.tv_sec = 120; sigprocmask(SIG_UNBLOCK, &blockset, NULL); ret = select(n + 1, &rd_set, NULL, NULL, &ts); sigprocmask(SIG_BLOCK, &blockset, NULL); #endif if (ret == 0 || (ret == -1 && errno == EINTR)) continue; if (ret < 0) { e = errno; seclog(sec, LOG_ERR, "Error in pselect(): %s", strerror(e)); exit(1); } /* we do a new allocation, to also use it as pool for the * parsers to use */ buffer_size = MAX_MSG_SIZE; buffer = talloc_size(sec, buffer_size); if (buffer == NULL) { seclog(sec, LOG_ERR, "error in memory allocation"); exit(1); } /* we use two fds for communication with main. The synchronous is for * ping-pong communication which each request is answered immediated. The * async is for messages sent back and forth in no particular order */ if (FD_ISSET(cmd_fd_sync, &rd_set)) { ret = serve_request_main(sec, cmd_fd_sync, buffer, buffer_size); if (ret < 0 && ret == ERR_BAD_COMMAND) { seclog(sec, LOG_ERR, "error processing sync command from main"); exit(1); } } if (FD_ISSET(cmd_fd, &rd_set)) { ret = serve_request_main(sec, cmd_fd, buffer, buffer_size); if (ret < 0 && ret == ERR_BAD_COMMAND) { seclog(sec, LOG_ERR, "error processing async command from main"); exit(1); } } if (FD_ISSET(sd, &rd_set)) { sa_len = sizeof(sa); cfd = accept(sd, (struct sockaddr *)&sa, &sa_len); if (cfd == -1) { e = errno; if (e != EINTR) { seclog(sec, LOG_DEBUG, "sec-mod error accepting connection: %s", strerror(e)); goto cont; } } set_cloexec_flag (cfd, 1); /* do not allow unauthorized processes to issue commands */ ret = check_upeer_id("sec-mod", sec->perm_config->debug, cfd, perm_config->uid, perm_config->gid, &uid, &pid); if (ret < 0) { seclog(sec, LOG_INFO, "rejected unauthorized connection"); } else { memset(buffer, 0, buffer_size); serve_request_worker(sec, cfd, pid, buffer, buffer_size); } close(cfd); } cont: talloc_free(buffer); #ifdef DEBUG_LEAKS talloc_report_full(sec, stderr); #endif } }
int main(int argc, char *argv[]) { struct gprs_rlcmac_bts *bts; int rc; tall_pcu_ctx = talloc_named_const(NULL, 1, "Osmo-PCU context"); if (!tall_pcu_ctx) return -ENOMEM; bv_tall_ctx = tall_pcu_ctx; bts = gprs_rlcmac_bts = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_bts); if (!gprs_rlcmac_bts) return -ENOMEM; bts->fc_interval = 1; bts->initial_cs_dl = bts->initial_cs_ul = 1; bts->cs1 = 1; bts->t3142 = 20; bts->t3169 = 5; bts->t3191 = 5; bts->t3193_msec = 100; bts->t3195 = 5; bts->n3101 = 10; bts->n3103 = 4; bts->n3105 = 8; bts->alpha = 0; /* a = 0.0 */ msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); vty_init(&pcu_vty_info); pcu_vty_init(&gprs_log_info); handle_options(argc, argv); if ((!!spoof_mcc) + (!!spoof_mnc) == 1) { fprintf(stderr, "--mcc and --mnc must be specified " "together.\n"); exit(0); } rc = vty_read_config_file(config_file, NULL); if (rc < 0 && config_given) { fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); exit(1); } if (rc < 0) fprintf(stderr, "No config file: '%s' Using default config.\n", config_file); rc = telnet_init(tall_pcu_ctx, NULL, 4240); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); } if (!bts->alloc_algorithm) bts->alloc_algorithm = alloc_algorithm_b; rc = pcu_l1if_open(); if (rc < 0) return rc; signal(SIGINT, sighandler); signal(SIGHUP, sighandler); signal(SIGTERM, sighandler); signal(SIGPIPE, sighandler); signal(SIGABRT, sighandler); signal(SIGUSR1, sighandler); signal(SIGUSR2, sighandler); while (!quit) { osmo_gsm_timers_check(); osmo_gsm_timers_prepare(); osmo_gsm_timers_update(); osmo_select_main(0); #ifdef DEBUG_DIAGRAM gettimeofday(&diagram_time, NULL); #endif } telnet_exit(); pcu_l1if_close(); talloc_free(gprs_rlcmac_bts); talloc_report_full(tall_pcu_ctx, stderr); talloc_free(tall_pcu_ctx); return 0; }
int main(int argc, char *argv[]) { struct sched_param param; struct gprs_rlcmac_bts *bts; int rc; tall_pcu_ctx = talloc_named_const(NULL, 1, "Osmo-PCU context"); if (!tall_pcu_ctx) return -ENOMEM; bv_tall_ctx = tall_pcu_ctx; bts = bts_main_data(); bts->fc_interval = 1; bts->initial_cs_dl = bts->initial_cs_ul = 1; bts->cs1 = 1; bts->t3142 = 20; bts->t3169 = 5; bts->t3191 = 5; bts->t3193_msec = 100; bts->t3195 = 5; bts->n3101 = 10; bts->n3103 = 4; bts->n3105 = 8; bts->alpha = 0; /* a = 0.0 */ msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&gprs_log_info); vty_init(&pcu_vty_info); pcu_vty_init(&gprs_log_info); handle_options(argc, argv); if ((!!spoof_mcc) + (!!spoof_mnc) == 1) { fprintf(stderr, "--mcc and --mnc must be specified " "together.\n"); exit(0); } rc = vty_read_config_file(config_file, NULL); if (rc < 0 && config_given) { fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); exit(1); } if (rc < 0) fprintf(stderr, "No config file: '%s' Using default config.\n", config_file); rc = telnet_init(tall_pcu_ctx, NULL, 4240); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); } if (!bts->alloc_algorithm) bts->alloc_algorithm = alloc_algorithm_b; rc = pcu_l1if_open(); if (rc < 0) return rc; signal(SIGINT, sighandler); signal(SIGHUP, sighandler); signal(SIGTERM, sighandler); signal(SIGPIPE, sighandler); signal(SIGABRT, sighandler); signal(SIGUSR1, sighandler); signal(SIGUSR2, sighandler); /* enable realtime priority for us */ if (rt_prio != -1) { memset(¶m, 0, sizeof(param)); param.sched_priority = rt_prio; rc = sched_setscheduler(getpid(), SCHED_RR, ¶m); if (rc != 0) { fprintf(stderr, "Setting SCHED_RR priority(%d) failed: %s\n", param.sched_priority, strerror(errno)); exit(1); } } while (!quit) { osmo_gsm_timers_check(); osmo_gsm_timers_prepare(); osmo_gsm_timers_update(); osmo_select_main(0); } telnet_exit(); pcu_l1if_close(); bts->bts->timing_advance()->flush(); talloc_report_full(tall_pcu_ctx, stderr); talloc_free(tall_pcu_ctx); return 0; }