]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: rc: bpf attach/detach requires write permission
authorSean Young <sean@mess.org>
Thu, 13 Apr 2023 08:50:32 +0000 (10:50 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2024 07:55:07 +0000 (08:55 +0100)
commit 6a9d552483d50953320b9d3b57abdee8d436f23f upstream.

Note that bpf attach/detach also requires CAP_NET_ADMIN.

Cc: stable@vger.kernel.org
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/rc/bpf-lirc.c
drivers/media/rc/lirc_dev.c
drivers/media/rc/rc-core-priv.h

index 3eff08d7b8e5cf3b4508a6b14708bbb0fc3134e4..713c4539f29c5a849cfe5ba0d92bce8e501ffd45 100644 (file)
@@ -249,7 +249,7 @@ int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
        if (attr->attach_flags)
                return -EINVAL;
 
-       rcdev = rc_dev_get_from_fd(attr->target_fd);
+       rcdev = rc_dev_get_from_fd(attr->target_fd, true);
        if (IS_ERR(rcdev))
                return PTR_ERR(rcdev);
 
@@ -274,7 +274,7 @@ int lirc_prog_detach(const union bpf_attr *attr)
        if (IS_ERR(prog))
                return PTR_ERR(prog);
 
-       rcdev = rc_dev_get_from_fd(attr->target_fd);
+       rcdev = rc_dev_get_from_fd(attr->target_fd, true);
        if (IS_ERR(rcdev)) {
                bpf_prog_put(prog);
                return PTR_ERR(rcdev);
@@ -299,7 +299,7 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
        if (attr->query.query_flags)
                return -EINVAL;
 
-       rcdev = rc_dev_get_from_fd(attr->query.target_fd);
+       rcdev = rc_dev_get_from_fd(attr->query.target_fd, false);
        if (IS_ERR(rcdev))
                return PTR_ERR(rcdev);
 
index 888177b91152513c6e4fada753e78c5399a704ff..d73f02b0db8425f5049a5772b416d008df75d25a 100644 (file)
@@ -827,7 +827,7 @@ void __exit lirc_dev_exit(void)
        unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);
 }
 
-struct rc_dev *rc_dev_get_from_fd(int fd)
+struct rc_dev *rc_dev_get_from_fd(int fd, bool write)
 {
        struct fd f = fdget(fd);
        struct lirc_fh *fh;
@@ -841,6 +841,9 @@ struct rc_dev *rc_dev_get_from_fd(int fd)
                return ERR_PTR(-EINVAL);
        }
 
+       if (write && !(f.file->f_mode & FMODE_WRITE))
+               return ERR_PTR(-EPERM);
+
        fh = f.file->private_data;
        dev = fh->rc;
 
index 62f032dffd33a09413c133a1bcbae5f5fb1f431f..dfe0352c0f0a62f1826aca0e03e9b75c489291a9 100644 (file)
@@ -325,7 +325,7 @@ void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);
 void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc);
 int lirc_register(struct rc_dev *dev);
 void lirc_unregister(struct rc_dev *dev);
-struct rc_dev *rc_dev_get_from_fd(int fd);
+struct rc_dev *rc_dev_get_from_fd(int fd, bool write);
 #else
 static inline int lirc_dev_init(void) { return 0; }
 static inline void lirc_dev_exit(void) {}