]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
psp: add admin/non-admin version of psp_device_get_locked
authorWei Wang <weibunny@fb.com>
Mon, 8 Jun 2026 23:31:09 +0000 (16:31 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 13 Jun 2026 01:31:32 +0000 (18:31 -0700)
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>
Documentation/netlink/specs/psp.yaml
net/psp/psp-nl-gen.c
net/psp/psp-nl-gen.h
net/psp/psp.h
net/psp/psp_main.c
net/psp/psp_nl.c

index bfcd6e4ecb850ee5a2439cacc0ce7832687e11ce..e3b0fe296e8fed4d4c7dc76b08e52dd7e4e8576a 100644 (file)
@@ -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
index 953309952cef75c8b4c14f69d3f941200ee46935..a71dd629aeab6c01dc729f667fae606cc30d8d5f 100644 (file)
@@ -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,
index 599c5f1c82f20dfb58b4e01fac92781b5ab29b58..97735545539523dc50269b370c19c09804742b81 100644 (file)
@@ -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
index 9f19137593a03abcf42c5b5f92aae61b1d439e22..0f9c4e4e52cbf3e70a72591e9d203f708f9d62de 100644 (file)
@@ -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);
 
index ccbbb2a5fa58676ab1be1add775c54946462c45f..aaa44e6cb9ff9c12b3469f717cd78b75d4ca5133 100644 (file)
@@ -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;
index 0cc744a6e1c9bc9c61282ad7a7027aba49a13fae..b4f1b7f9b0c2a21c3b23d651bce46b30be568dd0 100644 (file)
@@ -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));