Package: glibc / 2.41-10

hurd-i386/git-utime-EINVAL.diff Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
commit 8a0200c833f261e8eb456bbc4f0f5449e1a5e367
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Tue Mar 18 18:49:21 2025 +0100

    hurd: Make *utime*s catch invalid times [BZ #32802]

diff --git a/sysdeps/mach/hurd/futimens.c b/sysdeps/mach/hurd/futimens.c
index 30ef0a6493..12125299c4 100644
--- a/sysdeps/mach/hurd/futimens.c
+++ b/sysdeps/mach/hurd/futimens.c
@@ -32,7 +32,9 @@ __futimens (int fd, const struct timespec tsp[2])
   struct timespec atime, mtime;
   error_t err;
 
-  utime_ts_from_tspec (tsp, &atime, &mtime);
+  err = utime_ts_from_tspec (tsp, &atime, &mtime);
+  if (err)
+    return err;
 
   err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
 
@@ -40,7 +42,9 @@ __futimens (int fd, const struct timespec tsp[2])
     {
       time_value_t atim, mtim;
 
-      utime_tvalue_from_tspec (tsp, &atim, &mtim);
+      err = utime_tvalue_from_tspec (tsp, &atim, &mtim);
+      if (err)
+	return err;
 
       err = HURD_DPORT_USE (fd, __file_utimes (port, atim, mtim));
   }
diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c
index 20f47f3d28..97385d7dd0 100644
--- a/sysdeps/mach/hurd/futimes.c
+++ b/sysdeps/mach/hurd/futimes.c
@@ -32,7 +32,9 @@ __futimes (int fd, const struct timeval tvp[2])
   struct timespec atime, mtime;
   error_t err;
 
-  utime_ts_from_tval (tvp, &atime, &mtime);
+  err = utime_ts_from_tval (tvp, &atime, &mtime);
+  if (err)
+    return err;
 
   err = HURD_DPORT_USE (fd, __file_utimens (port, atime, mtime));
 
@@ -40,7 +42,9 @@ __futimes (int fd, const struct timeval tvp[2])
     {
       time_value_t atim, mtim;
 
-      utime_tvalue_from_tval (tvp, &atim, &mtim);
+      err = utime_tvalue_from_tval (tvp, &atim, &mtim);
+      if (err)
+	return err;
 
       err = HURD_DPORT_USE (fd, __file_utimes (port, atim, mtim));
     }
diff --git a/sysdeps/mach/hurd/utime-helper.c b/sysdeps/mach/hurd/utime-helper.c
index d88bccd786..6afa871197 100644
--- a/sysdeps/mach/hurd/utime-helper.c
+++ b/sysdeps/mach/hurd/utime-helper.c
@@ -21,8 +21,14 @@
 #include <stddef.h>
 #include <sys/time.h>
 
+static inline bool
+check_tval (const struct timeval *tvp)
+{
+  return tvp->tv_usec >= 0 && tvp->tv_usec < USEC_PER_SEC;
+}
+
 /* Initializes atime/mtime timespec structures from an array of timeval.  */
-static inline void
+static inline error_t
 utime_ts_from_tval (const struct timeval tvp[2],
                     struct timespec *atime, struct timespec *mtime)
 {
@@ -37,13 +43,19 @@ utime_ts_from_tval (const struct timeval tvp[2],
     }
   else
     {
+      if (!check_tval (&tvp[0]))
+	return EINVAL;
+      if (!check_tval (&tvp[1]))
+	return EINVAL;
+
       TIMEVAL_TO_TIMESPEC (&tvp[0], atime);
       TIMEVAL_TO_TIMESPEC (&tvp[1], mtime);
     }
+  return 0;
 }
 
 /* Initializes atime/mtime time_value_t structures from an array of timeval.  */
-static inline void
+static inline error_t
 utime_tvalue_from_tval (const struct timeval tvp[2],
                         time_value_t *atime, time_value_t *mtime)
 {
@@ -53,11 +65,17 @@ utime_tvalue_from_tval (const struct timeval tvp[2],
     atime->microseconds = mtime->microseconds = -1;
   else
     {
+      if (!check_tval (&tvp[0]))
+	return EINVAL;
+      if (!check_tval (&tvp[1]))
+	return EINVAL;
+
       atime->seconds = tvp[0].tv_sec;
       atime->microseconds = tvp[0].tv_usec;
       mtime->seconds = tvp[1].tv_sec;
       mtime->microseconds = tvp[1].tv_usec;
     }
+  return 0;
 }
 
 /* Changes the access time of the file behind PORT using a timeval array.  */
@@ -67,7 +85,9 @@ hurd_futimes (const file_t port, const struct timeval tvp[2])
   error_t err;
   struct timespec atime, mtime;
 
-  utime_ts_from_tval (tvp, &atime, &mtime);
+  err = utime_ts_from_tval (tvp, &atime, &mtime);
+  if (err)
+    return err;
 
   err = __file_utimens (port, atime, mtime);
 
@@ -75,7 +95,9 @@ hurd_futimes (const file_t port, const struct timeval tvp[2])
     {
       time_value_t atim, mtim;
 
-      utime_tvalue_from_tval (tvp, &atim, &mtim);
+      err = utime_tvalue_from_tval (tvp, &atim, &mtim);
+      if (err)
+	return err;
 
       err = __file_utimes (port, atim, mtim);
     }
@@ -83,8 +105,16 @@ hurd_futimes (const file_t port, const struct timeval tvp[2])
   return err;
 }
 
+static inline bool
+check_tspec (const struct timespec *tsp)
+{
+  return tsp->tv_nsec == UTIME_NOW
+      || tsp->tv_nsec == UTIME_OMIT
+      || tsp->tv_nsec >= 0 && tsp->tv_nsec < NSEC_PER_SEC;
+}
+
 /* Initializes atime/mtime timespec structures from an array of timespec.  */
-static inline void
+static inline error_t
 utime_ts_from_tspec (const struct timespec tsp[2],
                      struct timespec *atime, struct timespec *mtime)
 {
@@ -99,13 +129,19 @@ utime_ts_from_tspec (const struct timespec tsp[2],
     }
   else
     {
+      if (!check_tspec (&tsp[0]))
+	return EINVAL;
+      if (!check_tspec (&tsp[1]))
+	return EINVAL;
+
       *atime = tsp[0];
       *mtime = tsp[1];
     }
+  return 0;
 }
 
 /* Initializes atime/mtime time_value_t structures from an array of timespec.  */
-static inline void
+static inline error_t
 utime_tvalue_from_tspec (const struct timespec tsp[2],
                          time_value_t *atime, time_value_t *mtime)
 {
@@ -115,6 +151,11 @@ utime_tvalue_from_tspec (const struct timespec tsp[2],
     atime->microseconds = mtime->microseconds = -1;
   else
     {
+      if (!check_tspec (&tsp[0]))
+	return EINVAL;
+      if (!check_tspec (&tsp[1]))
+	return EINVAL;
+
       if (tsp[0].tv_nsec == UTIME_NOW)
 	atime->microseconds = -1;
       else if (tsp[0].tv_nsec == UTIME_OMIT)
@@ -128,6 +169,7 @@ utime_tvalue_from_tspec (const struct timespec tsp[2],
       else
 	TIMESPEC_TO_TIME_VALUE (mtime, &(tsp[1]));
     }
+  return 0;
 }
 
 /* Changes the access time of the file behind PORT using a timespec array.  */
@@ -137,7 +179,9 @@ hurd_futimens (const file_t port, const struct timespec tsp[2])
   error_t err;
   struct timespec atime, mtime;
 
-  utime_ts_from_tspec (tsp, &atime, &mtime);
+  err = utime_ts_from_tspec (tsp, &atime, &mtime);
+  if (err)
+    return err;
 
   err = __file_utimens (port, atime, mtime);
 
@@ -145,7 +189,9 @@ hurd_futimens (const file_t port, const struct timespec tsp[2])
     {
       time_value_t atim, mtim;
 
-      utime_tvalue_from_tspec (tsp, &atim, &mtim);
+      err = utime_tvalue_from_tspec (tsp, &atim, &mtim);
+      if (err)
+	return err;
 
       err = __file_utimes (port, atim, mtim);
     }