Commit 28e223f0 authored by Jinjie Ruan's avatar Jinjie Ruan Committed by Gu Bowen
Browse files

posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime()

stable inclusion
from stable-v5.10.229
commit c7fcfdba35abc9f39b83080c2bce398dad13a943
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2YU9
CVE: CVE-2024-50195

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



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

[ Upstream commit 6e62807c7fbb3c758d233018caf94dfea9c65dbd ]

If get_clock_desc() succeeds, it calls fget() for the clockid's fd,
and get the clk->rwsem read lock, so the error path should release
the lock to make the lock balance and fput the clockid's fd to make
the refcount balance and release the fd related resource.

However the below commit left the error path locked behind resulting in
unbalanced locking. Check timespec64_valid_strict() before
get_clock_desc() to fix it, because the "ts" is not changed
after that.

Fixes: d8794ac20a29 ("posix-clock: Fix missing timespec64 check in pc_clock_settime()")
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarJinjie Ruan <ruanjinjie@huawei.com>
Acked-by: default avatarAnna-Maria Behnsen <anna-maria@linutronix.de>
[pabeni@redhat.com: fixed commit message typo]
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarGu Bowen <gubowen5@huawei.com>
parent 6bc08af4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -290,6 +290,9 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts)
	struct posix_clock_desc cd;
	int err;

	if (!timespec64_valid_strict(ts))
		return -EINVAL;

	err = get_clock_desc(id, &cd);
	if (err)
		return err;
@@ -299,9 +302,6 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts)
		goto out;
	}

	if (!timespec64_valid_strict(ts))
		return -EINVAL;

	if (cd.clk->ops.clock_settime)
		err = cd.clk->ops.clock_settime(cd.clk, ts);
	else