Esempio n. 1
0
// 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);
}
Esempio n. 2
0
// 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));
}
Esempio n. 3
0
// 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);
}
Esempio n. 4
0
// 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);
    }
}
Esempio n. 5
0
// 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;
}
Esempio n. 6
0
// 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);
}
Esempio n. 7
0
/*
 * 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;
}