Commit bade7092 authored by Sean Young's avatar Sean Young Committed by openeuler-sync-bot
Browse files

media: rc: bpf attach/detach requires write permission

stable inclusion
from stable-v5.10.210
commit 93d8109bf182510629bbefc8cd45296d2393987f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9HJVU
CVE: CVE-2023-52642

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=93d8109bf182510629bbefc8cd45296d2393987f



--------------------------------

commit 6a9d552483d50953320b9d3b57abdee8d436f23f upstream.

Note that bpf attach/detach also requires CAP_NET_ADMIN.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZhenzeng Su <suzhenzeng@huawei.com>
(cherry picked from commit 8cba46fe)
parent 272e398d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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);

+4 −1
Original line number Diff line number Diff line
@@ -822,7 +822,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;
@@ -836,6 +836,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;

+1 −1
Original line number Diff line number Diff line
@@ -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) {}