// zx_status_t zx_mtrace_control zx_status_t sys_mtrace_control(zx_handle_t handle, uint32_t kind, uint32_t action, uint32_t options, user_inout_ptr<void> ptr, size_t size) { // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } return mtrace_control(kind, action, options, ptr, size); }
// zx_status_t zx_ktrace_read zx_status_t sys_ktrace_read(zx_handle_t handle, user_out_ptr<void> _data, uint32_t offset, size_t len, user_out_ptr<size_t> _actual) { // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } ssize_t result = ktrace_read_user(_data.get(), offset, len); if (result < 0) return static_cast<zx_status_t>(result); return _actual.copy_to_user(static_cast<size_t>(result)); }
// zx_status_t zx_debug_send_command zx_status_t sys_debug_send_command(zx_handle_t handle, user_in_ptr<const char> ptr, size_t len) { LTRACEF("ptr %p, len %zu\n", ptr.get(), len); // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } if (len > kMaxDebugWriteSize) return ZX_ERR_INVALID_ARGS; char buf[kMaxDebugWriteSize + 2]; if (ptr.copy_array_from_user(buf, len) != ZX_OK) return ZX_ERR_INVALID_ARGS; buf[len] = '\n'; buf[len + 1] = 0; return console_run_script(buf); }
// zx_status_t zx_ktrace_control zx_status_t sys_ktrace_control( zx_handle_t handle, uint32_t action, uint32_t options, user_inout_ptr<void> _ptr) { // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } switch (action) { case KTRACE_ACTION_NEW_PROBE: { char name[ZX_MAX_NAME_LEN]; if (_ptr.copy_array_from_user(name, sizeof(name) - 1) != ZX_OK) return ZX_ERR_INVALID_ARGS; name[sizeof(name) - 1] = 0; return ktrace_control(action, options, name); } default: return ktrace_control(action, options, nullptr); } }
// zx_status_t zx_ktrace_write zx_status_t sys_ktrace_write(zx_handle_t handle, uint32_t event_id, uint32_t arg0, uint32_t arg1) { // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } if (event_id > 0x7FF) { return ZX_ERR_INVALID_ARGS; } uint32_t* args = static_cast<uint32_t*>(ktrace_open(TAG_PROBE_24(event_id))); if (!args) { // There is not a single reason for failure. Assume it reached the end. return ZX_ERR_UNAVAILABLE; } args[0] = arg0; args[1] = arg1; return ZX_OK; }
// zx_status_t zx_debug_read zx_status_t sys_debug_read(zx_handle_t handle, user_out_ptr<char> ptr, user_inout_ptr<size_t> len) { LTRACEF("ptr %p\n", ptr.get()); // TODO(ZX-971): finer grained validation zx_status_t status; if ((status = validate_resource(handle, ZX_RSRC_KIND_ROOT)) < 0) { return status; } // get the number of bytes the user wants us to read size_t readlen; status = len.copy_from_user(&readlen); if (status != ZX_OK) { return status; } size_t idx = 0; for (; idx < readlen; ++idx) { int intc = getchar(); if (intc < 0) { return intc; } if (intc == '\r') { intc = '\n'; } char c = static_cast<char>(intc); status = ptr.copy_array_to_user(&c, 1, idx); if (status != ZX_OK) { return status; } } return len.copy_to_user(idx); }
/* * To add a resource during runtime, the following approach is used: * * - Create a temporary file which contains the new resource. * - Use the existing parsing functions to add the new resource to the configured resources. * - on error: * - remove the resource and the temporary file. * - on success: * - move the new temporary resource file to a place, where it will also be loaded on restart * (<CONFIGDIR>/bareos-dir.d/<resourcetype>/<name_of_the_resource>.conf). * * This way, the existing parsing functionality is used. */ static inline bool configure_add_resource(UAContext *ua, int first_parameter, RES_TABLE *res_table) { POOL_MEM resource(PM_MESSAGE); POOL_MEM name(PM_MESSAGE); POOL_MEM filename_tmp(PM_FNAME); POOL_MEM filename(PM_FNAME); POOL_MEM temp(PM_FNAME); JOBRES *res = NULL; if (!configure_create_resource_string(ua, first_parameter, res_table, name, resource)) { return false; } if (GetResWithName(res_table->rcode, name.c_str())) { ua->error_msg("Resource \"%s\" with name \"%s\" already exists.\n", res_table->name, name.c_str()); return false; } if (!my_config->get_path_of_new_resource(filename, temp, NULL, res_table->name, name.c_str(), true)) { ua->error_msg("%s", temp.c_str()); return false; } else { filename_tmp.strcpy(temp); } if (!configure_write_resource(filename_tmp.c_str(), res_table->name, name.c_str(), resource.c_str())) { ua->error_msg("failed to write config resource file\n"); return false; } if (!my_config->parse_config_file(filename_tmp.c_str(), ua, configure_lex_error_handler, NULL, M_ERROR)) { unlink(filename_tmp.c_str()); my_config->remove_resource(res_table->rcode, name.c_str()); return false; } /* * parse_config_file has already done some validation. * However, it skipped at least some checks for R_JOB * (reason: a job can get values from jobdefs, * and the value propagation happens after reading the full configuration) * therefore we explicitly check the new resource here. */ if ((res_table->rcode == R_JOB) || (res_table->rcode == R_JOBDEFS)) { res = (JOBRES *)GetResWithName(res_table->rcode, name.c_str()); propagate_jobdefs(res_table->rcode, res); if (!validate_resource(res_table->rcode, res_table->items, (BRSRES *)res)) { ua->error_msg("failed to create config resource \"%s\"\n", name.c_str()); unlink(filename_tmp.c_str()); my_config->remove_resource(res_table->rcode, name.c_str()); return false; } } /* * new config resource is working fine. Rename file to its permanent name. */ if (rename(filename_tmp.c_str(), filename.c_str()) != 0 ) { ua->error_msg("failed to create config file \"%s\"\n", filename.c_str()); unlink(filename_tmp.c_str()); my_config->remove_resource(res_table->rcode, name.c_str()); return false; } /* * When adding a client, also create the client configuration file. */ if (res_table->rcode==R_CLIENT) { configure_create_fd_resource(ua, name.c_str()); } ua->send->object_start("add"); ua->send->object_key_value("resource", res_table->name); ua->send->object_key_value("name", name.c_str()); ua->send->object_key_value("filename", filename.c_str(), "Created resource config file \"%s\":\n"); ua->send->object_key_value("content", resource.c_str(), "%s"); ua->send->object_end("add"); return true; }