1*4882a593SmuzhiyunFrom 9171c2495b1a05eabaeb0afeee629682cc6f5bac Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Adhemerval Zanella <adhemerval.zanella@linaro.org>
3*4882a593SmuzhiyunDate: Mon, 5 Oct 2020 17:30:05 -0300
4*4882a593SmuzhiyunSubject: [PATCH 15/20] posix: Fix -Warray-bounds instances building
5*4882a593Smuzhiyun timer_create [BZ #26687]
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunGCC 11 -Warray-bounds triggers invalid warnings when building
8*4882a593SmuzhiyunLinux timer_create.c:
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun../sysdeps/unix/sysv/linux/timer_create.c: In function '__timer_create_new':
11*4882a593Smuzhiyun../sysdeps/unix/sysv/linux/timer_create.c:83:17: warning: array subscript 'struct timer[0]' is partly outside array bounds of 'unsigned char[8]' [-Warray-bounds]
12*4882a593Smuzhiyun   83 |             newp->sigev_notify = (evp != NULL
13*4882a593Smuzhiyun      |                 ^~
14*4882a593Smuzhiyun../sysdeps/unix/sysv/linux/timer_create.c:59:47: note: referencing an object of size 8 allocated by 'malloc'
15*4882a593Smuzhiyun   59 |         struct timer *newp = (struct timer *) malloc (offsetof (struct timer,
16*4882a593Smuzhiyun      |                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17*4882a593Smuzhiyun   60 |                                                                 thrfunc));
18*4882a593Smuzhiyun      |                                                                 ~~~~~~~~~
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunThe struct allocated for !SIGEV_THREAD timers only requires two 'int'
21*4882a593Smuzhiyunfields (sigev_notify and ktimerid) and the offsetof trick tries minimize
22*4882a593Smuzhiyunthe memory usage by only allocation the required size.  However,
23*4882a593Smuzhiyunalthough the resulting size is suffice for !SIGEV_THREAD time, accessing
24*4882a593Smuzhiyunthe partially allocated object is error-prone and UB.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunThis patch fixes both issues by embedding the information whether
27*4882a593Smuzhiyunthe timer if a SIGEV_THREAD in the returned 'timer_t'.  For
28*4882a593Smuzhiyun!SIGEV_THREAD, the resulting 'timer_t' is the returned kernel timer
29*4882a593Smuzhiyunidentifer (kernel_timer_t), while for SIGEV_THREAD it uses the fact
30*4882a593Smuzhiyunmalloc returns at least _Alignof (max_align_t) pointers plus that
31*4882a593Smuzhiyunvalid kernel_timer_t are always positive to set MSB bit of the returned
32*4882a593Smuzhiyun'timer_t' to indicate the timer handles a SIGEV_THREAD.
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunIt allows to remove the memory allocation for !SIGEV_THREAD and also
35*4882a593Smuzhiyunremove the 'sigev_notify' field from 'struct timer'.
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunChecked on x86_64-linux-gnu and i686-linux-gnu.
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun(cherry picked from commit 7a887dd537cd00fe3cdf42b788b3f0e3b430b0ed)
40*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
41*4882a593Smuzhiyun---
42*4882a593Smuzhiyun sysdeps/unix/sysv/linux/kernel-posix-timers.h | 52 ++++++++++---
43*4882a593Smuzhiyun sysdeps/unix/sysv/linux/timer_create.c        | 74 ++++++-------------
44*4882a593Smuzhiyun sysdeps/unix/sysv/linux/timer_delete.c        | 15 ++--
45*4882a593Smuzhiyun sysdeps/unix/sysv/linux/timer_getoverr.c      |  8 +-
46*4882a593Smuzhiyun sysdeps/unix/sysv/linux/timer_gettime.c       |  4 +-
47*4882a593Smuzhiyun sysdeps/unix/sysv/linux/timer_settime.c       |  4 +-
48*4882a593Smuzhiyun 6 files changed, 76 insertions(+), 81 deletions(-)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/sysdeps/unix/sysv/linux/kernel-posix-timers.h
51*4882a593Smuzhiyunindex 31f51997..ad998235 100644
52*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/kernel-posix-timers.h
53*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/kernel-posix-timers.h
54*4882a593Smuzhiyun@@ -43,21 +43,11 @@ extern pthread_mutex_t __active_timer_sigev_thread_lock attribute_hidden;
55*4882a593Smuzhiyun /* Type of timers in the kernel.  */
56*4882a593Smuzhiyun typedef int kernel_timer_t;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun-
59*4882a593Smuzhiyun-/* Internal representation of timer.  */
60*4882a593Smuzhiyun+/* Internal representation of SIGEV_THREAD timer.  */
61*4882a593Smuzhiyun struct timer
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun-  /* Notification mechanism.  */
64*4882a593Smuzhiyun-  int sigev_notify;
65*4882a593Smuzhiyun-
66*4882a593Smuzhiyun-  /* Timer ID returned by the kernel.  */
67*4882a593Smuzhiyun   kernel_timer_t ktimerid;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun-  /* All new elements must be added after ktimerid.  And if the thrfunc
70*4882a593Smuzhiyun-     element is not the third element anymore the memory allocation in
71*4882a593Smuzhiyun-     timer_create needs to be changed.  */
72*4882a593Smuzhiyun-
73*4882a593Smuzhiyun-  /* Parameters for the thread to be started for SIGEV_THREAD.  */
74*4882a593Smuzhiyun   void (*thrfunc) (sigval_t);
75*4882a593Smuzhiyun   sigval_t sival;
76*4882a593Smuzhiyun   pthread_attr_t attr;
77*4882a593Smuzhiyun@@ -65,3 +55,43 @@ struct timer
78*4882a593Smuzhiyun   /* Next element in list of active SIGEV_THREAD timers.  */
79*4882a593Smuzhiyun   struct timer *next;
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun+
82*4882a593Smuzhiyun+
83*4882a593Smuzhiyun+/* For !SIGEV_THREAD, the resulting 'timer_t' is the returned kernel timer
84*4882a593Smuzhiyun+   identifer (kernel_timer_t), while for SIGEV_THREAD it uses the fact malloc
85*4882a593Smuzhiyun+   returns at least _Alignof (max_align_t) pointers plus that valid
86*4882a593Smuzhiyun+   kernel_timer_t are always positive to set the MSB bit of the returned
87*4882a593Smuzhiyun+   'timer_t' to indicate the timer handles a SIGEV_THREAD.  */
88*4882a593Smuzhiyun+
89*4882a593Smuzhiyun+static inline timer_t
90*4882a593Smuzhiyun+kernel_timer_to_timerid (kernel_timer_t ktimerid)
91*4882a593Smuzhiyun+{
92*4882a593Smuzhiyun+  return (timer_t) ((intptr_t) ktimerid);
93*4882a593Smuzhiyun+}
94*4882a593Smuzhiyun+
95*4882a593Smuzhiyun+static inline timer_t
96*4882a593Smuzhiyun+timer_to_timerid (struct timer *ptr)
97*4882a593Smuzhiyun+{
98*4882a593Smuzhiyun+  return (timer_t) (INTPTR_MIN | (uintptr_t) ptr >> 1);
99*4882a593Smuzhiyun+}
100*4882a593Smuzhiyun+
101*4882a593Smuzhiyun+static inline bool
102*4882a593Smuzhiyun+timer_is_sigev_thread (timer_t timerid)
103*4882a593Smuzhiyun+{
104*4882a593Smuzhiyun+  return (intptr_t) timerid < 0;
105*4882a593Smuzhiyun+}
106*4882a593Smuzhiyun+
107*4882a593Smuzhiyun+static inline struct timer *
108*4882a593Smuzhiyun+timerid_to_timer (timer_t timerid)
109*4882a593Smuzhiyun+{
110*4882a593Smuzhiyun+  return (struct timer *)((uintptr_t) timerid << 1);
111*4882a593Smuzhiyun+}
112*4882a593Smuzhiyun+
113*4882a593Smuzhiyun+static inline kernel_timer_t
114*4882a593Smuzhiyun+timerid_to_kernel_timer (timer_t timerid)
115*4882a593Smuzhiyun+{
116*4882a593Smuzhiyun+  if (timer_is_sigev_thread (timerid))
117*4882a593Smuzhiyun+    return timerid_to_timer (timerid)->ktimerid;
118*4882a593Smuzhiyun+  else
119*4882a593Smuzhiyun+    return (kernel_timer_t) ((uintptr_t) timerid);
120*4882a593Smuzhiyun+}
121*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c
122*4882a593Smuzhiyunindex a49a546e..ad4b0d46 100644
123*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/timer_create.c
124*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/timer_create.c
125*4882a593Smuzhiyun@@ -52,16 +52,6 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
126*4882a593Smuzhiyun       {
127*4882a593Smuzhiyun 	struct sigevent local_evp;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun-	/* We avoid allocating too much memory by basically
130*4882a593Smuzhiyun-	   using struct timer as a derived class with the
131*4882a593Smuzhiyun-	   first two elements being in the superclass.  We only
132*4882a593Smuzhiyun-	   need these two elements here.  */
133*4882a593Smuzhiyun-	struct timer *newp = (struct timer *) malloc (offsetof (struct timer,
134*4882a593Smuzhiyun-								thrfunc));
135*4882a593Smuzhiyun-	if (newp == NULL)
136*4882a593Smuzhiyun-	  /* No more memory.  */
137*4882a593Smuzhiyun-	  return -1;
138*4882a593Smuzhiyun-
139*4882a593Smuzhiyun 	if (evp == NULL)
140*4882a593Smuzhiyun 	  {
141*4882a593Smuzhiyun 	    /* The kernel has to pass up the timer ID which is a
142*4882a593Smuzhiyun@@ -69,31 +59,17 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
143*4882a593Smuzhiyun 	       the kernel to determine it.  */
144*4882a593Smuzhiyun 	    local_evp.sigev_notify = SIGEV_SIGNAL;
145*4882a593Smuzhiyun 	    local_evp.sigev_signo = SIGALRM;
146*4882a593Smuzhiyun-	    local_evp.sigev_value.sival_ptr = newp;
147*4882a593Smuzhiyun+	    local_evp.sigev_value.sival_ptr = NULL;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun 	    evp = &local_evp;
150*4882a593Smuzhiyun 	  }
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun 	kernel_timer_t ktimerid;
153*4882a593Smuzhiyun-	int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
154*4882a593Smuzhiyun-				     &ktimerid);
155*4882a593Smuzhiyun-
156*4882a593Smuzhiyun-	if (retval != -1)
157*4882a593Smuzhiyun-	  {
158*4882a593Smuzhiyun-	    newp->sigev_notify = (evp != NULL
159*4882a593Smuzhiyun-				  ? evp->sigev_notify : SIGEV_SIGNAL);
160*4882a593Smuzhiyun-	    newp->ktimerid = ktimerid;
161*4882a593Smuzhiyun-
162*4882a593Smuzhiyun-	    *timerid = (timer_t) newp;
163*4882a593Smuzhiyun-	  }
164*4882a593Smuzhiyun-	else
165*4882a593Smuzhiyun-	  {
166*4882a593Smuzhiyun-	    /* Cannot allocate the timer, fail.  */
167*4882a593Smuzhiyun-	    free (newp);
168*4882a593Smuzhiyun-	    retval = -1;
169*4882a593Smuzhiyun-	  }
170*4882a593Smuzhiyun+	if (INLINE_SYSCALL_CALL (timer_create, syscall_clockid, evp,
171*4882a593Smuzhiyun+				 &ktimerid) == -1)
172*4882a593Smuzhiyun+	  return -1;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun-	return retval;
175*4882a593Smuzhiyun+	*timerid = kernel_timer_to_timerid (ktimerid);
176*4882a593Smuzhiyun       }
177*4882a593Smuzhiyun     else
178*4882a593Smuzhiyun       {
179*4882a593Smuzhiyun@@ -106,20 +82,18 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
180*4882a593Smuzhiyun 	    return -1;
181*4882a593Smuzhiyun 	  }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun-	struct timer *newp;
184*4882a593Smuzhiyun-	newp = (struct timer *) malloc (sizeof (struct timer));
185*4882a593Smuzhiyun+	struct timer *newp = malloc (sizeof (struct timer));
186*4882a593Smuzhiyun 	if (newp == NULL)
187*4882a593Smuzhiyun 	  return -1;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun 	/* Copy the thread parameters the user provided.  */
190*4882a593Smuzhiyun 	newp->sival = evp->sigev_value;
191*4882a593Smuzhiyun 	newp->thrfunc = evp->sigev_notify_function;
192*4882a593Smuzhiyun-	newp->sigev_notify = SIGEV_THREAD;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun 	/* We cannot simply copy the thread attributes since the
195*4882a593Smuzhiyun 	   implementation might keep internal information for
196*4882a593Smuzhiyun 	   each instance.  */
197*4882a593Smuzhiyun-	(void) pthread_attr_init (&newp->attr);
198*4882a593Smuzhiyun+	pthread_attr_init (&newp->attr);
199*4882a593Smuzhiyun 	if (evp->sigev_notify_attributes != NULL)
200*4882a593Smuzhiyun 	  {
201*4882a593Smuzhiyun 	    struct pthread_attr *nattr;
202*4882a593Smuzhiyun@@ -137,8 +111,7 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
203*4882a593Smuzhiyun 	  }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun 	/* In any case set the detach flag.  */
206*4882a593Smuzhiyun-	(void) pthread_attr_setdetachstate (&newp->attr,
207*4882a593Smuzhiyun-					    PTHREAD_CREATE_DETACHED);
208*4882a593Smuzhiyun+	pthread_attr_setdetachstate (&newp->attr, PTHREAD_CREATE_DETACHED);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun 	/* Create the event structure for the kernel timer.  */
211*4882a593Smuzhiyun 	struct sigevent sev =
212*4882a593Smuzhiyun@@ -150,27 +123,24 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
213*4882a593Smuzhiyun 	/* Create the timer.  */
214*4882a593Smuzhiyun 	INTERNAL_SYSCALL_DECL (err);
215*4882a593Smuzhiyun 	int res;
216*4882a593Smuzhiyun-	res = INTERNAL_SYSCALL (timer_create, err, 3,
217*4882a593Smuzhiyun-				syscall_clockid, &sev, &newp->ktimerid);
218*4882a593Smuzhiyun-	if (! INTERNAL_SYSCALL_ERROR_P (res, err))
219*4882a593Smuzhiyun+	res = INTERNAL_SYSCALL_CALL (timer_create, syscall_clockid, &sev,
220*4882a593Smuzhiyun+				     &newp->ktimerid);
221*4882a593Smuzhiyun+	if (INTERNAL_SYSCALL_ERROR_P (res, err))
222*4882a593Smuzhiyun 	  {
223*4882a593Smuzhiyun-	    /* Add to the queue of active timers with thread
224*4882a593Smuzhiyun-	       delivery.  */
225*4882a593Smuzhiyun-	    pthread_mutex_lock (&__active_timer_sigev_thread_lock);
226*4882a593Smuzhiyun-	    newp->next = __active_timer_sigev_thread;
227*4882a593Smuzhiyun-	    __active_timer_sigev_thread = newp;
228*4882a593Smuzhiyun-	    pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
229*4882a593Smuzhiyun-
230*4882a593Smuzhiyun-	    *timerid = (timer_t) newp;
231*4882a593Smuzhiyun-	    return 0;
232*4882a593Smuzhiyun+	    free (newp);
233*4882a593Smuzhiyun+	    __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
234*4882a593Smuzhiyun+	    return -1;
235*4882a593Smuzhiyun 	  }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun-	/* Free the resources.  */
238*4882a593Smuzhiyun-	free (newp);
239*4882a593Smuzhiyun-
240*4882a593Smuzhiyun-	__set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
241*4882a593Smuzhiyun+	/* Add to the queue of active timers with thread delivery.  */
242*4882a593Smuzhiyun+	pthread_mutex_lock (&__active_timer_sigev_thread_lock);
243*4882a593Smuzhiyun+	newp->next = __active_timer_sigev_thread;
244*4882a593Smuzhiyun+	__active_timer_sigev_thread = newp;
245*4882a593Smuzhiyun+	pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun-	return -1;
248*4882a593Smuzhiyun+	*timerid = timer_to_timerid (newp);
249*4882a593Smuzhiyun       }
250*4882a593Smuzhiyun   }
251*4882a593Smuzhiyun+
252*4882a593Smuzhiyun+  return 0;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/timer_delete.c b/sysdeps/unix/sysv/linux/timer_delete.c
255*4882a593Smuzhiyunindex e1eb1db5..be459dc3 100644
256*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/timer_delete.c
257*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/timer_delete.c
258*4882a593Smuzhiyun@@ -32,15 +32,15 @@ int
259*4882a593Smuzhiyun timer_delete (timer_t timerid)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun #undef timer_delete
262*4882a593Smuzhiyun-  struct timer *kt = (struct timer *) timerid;
263*4882a593Smuzhiyun-
264*4882a593Smuzhiyun-  /* Delete the kernel timer object.  */
265*4882a593Smuzhiyun-  int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);
266*4882a593Smuzhiyun+  kernel_timer_t ktimerid = timerid_to_kernel_timer (timerid);
267*4882a593Smuzhiyun+  int res = INLINE_SYSCALL_CALL (timer_delete, ktimerid);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun   if (res == 0)
270*4882a593Smuzhiyun     {
271*4882a593Smuzhiyun-      if (kt->sigev_notify == SIGEV_THREAD)
272*4882a593Smuzhiyun+      if (timer_is_sigev_thread (timerid))
273*4882a593Smuzhiyun 	{
274*4882a593Smuzhiyun+	  struct timer *kt = timerid_to_timer (timerid);
275*4882a593Smuzhiyun+
276*4882a593Smuzhiyun 	  /* Remove the timer from the list.  */
277*4882a593Smuzhiyun 	  pthread_mutex_lock (&__active_timer_sigev_thread_lock);
278*4882a593Smuzhiyun 	  if (__active_timer_sigev_thread == kt)
279*4882a593Smuzhiyun@@ -58,10 +58,9 @@ timer_delete (timer_t timerid)
280*4882a593Smuzhiyun 		  prevp = prevp->next;
281*4882a593Smuzhiyun 	    }
282*4882a593Smuzhiyun 	  pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
283*4882a593Smuzhiyun-	}
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun-      /* Free the memory.  */
286*4882a593Smuzhiyun-      (void) free (kt);
287*4882a593Smuzhiyun+	  free (kt);
288*4882a593Smuzhiyun+	}
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun       return 0;
291*4882a593Smuzhiyun     }
292*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/timer_getoverr.c b/sysdeps/unix/sysv/linux/timer_getoverr.c
293*4882a593Smuzhiyunindex 26f23e1d..0dfcbe81 100644
294*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/timer_getoverr.c
295*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/timer_getoverr.c
296*4882a593Smuzhiyun@@ -31,10 +31,6 @@ int
297*4882a593Smuzhiyun timer_getoverrun (timer_t timerid)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun #undef timer_getoverrun
300*4882a593Smuzhiyun-  struct timer *kt = (struct timer *) timerid;
301*4882a593Smuzhiyun-
302*4882a593Smuzhiyun-  /* Get the information from the kernel.  */
303*4882a593Smuzhiyun-  int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid);
304*4882a593Smuzhiyun-
305*4882a593Smuzhiyun-  return res;
306*4882a593Smuzhiyun+  kernel_timer_t ktimerid = timerid_to_kernel_timer (timerid);
307*4882a593Smuzhiyun+  return INLINE_SYSCALL_CALL (timer_getoverrun, ktimerid);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c
310*4882a593Smuzhiyunindex 10a19d9e..a3e1981a 100644
311*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/timer_gettime.c
312*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/timer_gettime.c
313*4882a593Smuzhiyun@@ -32,10 +32,10 @@ int
314*4882a593Smuzhiyun timer_gettime (timer_t timerid, struct itimerspec *value)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun #undef timer_gettime
317*4882a593Smuzhiyun-  struct timer *kt = (struct timer *) timerid;
318*4882a593Smuzhiyun+  kernel_timer_t ktimerid = timerid_to_kernel_timer (timerid);
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun   /* Delete the kernel timer object.  */
321*4882a593Smuzhiyun-  int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
322*4882a593Smuzhiyun+  int res = INLINE_SYSCALL (timer_gettime, 2, ktimerid, value);
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun   return res;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyundiff --git a/sysdeps/unix/sysv/linux/timer_settime.c b/sysdeps/unix/sysv/linux/timer_settime.c
327*4882a593Smuzhiyunindex 7c938bd4..7038e2a7 100644
328*4882a593Smuzhiyun--- a/sysdeps/unix/sysv/linux/timer_settime.c
329*4882a593Smuzhiyun+++ b/sysdeps/unix/sysv/linux/timer_settime.c
330*4882a593Smuzhiyun@@ -33,10 +33,10 @@ timer_settime (timer_t timerid, int flags, const struct itimerspec *value,
331*4882a593Smuzhiyun 	       struct itimerspec *ovalue)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun #undef timer_settime
334*4882a593Smuzhiyun-  struct timer *kt = (struct timer *) timerid;
335*4882a593Smuzhiyun+  kernel_timer_t ktimerid = timerid_to_kernel_timer (timerid);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun   /* Delete the kernel timer object.  */
338*4882a593Smuzhiyun-  int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
339*4882a593Smuzhiyun+  int res = INLINE_SYSCALL (timer_settime, 4, ktimerid, flags,
340*4882a593Smuzhiyun 			    value, ovalue);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun   return res;
343*4882a593Smuzhiyun--
344*4882a593Smuzhiyun2.20.1
345*4882a593Smuzhiyun
346