summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbernard <[email protected]>2026-11-07 03:04:14 +0800
committerRbb666 <[email protected]>2026-11-08 14:12:22 +0800
commit2b0b1044c0ef4c49df5f27680635b48e405f7e86 (patch)
treea91137c686a123e2057afea3365c7e2897548b1b
parentcf85de90b8e1af46cb53957e277b2f257e440c35 (diff)
[libc][posix] fix: validate fd type in timerfd_settime/gettime
timerfd_do_settime() and timerfd_do_gettime() used vnode->data from any file descriptor as struct rt_timerfd. Validate that the descriptor's file operations are timerfd_fops before dereferencing the private data, using df->fops under DFS v2 and vnode->fops under DFS v1.
-rw-r--r--components/libc/posix/io/timerfd/timerfd.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/components/libc/posix/io/timerfd/timerfd.c b/components/libc/posix/io/timerfd/timerfd.c
index ddf46fd91a..ce921e38ae 100644
--- a/components/libc/posix/io/timerfd/timerfd.c
+++ b/components/libc/posix/io/timerfd/timerfd.c
@@ -378,8 +378,21 @@ static int timerfd_do_settime(int fd, int flags, const struct itimerspec *new, s
}
df = fd_get(fd);
- if (!df)
+ if (df == RT_NULL || df->vnode == RT_NULL)
+ {
+ rt_set_errno(EINVAL);
return -EINVAL;
+ }
+
+#ifdef RT_USING_DFS_V2
+ if (df->fops != &timerfd_fops)
+#else
+ if (df->vnode->fops != &timerfd_fops)
+#endif
+ {
+ rt_set_errno(EINVAL);
+ return -EINVAL;
+ }
tfd = df->vnode->data;
@@ -502,7 +515,17 @@ static int timerfd_do_gettime(int fd, struct itimerspec *cur)
df = fd_get(fd);
- if (df == RT_NULL)
+ if (df == RT_NULL || df->vnode == RT_NULL)
+ {
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+
+#ifdef RT_USING_DFS_V2
+ if (df->fops != &timerfd_fops)
+#else
+ if (df->vnode->fops != &timerfd_fops)
+#endif
{
rt_set_errno(EINVAL);
return -1;