mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
psp: add admin/non-admin version of psp_device_get_locked
Introduce 2 versions of psp_device_get_locked: 1. psp_device_get_locked_admin(): This version is used for operations that would change the status of the psd, and are currently used for dev-set and key-rotation. 2. psp_device_get_locked(): This is the non-admin version, which are used for broader user issued operations including: dev-get, rx-assoc, tx-assoc, get-stats. Following commit will be implementing both of the checks. Signed-off-by: Wei Wang <weibunny@fb.com> Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com> Link: https://patch.msgid.link/20260608233118.2694144-2-weibunny.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -196,7 +196,7 @@ operations:
|
||||
- psp-versions-ena
|
||||
reply:
|
||||
attributes: []
|
||||
pre: psp-device-get-locked
|
||||
pre: psp-device-get-locked-admin
|
||||
post: psp-device-unlock
|
||||
-
|
||||
name: dev-change-ntf
|
||||
@@ -216,7 +216,7 @@ operations:
|
||||
reply:
|
||||
attributes:
|
||||
- id
|
||||
pre: psp-device-get-locked
|
||||
pre: psp-device-get-locked-admin
|
||||
post: psp-device-unlock
|
||||
-
|
||||
name: key-rotate-ntf
|
||||
|
||||
@@ -71,7 +71,7 @@ static const struct genl_split_ops psp_nl_ops[] = {
|
||||
},
|
||||
{
|
||||
.cmd = PSP_CMD_DEV_SET,
|
||||
.pre_doit = psp_device_get_locked,
|
||||
.pre_doit = psp_device_get_locked_admin,
|
||||
.doit = psp_nl_dev_set_doit,
|
||||
.post_doit = psp_device_unlock,
|
||||
.policy = psp_dev_set_nl_policy,
|
||||
@@ -80,7 +80,7 @@ static const struct genl_split_ops psp_nl_ops[] = {
|
||||
},
|
||||
{
|
||||
.cmd = PSP_CMD_KEY_ROTATE,
|
||||
.pre_doit = psp_device_get_locked,
|
||||
.pre_doit = psp_device_get_locked_admin,
|
||||
.doit = psp_nl_key_rotate_doit,
|
||||
.post_doit = psp_device_unlock,
|
||||
.policy = psp_key_rotate_nl_policy,
|
||||
|
||||
@@ -17,6 +17,8 @@ extern const struct nla_policy psp_keys_nl_policy[PSP_A_KEYS_SPI + 1];
|
||||
|
||||
int psp_device_get_locked(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_device_get_locked_admin(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_assoc_device_get_locked(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info);
|
||||
void
|
||||
|
||||
@@ -14,7 +14,7 @@ extern struct xarray psp_devs;
|
||||
extern struct mutex psp_devs_lock;
|
||||
|
||||
void psp_dev_free(struct psp_dev *psd);
|
||||
int psp_dev_check_access(struct psp_dev *psd, struct net *net);
|
||||
int psp_dev_check_access(struct psp_dev *psd, struct net *net, bool admin);
|
||||
|
||||
void psp_nl_notify_dev(struct psp_dev *psd, u32 cmd);
|
||||
|
||||
|
||||
@@ -27,10 +27,15 @@ struct mutex psp_devs_lock;
|
||||
* psp_dev_check_access() - check if user in a given net ns can access PSP dev
|
||||
* @psd: PSP device structure user is trying to access
|
||||
* @net: net namespace user is in
|
||||
* @admin: If true, only allow access from @psd's main device's netns,
|
||||
* for admin operations like config changes and key rotation.
|
||||
* If false, also allow access from network namespaces that have
|
||||
* an associated device with @psd, for read-only and association
|
||||
* management operations.
|
||||
*
|
||||
* Return: 0 if PSP device should be visible in @net, errno otherwise.
|
||||
*/
|
||||
int psp_dev_check_access(struct psp_dev *psd, struct net *net)
|
||||
int psp_dev_check_access(struct psp_dev *psd, struct net *net, bool admin)
|
||||
{
|
||||
if (dev_net(psd->main_netdev) == net)
|
||||
return 0;
|
||||
|
||||
@@ -41,7 +41,8 @@ static int psp_nl_reply_send(struct sk_buff *rsp, struct genl_info *info)
|
||||
/* Device stuff */
|
||||
|
||||
static struct psp_dev *
|
||||
psp_device_get_and_lock(struct net *net, struct nlattr *dev_id)
|
||||
psp_device_get_and_lock(struct net *net, struct nlattr *dev_id,
|
||||
bool admin)
|
||||
{
|
||||
struct psp_dev *psd;
|
||||
int err;
|
||||
@@ -56,7 +57,7 @@ psp_device_get_and_lock(struct net *net, struct nlattr *dev_id)
|
||||
mutex_lock(&psd->lock);
|
||||
mutex_unlock(&psp_devs_lock);
|
||||
|
||||
err = psp_dev_check_access(psd, net);
|
||||
err = psp_dev_check_access(psd, net, admin);
|
||||
if (err) {
|
||||
mutex_unlock(&psd->lock);
|
||||
return ERR_PTR(err);
|
||||
@@ -65,17 +66,31 @@ psp_device_get_and_lock(struct net *net, struct nlattr *dev_id)
|
||||
return psd;
|
||||
}
|
||||
|
||||
int psp_device_get_locked(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
static int __psp_device_get_locked(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info,
|
||||
bool admin)
|
||||
{
|
||||
if (GENL_REQ_ATTR_CHECK(info, PSP_A_DEV_ID))
|
||||
return -EINVAL;
|
||||
|
||||
info->user_ptr[0] = psp_device_get_and_lock(genl_info_net(info),
|
||||
info->attrs[PSP_A_DEV_ID]);
|
||||
info->attrs[PSP_A_DEV_ID],
|
||||
admin);
|
||||
return PTR_ERR_OR_ZERO(info->user_ptr[0]);
|
||||
}
|
||||
|
||||
int psp_device_get_locked_admin(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return __psp_device_get_locked(ops, skb, info, true);
|
||||
}
|
||||
|
||||
int psp_device_get_locked(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return __psp_device_get_locked(ops, skb, info, false);
|
||||
}
|
||||
|
||||
void
|
||||
psp_device_unlock(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
@@ -160,7 +175,7 @@ static int
|
||||
psp_nl_dev_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb,
|
||||
struct psp_dev *psd)
|
||||
{
|
||||
if (psp_dev_check_access(psd, sock_net(rsp->sk)))
|
||||
if (psp_dev_check_access(psd, sock_net(rsp->sk), false))
|
||||
return 0;
|
||||
|
||||
return psp_nl_dev_fill(psd, rsp, genl_info_dump(cb));
|
||||
@@ -310,7 +325,7 @@ int psp_assoc_device_get_locked(const struct genl_split_ops *ops,
|
||||
*/
|
||||
mutex_lock(&psd->lock);
|
||||
if (!psp_dev_is_registered(psd) ||
|
||||
psp_dev_check_access(psd, genl_info_net(info))) {
|
||||
psp_dev_check_access(psd, genl_info_net(info), false)) {
|
||||
mutex_unlock(&psd->lock);
|
||||
psp_dev_put(psd);
|
||||
psd = NULL;
|
||||
@@ -334,7 +349,7 @@ int psp_assoc_device_get_locked(const struct genl_split_ops *ops,
|
||||
|
||||
psp_dev_put(psd);
|
||||
} else {
|
||||
psd = psp_device_get_and_lock(genl_info_net(info), id);
|
||||
psd = psp_device_get_and_lock(genl_info_net(info), id, false);
|
||||
if (IS_ERR(psd)) {
|
||||
err = PTR_ERR(psd);
|
||||
goto err_sock_put;
|
||||
@@ -577,7 +592,7 @@ static int
|
||||
psp_nl_stats_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb,
|
||||
struct psp_dev *psd)
|
||||
{
|
||||
if (psp_dev_check_access(psd, sock_net(rsp->sk)))
|
||||
if (psp_dev_check_access(psd, sock_net(rsp->sk), false))
|
||||
return 0;
|
||||
|
||||
return psp_nl_stats_fill(psd, rsp, genl_info_dump(cb));
|
||||
|
||||
Reference in New Issue
Block a user