str = kstrdup(buf, GFP_KERNEL); if (!str) return -ENOMEM;
acl = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL); if (!acl) {
ret = -ENOMEM; goto err_free_str;
}
uuid_str = strim(str); while ((s = strsep(&uuid_str, ",")) != NULL && i < tb->nboot_acl) {
size_t len = strlen(s);
if (len) { if (len != UUID_STRING_LEN) {
ret = -EINVAL; goto err_free_acl;
}
ret = uuid_parse(s, &acl[i]); if (ret) goto err_free_acl;
}
i++;
}
if (s || i < tb->nboot_acl) {
ret = -EINVAL; goto err_free_acl;
}
pm_runtime_get_sync(&tb->dev);
if (mutex_lock_interruptible(&tb->lock)) {
ret = -ERESTARTSYS; goto err_rpm_put;
}
ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl); if (!ret) { /* Notify userspace about the change */
tb_domain_event(tb, NULL);
}
mutex_unlock(&tb->lock);
/* Only meaningful if authorization is supported */ if (tb->security_level == TB_SECURITY_USER ||
tb->security_level == TB_SECURITY_SECURE)
deauthorization = !!tb->cm_ops->disapprove_switch;
if (!tb->cm_ops->handle_event) {
tb_warn(tb, "domain does not have event handler\n"); returntrue;
}
switch (type) { case TB_CFG_PKG_XDOMAIN_REQ: case TB_CFG_PKG_XDOMAIN_RESP: if (tb_is_xdomain_enabled()) return tb_xdomain_handle_request(tb, type, buf, size); break;
/** *tb_domain_remove()-Removesandreleasesadomain *@tb:Domaintoremove * *Stopsthedomain,removesitfromthesystemandreleasesall *resourcesoncethelastreferencehasbeenreleased.
*/ void tb_domain_remove(struct tb *tb)
{
mutex_lock(&tb->lock); if (tb->cm_ops->stop)
tb->cm_ops->stop(tb); /* Stop the domain control traffic */
tb_ctl_stop(tb->ctl);
mutex_unlock(&tb->lock);
flush_workqueue(tb->wq);
if (tb->cm_ops->deinit)
tb->cm_ops->deinit(tb);
device_unregister(&tb->dev);
}
/** *tb_domain_suspend_noirq()-Suspendadomain *@tb:Domaintosuspend * *Suspendsalldevicesinthedomainandstopsthecontrolchannel.
*/ int tb_domain_suspend_noirq(struct tb *tb)
{ int ret = 0;
/* *Thecontrolchannelinterruptisleftenabledduringsuspend *andtakingthelockherepreventsanyeventshappeningbefore *weactuallyhavestoppedthedomainandthecontrolchannel.
*/
mutex_lock(&tb->lock); if (tb->cm_ops->suspend_noirq)
ret = tb->cm_ops->suspend_noirq(tb); if (!ret)
tb_ctl_stop(tb->ctl);
mutex_unlock(&tb->lock);
return ret;
}
/** *tb_domain_resume_noirq()-Resumeadomain *@tb:Domaintoresume * *Re-startsthecontrolchannel,andresumesalldevicesconnectedto *thedomain.
*/ int tb_domain_resume_noirq(struct tb *tb)
{ int ret = 0;
mutex_lock(&tb->lock);
tb_ctl_start(tb->ctl); if (tb->cm_ops->resume_noirq)
ret = tb->cm_ops->resume_noirq(tb);
mutex_unlock(&tb->lock);
int tb_domain_freeze_noirq(struct tb *tb)
{ int ret = 0;
mutex_lock(&tb->lock); if (tb->cm_ops->freeze_noirq)
ret = tb->cm_ops->freeze_noirq(tb); if (!ret)
tb_ctl_stop(tb->ctl);
mutex_unlock(&tb->lock);
return ret;
}
int tb_domain_thaw_noirq(struct tb *tb)
{ int ret = 0;
mutex_lock(&tb->lock);
tb_ctl_start(tb->ctl); if (tb->cm_ops->thaw_noirq)
ret = tb->cm_ops->thaw_noirq(tb);
mutex_unlock(&tb->lock);
return ret;
}
void tb_domain_complete(struct tb *tb)
{ if (tb->cm_ops->complete)
tb->cm_ops->complete(tb);
}
int tb_domain_runtime_suspend(struct tb *tb)
{ if (tb->cm_ops->runtime_suspend) { int ret = tb->cm_ops->runtime_suspend(tb); if (ret) return ret;
}
tb_ctl_stop(tb->ctl); return0;
}
int tb_domain_runtime_resume(struct tb *tb)
{
tb_ctl_start(tb->ctl); if (tb->cm_ops->runtime_resume) { int ret = tb->cm_ops->runtime_resume(tb); if (ret) return ret;
} return0;
}
/* The parent switch must be authorized before this one */
parent_sw = tb_to_switch(sw->dev.parent); if (!parent_sw || !parent_sw->authorized) return -EINVAL;
if (!tb->cm_ops->approve_switch || !tb->cm_ops->add_switch_key) return -EPERM;
/* The parent switch must be authorized before this one */
parent_sw = tb_to_switch(sw->dev.parent); if (!parent_sw || !parent_sw->authorized) return -EINVAL;
ret = tb->cm_ops->add_switch_key(tb, sw); if (ret) return ret;
if (!tb->cm_ops->approve_switch || !tb->cm_ops->challenge_switch_key) return -EPERM;
/* The parent switch must be authorized before this one */
parent_sw = tb_to_switch(sw->dev.parent); if (!parent_sw || !parent_sw->authorized) return -EINVAL;
get_random_bytes(challenge, sizeof(challenge));
ret = tb->cm_ops->challenge_switch_key(tb, sw, challenge, response); if (ret) return ret;
tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); if (IS_ERR(tfm)) return PTR_ERR(tfm);
ret = crypto_shash_setkey(tfm, sw->key, TB_SWITCH_KEY_SIZE); if (ret) goto err_free_tfm;
shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
GFP_KERNEL); if (!shash) {
ret = -ENOMEM; goto err_free_tfm;
}
shash->tfm = tfm;
memset(hmac, 0, sizeof(hmac));
ret = crypto_shash_digest(shash, challenge, sizeof(hmac), hmac); if (ret) goto err_free_shash;
/* The returned HMAC must match the one we calculated */ if (memcmp(response, hmac, sizeof(hmac))) {
ret = -EKEYREJECTED; goto err_free_shash;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.13Bemerkung:
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.