blob: bb7c84cac48faeb13acca83ed8d64c0807fcdf78 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- Update the byte permission maps following a system call. ---*/
4/*--- vg_syscall_mem.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32#include "vg_include.h"
33
34/* vg_unsafe.h should NOT be included into any file except this
35 one. */
36#include "vg_unsafe.h"
37
38
39/* All system calls are channelled through vg_wrap_syscall. It does
40 three things:
41
42 * optionally, checks the permissions for the args to the call
43
44 * perform the syscall, usually by passing it along to the kernel
45 unmodified. However, because we simulate signals ourselves,
46 signal-related syscalls are routed to vg_signal.c, and are not
47 delivered to the kernel.
48
49 * Update the permission maps following the syscall.
50
51 A magical piece of assembly code, vg_do_syscall(), in vg_syscall.S
52 does the tricky bit of passing a syscall to the kernel, whilst
53 having the simulator retain control.
54*/
55
56static void make_noaccess ( Addr a, UInt len )
57{
58 if (VG_(clo_instrument))
59 VGM_(make_noaccess) ( a, len );
60}
61
62static void make_writable ( Addr a, UInt len )
63{
64 if (VG_(clo_instrument))
65 VGM_(make_writable) ( a, len );
66}
67
68static void make_readable ( Addr a, UInt len )
69{
70 if (VG_(clo_instrument))
71 VGM_(make_readable) ( a, len );
72}
73
74static void make_readwritable ( Addr a, UInt len )
75{
76 if (VG_(clo_instrument))
77 VGM_(make_readwritable) ( a, len );
78}
79
80static
sewardj8c824512002-04-14 04:16:48 +000081void must_be_writable ( ThreadState* tst,
82 Char* syscall_name, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +000083{
84 Bool ok;
85 Addr bad_addr;
86 /* VG_(message)(Vg_DebugMsg,"must be writable: %x .. %x",
87 base,base+size-1); */
88 if (!VG_(clo_instrument))
89 return;
90 ok = VGM_(check_writable) ( base, size, &bad_addr );
91 if (!ok)
sewardj8c824512002-04-14 04:16:48 +000092 VG_(record_param_err) ( tst, bad_addr, True, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +000093}
94
95static
sewardj8c824512002-04-14 04:16:48 +000096void must_be_readable ( ThreadState* tst,
97 Char* syscall_name, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +000098{
99 Bool ok;
100 Addr bad_addr;
101 /* VG_(message)(Vg_DebugMsg,"must be readable: %x .. %x",
102 base,base+size-1); */
103 if (!VG_(clo_instrument))
104 return;
105 ok = VGM_(check_readable) ( base, size, &bad_addr );
106 if (!ok)
sewardj8c824512002-04-14 04:16:48 +0000107 VG_(record_param_err) ( tst, bad_addr, False, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +0000108}
109
110static
sewardj8c824512002-04-14 04:16:48 +0000111void must_be_readable_asciiz ( ThreadState* tst,
112 Char* syscall_name, UInt str )
sewardjde4a1d02002-03-22 01:27:54 +0000113{
114 Bool ok = True;
115 Addr bad_addr;
116 /* VG_(message)(Vg_DebugMsg,"must be readable asciiz: 0x%x",str); */
117 if (!VG_(clo_instrument))
118 return;
119 ok = VGM_(check_readable_asciiz) ( (Addr)str, &bad_addr );
120 if (!ok)
sewardj8c824512002-04-14 04:16:48 +0000121 VG_(record_param_err) ( tst, bad_addr, False, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +0000122}
123
124
125/* Set memory permissions, based on PROT_* values for mmap/mprotect,
126 into the permissions our scheme understands. Dunno if this is
127 really correct. */
128
129static void approximate_mmap_permissions ( Addr a, UInt len, UInt prot )
130{
131 /* PROT_READ and PROT_WRITE --> readable
132 PROT_READ only --> readable
133 PROT_WRITE only --> writable
134 NEITHER --> noaccess
135 */
136 if (prot & PROT_READ)
137 make_readable(a,len);
138 else
139 if (prot & PROT_WRITE)
140 make_writable(a,len);
141 else
142 make_noaccess(a,len);
143}
144
145
146/* Dereference a pointer, but only after checking that it's
147 safe to do so. If not, return the default.
148*/
149static
150UInt safe_dereference ( Addr aa, UInt defawlt )
151{
152 if (!VG_(clo_instrument))
153 return * (UInt*)aa;
154 if (VGM_(check_readable)(aa,4,NULL))
155 return * (UInt*)aa;
156 else
157 return defawlt;
158}
159
160
161/* Is this a Linux kernel error return value? */
162/* From:
163 http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
164 linux/i386/sysdep.h?
165 rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
166
167 QUOTE:
168
169 Linux uses a negative return value to indicate syscall errors,
170 unlike most Unices, which use the condition codes' carry flag.
171
172 Since version 2.1 the return value of a system call might be
173 negative even if the call succeeded. E.g., the `lseek' system call
174 might return a large offset. Therefore we must not anymore test
175 for < 0, but test for a real error by making sure the value in %eax
176 is a real error number. Linus said he will make sure the no syscall
177 returns a value in -1 .. -4095 as a valid result so we can savely
178 test with -4095.
179
180 END QUOTE
181*/
182Bool VG_(is_kerror) ( Int res )
183{
184 if (res >= -4095 && res <= -1)
185 return True;
186 else
187 return False;
188}
189
190static
191UInt get_shm_size ( Int shmid )
192{
193 struct shmid_ds buf;
194 long __res;
195 __asm__ volatile ( "int $0x80"
196 : "=a" (__res)
197 : "0" (__NR_ipc),
198 "b" ((long)(24) /*IPCOP_shmctl*/),
199 "c" ((long)(shmid)),
200 "d" ((long)(IPC_STAT)),
201 "S" ((long)(0)),
202 "D" ((long)(&buf)) );
203 if ( VG_(is_kerror) ( __res ) )
204 return 0;
205
206 return buf.shm_segsz;
207}
208
209static
sewardj8c824512002-04-14 04:16:48 +0000210Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000211{
212 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
213 Char *result = VG_(malloc) ( aid, len );
214 VG_(strcpy) ( result, s1 );
215 VG_(strcat) ( result, s2 );
216 return result;
217}
218
219static
sewardj8c824512002-04-14 04:16:48 +0000220void must_be_readable_sendmsg ( ThreadState* tst,
221 Char *msg, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000222{
223 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_TRANSIENT );
sewardj8c824512002-04-14 04:16:48 +0000224 must_be_readable ( tst, outmsg, base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000225 VG_(free) ( VG_AR_TRANSIENT, outmsg );
226}
227
228static
sewardj8c824512002-04-14 04:16:48 +0000229void must_be_writable_recvmsg ( ThreadState* tst,
230 Char *msg, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000231{
232 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_TRANSIENT );
sewardj8c824512002-04-14 04:16:48 +0000233 must_be_writable ( tst, outmsg, base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000234 VG_(free) ( VG_AR_TRANSIENT, outmsg );
235}
236
237static
sewardj8c824512002-04-14 04:16:48 +0000238void make_readable_recvmsg ( ThreadState* tst,
239 Char *fieldName, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000240{
241 make_readable( base, size );
242}
243
244static
sewardj8c824512002-04-14 04:16:48 +0000245void msghdr_foreachfield (
246 ThreadState* tst,
247 struct msghdr *msg,
248 void (*foreach_func)( ThreadState*, Char *, UInt, UInt )
249 )
sewardjde4a1d02002-03-22 01:27:54 +0000250{
251 if ( !msg )
252 return;
253
sewardj8c824512002-04-14 04:16:48 +0000254 foreach_func ( tst, "(msg)", (Addr)msg, sizeof( struct msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000255
256 if ( msg->msg_name )
sewardj8c824512002-04-14 04:16:48 +0000257 foreach_func ( tst,
258 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000259 (Addr)msg->msg_name, msg->msg_namelen );
260
261 if ( msg->msg_iov ) {
262 struct iovec *iov = msg->msg_iov;
263 UInt i;
264
sewardj8c824512002-04-14 04:16:48 +0000265 foreach_func ( tst,
266 "(msg.msg_iov)",
sewardjde4a1d02002-03-22 01:27:54 +0000267 (Addr)iov, msg->msg_iovlen * sizeof( struct iovec ) );
268
269 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
sewardj8c824512002-04-14 04:16:48 +0000270 foreach_func ( tst,
271 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000272 (Addr)iov->iov_base, iov->iov_len );
273 }
274
275 if ( msg->msg_control )
sewardj8c824512002-04-14 04:16:48 +0000276 foreach_func ( tst,
277 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000278 (Addr)msg->msg_control, msg->msg_controllen );
279}
280
sewardjc483e8f2002-05-03 21:01:35 +0000281static
282void must_be_readable_sockaddr ( ThreadState* tst,
283 Char *description,
284 struct sockaddr *sa, UInt salen )
285{
286 Char *outmsg = VG_(malloc) ( VG_AR_TRANSIENT, strlen( description ) + 30 );
287
288 VG_(sprintf) ( outmsg, description, ".sa_family" );
289 must_be_readable( tst, outmsg, (UInt) &sa->sa_family, sizeof (sa_family_t));
290
291 switch (sa->sa_family) {
292
293 case AF_UNIX:
294 VG_(sprintf) ( outmsg, description, ".sun_path" );
295 must_be_readable_asciiz( tst, outmsg,
296 (UInt) ((struct sockaddr_un *) sa)->sun_path);
297 break;
298
299 case AF_INET:
300 VG_(sprintf) ( outmsg, description, ".sin_port" );
301 must_be_readable( tst, outmsg,
302 (UInt) &((struct sockaddr_in *) sa)->sin_port,
sewardj32102152002-05-04 10:28:17 +0000303 sizeof (((struct sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000304 VG_(sprintf) ( outmsg, description, ".sin_addr" );
305 must_be_readable( tst, outmsg,
306 (UInt) &((struct sockaddr_in *) sa)->sin_addr,
307 sizeof (struct in_addr));
308 break;
309
310 case AF_INET6:
311 VG_(sprintf) ( outmsg, description, ".sin6_port" );
312 must_be_readable( tst, outmsg,
313 (UInt) &((struct sockaddr_in6 *) sa)->sin6_port,
sewardj32102152002-05-04 10:28:17 +0000314 sizeof (((struct sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000315 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
316 must_be_readable( tst, outmsg,
317 (UInt) &((struct sockaddr_in6 *) sa)->sin6_flowinfo,
318 sizeof (uint32_t));
319 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
320 must_be_readable( tst, outmsg,
321 (UInt) &((struct sockaddr_in6 *) sa)->sin6_addr,
322 sizeof (struct in6_addr));
sewardj32102152002-05-04 10:28:17 +0000323# ifndef GLIBC_2_1
sewardjc483e8f2002-05-03 21:01:35 +0000324 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
325 must_be_readable( tst, outmsg,
326 (UInt) &((struct sockaddr_in6 *) sa)->sin6_scope_id,
327 sizeof (uint32_t));
sewardj32102152002-05-04 10:28:17 +0000328# endif
sewardjc483e8f2002-05-03 21:01:35 +0000329 break;
330
331 default:
332 VG_(sprintf) ( outmsg, description, "" );
333 must_be_readable( tst, outmsg, (UInt) sa, salen );
334 break;
335 }
336
337 VG_(free) ( VG_AR_TRANSIENT, outmsg );
338}
339
sewardjde4a1d02002-03-22 01:27:54 +0000340
341/* Records the current end of the data segment so we can make sense of
342 calls to brk(). Initial value set by hdm_init_memory_audit(). */
343Addr VGM_(curr_dataseg_end);
344
345
sewardj2e93c502002-04-12 11:12:52 +0000346
sewardjde4a1d02002-03-22 01:27:54 +0000347/* The Main Entertainment ... */
348
sewardj2e93c502002-04-12 11:12:52 +0000349void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +0000350{
sewardj018f7622002-05-15 21:13:39 +0000351 ThreadState* tst;
352 Bool sane_before_call, sane_after_call;
353 UInt syscallno, arg1, arg2, arg3, arg4, arg5;
sewardjde4a1d02002-03-22 01:27:54 +0000354 /* Do not make this unsigned! */
355 Int res;
356
sewardjde4a1d02002-03-22 01:27:54 +0000357 VGP_PUSHCC(VgpSyscall);
358
sewardj018f7622002-05-15 21:13:39 +0000359 vg_assert(VG_(is_valid_tid)(tid));
360 sane_before_call = True;
361 sane_after_call = True;
362 tst = & VG_(threads)[tid];
363 syscallno = tst->m_eax;
364 arg1 = tst->m_ebx;
365 arg2 = tst->m_ecx;
366 arg3 = tst->m_edx;
367 arg4 = tst->m_esi;
368 arg5 = tst->m_edi;
369
sewardjde4a1d02002-03-22 01:27:54 +0000370 /* Since buggy syscall wrappers sometimes break this, we may as well
371 check ourselves. */
sewardj126a41f2002-05-07 23:45:03 +0000372 if (! VG_(first_and_last_secondaries_look_plausible)())
sewardjde4a1d02002-03-22 01:27:54 +0000373 sane_before_call = False;
374
375 /* the syscall no is in %eax. For syscalls with <= 5 args,
376 args 1 .. 5 to the syscall are in %ebx %ecx %edx %esi %edi.
377 For calls with > 5 args, %ebx points to a lump of memory
378 containing the args.
379
380 The result is returned in %eax. If this value >= 0, the call
381 succeeded, and this is the return value. If < 0, it failed, and
382 the negation of this value is errno. To be more specific,
383 if res is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
384 (kernel 2.4.9 sources, include/asm-i386/errno.h)
385 then it indicates an error. Otherwise it doesn't.
386
387 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
388 (inclusive?) indicate error returns. Not sure where the -4095
389 comes from.
390 */
391
392 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000393 VG_(printf)("SYSCALL[%d,%d](%3d): ",
394 VG_(getpid)(), tid, syscallno);
sewardjde4a1d02002-03-22 01:27:54 +0000395
396 switch (syscallno) {
397
sewardj7e87e382002-05-03 19:09:05 +0000398 case __NR_exit:
399 VG_(panic)("syscall exit() not caught by the scheduler?!");
400 break;
401
sewardjde4a1d02002-03-22 01:27:54 +0000402 case __NR_clone:
403 VG_(unimplemented)
sewardj827d95b2002-04-16 02:09:31 +0000404 ("clone(): not supported by Valgrind.\n "
405 "We do now support programs linked against\n "
406 "libpthread.so, though. Re-run with -v and ensure that\n "
407 "you are picking up Valgrind's implementation of libpthread.so.");
sewardjde4a1d02002-03-22 01:27:54 +0000408 break;
409
410# if defined(__NR_modify_ldt)
411 case __NR_modify_ldt:
sewardjcfc39b22002-05-08 01:58:18 +0000412 VG_(nvidia_moan)();
sewardjde4a1d02002-03-22 01:27:54 +0000413 VG_(unimplemented)
sewardjcfc39b22002-05-08 01:58:18 +0000414 ("modify_ldt(): I (JRS) haven't investigated this yet; sorry.");
sewardjde4a1d02002-03-22 01:27:54 +0000415 break;
416# endif
417
sewardj73f1f072002-03-29 14:22:46 +0000418 /* !!!!!!!!!! New, untested syscalls !!!!!!!!!!!!!!!!!!!!! */
419
sewardj67f1d582002-05-24 02:11:32 +0000420# if defined(__NR_msync) /* syscall 144 */
421 case __NR_msync:
422 /* int msync(const void *start, size_t length, int flags); */
423 if (VG_(clo_trace_syscalls))
424 VG_(printf)("msync ( %p, %d, %d )\n", arg1,arg2,arg3);
425 must_be_readable( tst, "msync(start)", arg1, arg2 );
426 KERNEL_DO_SYSCALL(tid,res);
427 break;
428# endif
429
sewardj0ff15782002-05-18 13:24:24 +0000430# if defined(__NR_getpmsg) /* syscall 188 */
431 case __NR_getpmsg:
432 {
433 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
434 /* int getpmsg(int fd, struct strbuf *ctrl, struct strbuf *data,
435 int *bandp, int *flagsp); */
436 struct strbuf {
437 int maxlen; /* no. of bytes in buffer */
438 int len; /* no. of bytes returned */
439 caddr_t buf; /* pointer to data */
440 };
441 struct strbuf *ctrl;
442 struct strbuf *data;
443 if (VG_(clo_trace_syscalls))
444 VG_(printf)("getpmsg ( %d, %p, %p, %p, %p )\n",
445 arg1,arg2,arg3,arg4,arg5);
446 ctrl = (struct strbuf *)arg2;
447 data = (struct strbuf *)arg3;
448 if (ctrl && ctrl->maxlen > 0)
449 must_be_writable(tst, "getpmsg(ctrl)",
450 (UInt)ctrl->buf, ctrl->maxlen);
451 if (data && data->maxlen > 0)
452 must_be_writable(tst, "getpmsg(data)",
453 (UInt)data->buf, data->maxlen);
454 if (arg4)
455 must_be_writable(tst, "getpmsg(bandp)",
456 (UInt)arg4, sizeof(int));
457 if (arg5)
458 must_be_writable(tst, "getpmsg(flagsp)",
459 (UInt)arg5, sizeof(int));
460 KERNEL_DO_SYSCALL(tid,res);
461 if (!VG_(is_kerror)(res) && res == 0 && ctrl && ctrl->len > 0) {
462 make_readable( (UInt)ctrl->buf, ctrl->len);
463 }
464 if (!VG_(is_kerror)(res) && res == 0 && data && data->len > 0) {
465 make_readable( (UInt)data->buf, data->len);
466 }
467 }
468 break;
469# endif
470
471
472# if defined(__NR_putpmsg) /* syscall 189 */
473 case __NR_putpmsg:
474 {
475 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
476 /* int putpmsg(int fd, struct strbuf *ctrl, struct strbuf *data,
477 int band, int flags); */
478 struct strbuf {
479 int maxlen; /* no. of bytes in buffer */
480 int len; /* no. of bytes returned */
481 caddr_t buf; /* pointer to data */
482 };
483 struct strbuf *ctrl;
484 struct strbuf *data;
485 if (VG_(clo_trace_syscalls))
486 VG_(printf)("putpmsg ( %d, %p, %p, %d, %d )\n",
487 arg1,arg2,arg3,arg4,arg5);
488 ctrl = (struct strbuf *)arg2;
489 data = (struct strbuf *)arg3;
490 if (ctrl && ctrl->len > 0)
491 must_be_readable(tst, "putpmsg(ctrl)",
492 (UInt)ctrl->buf, ctrl->len);
493 if (data && data->len > 0)
494 must_be_readable(tst, "putpmsg(data)",
495 (UInt)data->buf, data->len);
496 KERNEL_DO_SYSCALL(tid,res);
497 }
498 break;
499# endif
500
sewardj9e631f72002-05-18 11:01:06 +0000501 case __NR_getitimer: /* syscall 105 */
502 /* int getitimer(int which, struct itimerval *value); */
503 if (VG_(clo_trace_syscalls))
504 VG_(printf)("getitimer ( %d, %p )\n", arg1, arg2);
505 must_be_writable( tst, "getitimer(timer)", arg2,
506 sizeof(struct itimerval) );
507 KERNEL_DO_SYSCALL(tid,res);
508 if (!VG_(is_kerror)(res) && arg2 != (Addr)NULL) {
509 make_readable(arg2, sizeof(struct itimerval));
510 }
511 break;
512
sewardjd354bb32002-05-10 22:58:14 +0000513# if defined(__NR_syslog)
514 case __NR_syslog: /* syscall 103 */
515 /* int syslog(int type, char *bufp, int len); */
516 if (VG_(clo_trace_syscalls))
517 VG_(printf)("syslog (%d, %p, %d)\n",arg1,arg2,arg3);
518 switch(arg1) {
519 case 2: case 3: case 4:
520 must_be_writable( tst, "syslog(buf)", arg2, arg3);
521 break;
522 default:
523 break;
524 }
525 KERNEL_DO_SYSCALL(tid, res);
526 if (!VG_(is_kerror)(res)) {
527 switch (arg1) {
528 case 2: case 3: case 4:
529 make_readable( arg2, arg3 );
530 break;
531 default:
532 break;
533 }
534 }
535 break;
536# endif
537
sewardjf4afb002002-05-10 21:01:34 +0000538 case __NR_personality: /* syscall 136 */
sewardjd354bb32002-05-10 22:58:14 +0000539 /* int personality(unsigned long persona); */
sewardjf4afb002002-05-10 21:01:34 +0000540 if (VG_(clo_trace_syscalls))
541 VG_(printf)("personality ( %d )\n", arg1);
542 KERNEL_DO_SYSCALL(tid,res);
543 break;
544
sewardjfb617112002-05-03 21:07:55 +0000545 case __NR_chroot: /* syscall 61 */
546 /* int chroot(const char *path); */
547 if (VG_(clo_trace_syscalls))
548 VG_(printf)("chroot ( %p )\n", arg1);
549 must_be_readable_asciiz( tst, "chroot(path)", arg1 );
550 KERNEL_DO_SYSCALL(tid,res);
551 break;
552
sewardj6e435c02002-04-24 02:24:44 +0000553# if defined(__NR_madvise)
554 case __NR_madvise: /* syscall 219 */
555 /* int madvise(void *start, size_t length, int advice ); */
556 if (VG_(clo_trace_syscalls))
557 VG_(printf)("madvise ( %p, %d, %d )\n", arg1,arg2,arg3);
558 KERNEL_DO_SYSCALL(tid,res);
559 break;
560# endif
561
sewardj6af4b5d2002-04-16 04:40:49 +0000562# if defined(__NR_mremap)
563 /* Is this really right? Perhaps it should copy the permissions
564 from the old area into the new. Unclear from the Linux man
565 pages what this really does. Also, the flags don't look like
566 they mean the same as the standard mmap flags, so that's
567 probably wrong too. */
568 case __NR_mremap: /* syscall 163 */
569 /* void* mremap(void * old_address, size_t old_size,
570 size_t new_size, unsigned long flags); */
571 if (VG_(clo_trace_syscalls))
572 VG_(printf)("mremap ( %p, %d, %d, 0x%x )\n",
573 arg1, arg2, arg3, arg4);
574 must_be_writable ( tst, "mremap(old_address)", arg1, arg2 );
575 KERNEL_DO_SYSCALL(tid,res);
576 if (!VG_(is_kerror)(res)) {
577 /* Copied from munmap() wrapper. */
sewardj18d75132002-05-16 11:06:21 +0000578 Bool munmap_exe;
sewardj6af4b5d2002-04-16 04:40:49 +0000579 Addr start = arg1;
580 Addr length = arg2;
581 while ((start % VKI_BYTES_PER_PAGE) > 0) { start--; length++; }
582 while (((start+length) % VKI_BYTES_PER_PAGE) > 0) { length++; }
583 make_noaccess( start, length );
sewardj18d75132002-05-16 11:06:21 +0000584 munmap_exe = VG_(symtab_notify_munmap) ( start, length );
585 if (munmap_exe)
586 VG_(invalidate_translations) ( start, length );
sewardj6af4b5d2002-04-16 04:40:49 +0000587 approximate_mmap_permissions( (Addr)res, arg3, arg4 );
588 }
589 break;
590# endif
591
sewardj73f1f072002-03-29 14:22:46 +0000592 case __NR_nice: /* syscall 34 */
593 /* int nice(int inc); */
594 if (VG_(clo_trace_syscalls))
595 VG_(printf)("nice ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000596 KERNEL_DO_SYSCALL(tid,res);
sewardj73f1f072002-03-29 14:22:46 +0000597 break;
598
sewardjde4a1d02002-03-22 01:27:54 +0000599 /* !!!!!!!!!! New, untested syscalls, 14 Mar 02 !!!!!!!!!! */
600
sewardjd7f07662002-03-24 10:49:46 +0000601# if defined(__NR_setresgid32)
602 case __NR_setresgid32: /* syscall 210 */
603 /* int setresgid(gid_t rgid, gid_t egid, gid_t sgid); */
604 if (VG_(clo_trace_syscalls))
605 VG_(printf)("setresgid32 ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +0000606 KERNEL_DO_SYSCALL(tid,res);
sewardjd7f07662002-03-24 10:49:46 +0000607 break;
608# endif
609
sewardjde4a1d02002-03-22 01:27:54 +0000610# if defined(__NR_setfsuid32)
611 case __NR_setfsuid32: /* syscall 215 */
612 /* int setfsuid(uid_t fsuid); */
613 if (VG_(clo_trace_syscalls))
614 VG_(printf)("setfsuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000615 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000616 break;
617# endif
618
619# if defined(__NR__sysctl)
620 case __NR__sysctl:
621 /* int _sysctl(struct __sysctl_args *args); */
622 if (VG_(clo_trace_syscalls))
623 VG_(printf)("_sysctl ( %p )\n", arg1 );
sewardj8c824512002-04-14 04:16:48 +0000624 must_be_writable ( tst, "_sysctl(args)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000625 sizeof(struct __sysctl_args) );
sewardj2e93c502002-04-12 11:12:52 +0000626 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000627 if (!VG_(is_kerror)(res))
628 make_readable ( arg1, sizeof(struct __sysctl_args) );
629 break;
630# endif
631
632# if defined(__NR_sched_getscheduler)
633 case __NR_sched_getscheduler:
634 /* int sched_getscheduler(pid_t pid); */
635 if (VG_(clo_trace_syscalls))
636 VG_(printf)("sched_getscheduler ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000637 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000638 break;
639# endif
640
641# if defined(__NR_sched_setscheduler)
642 case __NR_sched_setscheduler:
643 /* int sched_setscheduler(pid_t pid, int policy,
644 const struct sched_param *p); */
645 if (VG_(clo_trace_syscalls))
646 VG_(printf)("sched_setscheduler ( %d, %d, %p )\n",arg1,arg2,arg3);
647 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +0000648 must_be_readable( tst,
649 "sched_setscheduler(struct sched_param *p)",
sewardjde4a1d02002-03-22 01:27:54 +0000650 arg3, sizeof(struct sched_param));
sewardj2e93c502002-04-12 11:12:52 +0000651 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000652 break;
653# endif
654
655# if defined(__NR_mlockall)
656 case __NR_mlockall:
657 /* int mlockall(int flags); */
658 if (VG_(clo_trace_syscalls))
659 VG_(printf)("mlockall ( %x )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000660 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000661 break;
662# endif
663
664# if defined(__NR_munlockall)
665 case __NR_munlockall:
666 /* int munlockall(void); */
667 if (VG_(clo_trace_syscalls))
668 VG_(printf)("munlockall ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000669 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000670 break;
671# endif
672
673#if defined(__NR_sched_get_priority_max)
674 case __NR_sched_get_priority_max:
675 /* int sched_get_priority_max(int policy); */
676 if (VG_(clo_trace_syscalls))
677 VG_(printf)("sched_get_priority_max ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000678 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000679 break;
680# endif
681
sewardj9dfb4a72002-04-27 01:56:30 +0000682#if defined(__NR_sched_get_priority_min)
683 case __NR_sched_get_priority_min: /* syscall 160 */
684 /* int sched_get_priority_min(int policy); */
685 if (VG_(clo_trace_syscalls))
686 VG_(printf)("sched_get_priority_min ( %d )\n", arg1);
687 KERNEL_DO_SYSCALL(tid,res);
688 break;
689# endif
690
691#if defined(__NR_setpriority)
692 case __NR_setpriority: /* syscall 97 */
693 /* int setpriority(int which, int who, int prio); */
694 if (VG_(clo_trace_syscalls))
695 VG_(printf)("setpriority ( %d, %d, %d )\n", arg1, arg2, arg3);
696 KERNEL_DO_SYSCALL(tid,res);
697 break;
698# endif
699
sewardjde5ac182002-04-27 02:13:24 +0000700#if defined(__NR_getpriority)
701 case __NR_getpriority: /* syscall 96 */
702 /* int getpriority(int which, int who); */
703 if (VG_(clo_trace_syscalls))
704 VG_(printf)("getpriority ( %d, %d )\n", arg1, arg2);
705 KERNEL_DO_SYSCALL(tid,res);
706 break;
707# endif
708
sewardjde4a1d02002-03-22 01:27:54 +0000709# if defined(__NR_setfsgid)
710 case __NR_setfsgid: /* syscall 139 */
711 /* int setfsgid(gid_t gid); */
712 if (VG_(clo_trace_syscalls))
713 VG_(printf)("setfsgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000714 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000715 break;
716# endif
717
718# if defined(__NR_setregid)
719 case __NR_setregid: /* syscall 71 */
720 /* int setregid(gid_t rgid, gid_t egid); */
721 if (VG_(clo_trace_syscalls))
722 VG_(printf)("setregid ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +0000723 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000724 break;
725# endif
726
727# if defined(__NR_setresuid)
728 case __NR_setresuid: /* syscall 164 */
729 /* int setresuid(uid_t ruid, uid_t euid, uid_t suid); */
730 if (VG_(clo_trace_syscalls))
731 VG_(printf)("setresuid ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +0000732 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000733 break;
734# endif
735
736# if defined(__NR_setfsuid)
737 case __NR_setfsuid: /* syscall 138 */
738 /* int setfsuid(uid_t uid); */
739 if (VG_(clo_trace_syscalls))
740 VG_(printf)("setfsuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000741 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000742 break;
743# endif
744
745 /* !!!!!!!!!! New, untested syscalls, 8 Mar 02 !!!!!!!!!!! */
746
747# if defined(__NR_sendfile)
748 case __NR_sendfile: /* syscall 187 */
749 /* ssize_t sendfile(int out_fd, int in_fd, off_t *offset,
750 size_t count) */
751 if (VG_(clo_trace_syscalls))
752 VG_(printf)("sendfile ( %d, %d, %p, %d )\n",arg1,arg2,arg3,arg4);
sewardj8c824512002-04-14 04:16:48 +0000753 must_be_writable( tst, "sendfile(offset)", arg3, sizeof(off_t) );
sewardj2e93c502002-04-12 11:12:52 +0000754 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000755 if (!VG_(is_kerror)(res)) {
756 make_readable( arg3, sizeof( off_t ) );
757 }
758 break;
759# endif
760
761 /* !!!!!!!!!! New, untested syscalls, 7 Mar 02 !!!!!!!!!!! */
762
763# if defined(__NR_pwrite)
764 case __NR_pwrite: /* syscall 181 */
765 /* ssize_t pwrite (int fd, const void *buf, size_t nbytes,
766 off_t offset); */
767 if (VG_(clo_trace_syscalls))
768 VG_(printf)("pwrite ( %d, %p, %d, %d )\n", arg1, arg2, arg3, arg4);
sewardj8c824512002-04-14 04:16:48 +0000769 must_be_readable( tst, "pwrite(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000770 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000771 break;
772# endif
773
774 /* !!!!!!!!!! New, untested syscalls, 6 Mar 02 !!!!!!!!!!! */
775
776 case __NR_sync: /* syscall 36 */
777 /* int sync(); */
778 if (VG_(clo_trace_syscalls))
779 VG_(printf)("sync ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000780 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000781 break;
782
783 case __NR_fstatfs: /* syscall 100 */
784 /* int fstatfs(int fd, struct statfs *buf); */
785 if (VG_(clo_trace_syscalls))
786 VG_(printf)("fstatfs ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000787 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct statfs) );
sewardj2e93c502002-04-12 11:12:52 +0000788 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000789 if (!VG_(is_kerror)(res))
790 make_readable( arg2, sizeof(struct statfs) );
791 break;
792
793 /* !!!!!!!!!! New, untested syscalls, 4 Mar 02 !!!!!!!!!!! */
794
795 case __NR_pause: /* syscall 29 */
796 /* int pause(void); */
797 if (VG_(clo_trace_syscalls))
798 VG_(printf)("pause ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000799 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000800 break;
801
802 case __NR_getsid: /* syscall 147 */
803 /* pid_t getsid(pid_t pid); */
804 if (VG_(clo_trace_syscalls))
805 VG_(printf)("getsid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000806 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000807 break;
808
809# if defined(__NR_pread)
810 case __NR_pread: /* syscall 180 */
811 /* ssize_t pread(int fd, void *buf, size_t count, off_t offset); */
812 if (VG_(clo_trace_syscalls))
813 VG_(printf)("pread ( %d, %p, %d, %d ) ...\n",arg1,arg2,arg3,arg4);
sewardj8c824512002-04-14 04:16:48 +0000814 must_be_writable( tst, "pread(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000815 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000816 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000817 VG_(printf)("SYSCALL[%d] pread ( %d, %p, %d, %d ) --> %d\n",
818 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +0000819 arg1, arg2, arg3, arg4, res);
820 if (!VG_(is_kerror)(res) && res > 0) {
821 make_readable( arg2, res );
822 }
823 break;
824# endif
825
826 /* !!!!!!!!!! New, untested syscalls, 27 Feb 02 !!!!!!!!!! */
827
828 case __NR_mknod: /* syscall 14 */
829 /* int mknod(const char *pathname, mode_t mode, dev_t dev); */
830 if (VG_(clo_trace_syscalls))
831 VG_(printf)("mknod ( %p, 0x%x, 0x%x )\n", arg1, arg2, arg3 );
sewardj8c824512002-04-14 04:16:48 +0000832 must_be_readable_asciiz( tst, "mknod(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000833 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000834 break;
835
836 case __NR_flock: /* syscall 143 */
837 /* int flock(int fd, int operation); */
838 if (VG_(clo_trace_syscalls))
839 VG_(printf)("flock ( %d, %d )\n", arg1, arg2 );
sewardj2e93c502002-04-12 11:12:52 +0000840 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000841 break;
842
843# if defined(__NR_rt_sigsuspend)
844 /* Viewed with great suspicion by me, but, hey, let's do it
845 anyway ... */
846 case __NR_rt_sigsuspend: /* syscall 179 */
847 /* int sigsuspend(const sigset_t *mask); */
848 if (VG_(clo_trace_syscalls))
849 VG_(printf)("sigsuspend ( %p )\n", arg1 );
850 if (arg1 != (Addr)NULL) {
851 /* above NULL test is paranoia */
sewardj8c824512002-04-14 04:16:48 +0000852 must_be_readable( tst, "sigsuspend(mask)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000853 sizeof(vki_ksigset_t) );
854 }
sewardj2e93c502002-04-12 11:12:52 +0000855 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000856 break;
857# endif
858
859 case __NR_init_module: /* syscall 128 */
860 /* int init_module(const char *name, struct module *image); */
861 if (VG_(clo_trace_syscalls))
862 VG_(printf)("init_module ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +0000863 must_be_readable_asciiz( tst, "init_module(name)", arg1 );
864 must_be_readable( tst, "init_module(image)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +0000865 sizeof(struct module) );
sewardj2e93c502002-04-12 11:12:52 +0000866 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000867 break;
868
869 case __NR_ioperm: /* syscall 101 */
870 /* int ioperm(unsigned long from, unsigned long num, int turn_on); */
871 if (VG_(clo_trace_syscalls))
872 VG_(printf)("ioperm ( %d, %d, %d )\n", arg1, arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000873 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000874 break;
875
876 case __NR_capget: /* syscall 184 */
877 /* int capget(cap_user_header_t header, cap_user_data_t data); */
878 if (VG_(clo_trace_syscalls))
879 VG_(printf)("capget ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +0000880 must_be_readable( tst, "capget(header)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000881 sizeof(vki_cap_user_header_t) );
sewardj8c824512002-04-14 04:16:48 +0000882 must_be_writable( tst, "capget(data)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +0000883 sizeof( vki_cap_user_data_t) );
sewardj2e93c502002-04-12 11:12:52 +0000884 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000885 if (!VG_(is_kerror)(res) && arg2 != (Addr)NULL)
886 make_readable ( arg2, sizeof( vki_cap_user_data_t) );
887 break;
888
889 /* !!!!!!!!!!!!!!!!!!!!! mutant ones !!!!!!!!!!!!!!!!!!!!! */
890
891 case __NR_execve:
892 /* int execve (const char *filename,
893 char *const argv [],
894 char *const envp[]); */
895 if (VG_(clo_trace_syscalls))
896 VG_(printf)("execve ( %p(%s), %p, %p ) --- NOT CHECKED\n",
897 arg1, arg1, arg2, arg3);
898 /* Make any binding for LD_PRELOAD disappear, so that child
899 processes don't get traced into. */
900 if (!VG_(clo_trace_children)) {
901 Int i;
902 Char** envp = (Char**)arg3;
sewardj3e1eb1f2002-05-18 13:14:17 +0000903 Char* ld_preload_str = NULL;
904 Char* ld_library_path_str = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000905 for (i = 0; envp[i] != NULL; i++) {
sewardj3e1eb1f2002-05-18 13:14:17 +0000906 if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
907 ld_preload_str = &envp[i][11];
908 if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
909 ld_library_path_str = &envp[i][16];
sewardjde4a1d02002-03-22 01:27:54 +0000910 }
sewardj3e1eb1f2002-05-18 13:14:17 +0000911 VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
912 ld_preload_str, ld_library_path_str );
sewardjde4a1d02002-03-22 01:27:54 +0000913 }
sewardj2e93c502002-04-12 11:12:52 +0000914 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000915 /* Should we still be alive here? Don't think so. */
916 /* Actually, above comment is wrong. execve can fail, just
917 like any other syscall -- typically the file to exec does
918 not exist. Hence: */
919 vg_assert(VG_(is_kerror)(res));
920 break;
921
sewardjde4a1d02002-03-22 01:27:54 +0000922 /* !!!!!!!!!!!!!!!!!!!!! end !!!!!!!!!!!!!!!!!!!!! */
923
924 case __NR_access: /* syscall 33 */
925 /* int access(const char *pathname, int mode); */
926 if (VG_(clo_trace_syscalls))
927 VG_(printf)("access ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000928 must_be_readable_asciiz( tst, "access(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000929 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000930 break;
931
932 case __NR_alarm: /* syscall 27 */
933 /* unsigned int alarm(unsigned int seconds); */
934 if (VG_(clo_trace_syscalls))
935 VG_(printf)("alarm ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000936 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000937 break;
938
939 case __NR_brk: /* syscall 45 */
940 /* Haven't a clue if this is really right. */
941 /* int brk(void *end_data_segment); */
942 if (VG_(clo_trace_syscalls))
943 VG_(printf)("brk ( %p ) --> ",arg1);
sewardj2e93c502002-04-12 11:12:52 +0000944 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000945 if (VG_(clo_trace_syscalls))
946 VG_(printf)("0x%x\n", res);
947
948 if (!VG_(is_kerror)(res)) {
949 if (arg1 == 0) {
950 /* Just asking where the current end is. (???) */
951 VGM_(curr_dataseg_end) = res;
952 } else
953 if (arg1 < VGM_(curr_dataseg_end)) {
954 /* shrinking the data segment. */
955 make_noaccess( (Addr)arg1,
956 VGM_(curr_dataseg_end)-arg1 );
957 VGM_(curr_dataseg_end) = arg1;
958 } else
959 if (arg1 > VGM_(curr_dataseg_end) && res != 0) {
960 /* asked for more memory, and got it */
961 /*
962 VG_(printf)("BRK: new area %x .. %x\n",
963 VGM_(curr_dataseg_end, arg1-1 );
964 */
965 make_writable ( (Addr)VGM_(curr_dataseg_end),
966 arg1-VGM_(curr_dataseg_end) );
967 VGM_(curr_dataseg_end) = arg1;
968 }
969 }
970 break;
971
972 case __NR_chdir: /* syscall 12 */
973 /* int chdir(const char *path); */
974 if (VG_(clo_trace_syscalls))
975 VG_(printf)("chdir ( %p )\n", arg1);
sewardj8c824512002-04-14 04:16:48 +0000976 must_be_readable_asciiz( tst, "chdir(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000977 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000978 break;
979
980 case __NR_chmod: /* syscall 15 */
981 /* int chmod(const char *path, mode_t mode); */
982 if (VG_(clo_trace_syscalls))
983 VG_(printf)("chmod ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000984 must_be_readable_asciiz( tst, "chmod(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000985 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000986 break;
987
988# if defined(__NR_chown32)
989 case __NR_chown32: /* syscall 212 */
990# endif
991# if defined(__NR_lchown32)
992 case __NR_lchown32: /* syscall 198 */
993# endif
994 case __NR_chown: /* syscall 16 */
995 /* int chown(const char *path, uid_t owner, gid_t group); */
996 if (VG_(clo_trace_syscalls))
997 VG_(printf)("chown ( %p, 0x%x, 0x%x )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +0000998 must_be_readable_asciiz( tst, "chown(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000999 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001000 break;
1001
1002 case __NR_close: /* syscall 6 */
1003 /* int close(int fd); */
1004 if (VG_(clo_trace_syscalls))
1005 VG_(printf)("close ( %d )\n",arg1);
1006 /* Detect and negate attempts by the client to close Valgrind's
1007 logfile fd ... */
1008 if (arg1 == VG_(clo_logfile_fd)) {
1009 VG_(message)(Vg_UserMsg,
1010 "Warning: client attempted to close "
1011 "Valgrind's logfile fd (%d).",
1012 VG_(clo_logfile_fd));
1013 VG_(message)(Vg_UserMsg,
1014 " Use --logfile-fd=<number> to select an "
1015 "alternative logfile fd." );
1016 } else {
sewardj2e93c502002-04-12 11:12:52 +00001017 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001018 }
1019 break;
1020
1021 case __NR_dup: /* syscall 41 */
1022 /* int dup(int oldfd); */
1023 if (VG_(clo_trace_syscalls))
1024 VG_(printf)("dup ( %d ) --> ", arg1);
sewardj2e93c502002-04-12 11:12:52 +00001025 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001026 if (VG_(clo_trace_syscalls))
1027 VG_(printf)("%d\n", res);
1028 break;
1029
1030 case __NR_dup2: /* syscall 63 */
1031 /* int dup2(int oldfd, int newfd); */
1032 if (VG_(clo_trace_syscalls))
1033 VG_(printf)("dup2 ( %d, %d ) ...\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001034 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001035 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +00001036 VG_(printf)("SYSCALL[%d] dup2 ( %d, %d ) = %d\n",
1037 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +00001038 arg1, arg2, res);
1039 break;
1040
1041 case __NR_fcntl: /* syscall 55 */
sewardj2e93c502002-04-12 11:12:52 +00001042 /* int fcntl(int fd, int cmd, int arg); */
sewardjde4a1d02002-03-22 01:27:54 +00001043 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +00001044 VG_(printf)("fcntl ( %d, %d, %d )\n",arg1,arg2,arg3);
1045 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001046 break;
1047
1048 case __NR_fchdir: /* syscall 133 */
1049 /* int fchdir(int fd); */
1050 if (VG_(clo_trace_syscalls))
1051 VG_(printf)("fchdir ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00001052 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001053 break;
1054
sewardj2f0de322002-03-24 10:17:25 +00001055# if defined(__NR_fchown32)
1056 case __NR_fchown32: /* syscall 207 */
1057# endif
1058 case __NR_fchown: /* syscall 95 */
1059 /* int fchown(int filedes, uid_t owner, gid_t group); */
1060 if (VG_(clo_trace_syscalls))
1061 VG_(printf)("fchown ( %d, %d, %d )\n", arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +00001062 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +00001063 break;
1064
sewardjde4a1d02002-03-22 01:27:54 +00001065 case __NR_fchmod: /* syscall 94 */
1066 /* int fchmod(int fildes, mode_t mode); */
1067 if (VG_(clo_trace_syscalls))
1068 VG_(printf)("fchmod ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001069 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001070 break;
sewardj2f0de322002-03-24 10:17:25 +00001071
sewardjde4a1d02002-03-22 01:27:54 +00001072# if defined(__NR_fcntl64)
1073 case __NR_fcntl64: /* syscall 221 */
1074 /* I don't know what the prototype for this is supposed to be. */
1075 /* ??? int fcntl(int fd, int cmd); */
1076 if (VG_(clo_trace_syscalls))
1077 VG_(printf)("fcntl64 (?!) ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001078 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001079 break;
1080# endif
1081
1082 case __NR_fstat: /* syscall 108 */
1083 /* int fstat(int filedes, struct stat *buf); */
1084 if (VG_(clo_trace_syscalls))
1085 VG_(printf)("fstat ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001086 must_be_writable( tst, "fstat", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +00001087 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001088 if (!VG_(is_kerror)(res))
1089 make_readable( arg2, sizeof(struct stat) );
1090 break;
1091
1092 case __NR_vfork: /* syscall 190 */
1093 /* pid_t vfork(void); */
1094 if (VG_(clo_trace_syscalls))
1095 VG_(printf)("vfork ( ) ... becomes ... ");
1096 /* KLUDGE: we prefer to do a fork rather than vfork.
1097 vfork gives a SIGSEGV, and the stated semantics looks
1098 pretty much impossible for us. */
sewardj2e93c502002-04-12 11:12:52 +00001099 tst->m_eax = __NR_fork;
sewardjde4a1d02002-03-22 01:27:54 +00001100 /* fall through ... */
1101 case __NR_fork: /* syscall 2 */
1102 /* pid_t fork(void); */
1103 if (VG_(clo_trace_syscalls))
1104 VG_(printf)("fork ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001105 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001106 break;
1107
1108 case __NR_fsync: /* syscall 118 */
1109 /* int fsync(int fd); */
1110 if (VG_(clo_trace_syscalls))
1111 VG_(printf)("fsync ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00001112 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001113 break;
1114
1115 case __NR_ftruncate: /* syscall 93 */
1116 /* int ftruncate(int fd, size_t length); */
1117 if (VG_(clo_trace_syscalls))
1118 VG_(printf)("ftruncate ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001119 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001120 break;
1121
sewardj2f0de322002-03-24 10:17:25 +00001122# if defined(__NR_ftruncate64)
1123 case __NR_ftruncate64: /* syscall 194 */
1124 /* int ftruncate64(int fd, off64_t length); */
1125 if (VG_(clo_trace_syscalls))
1126 VG_(printf)("ftruncate64 ( %d, %lld )\n",
1127 arg1,arg2|((long long) arg3 << 32));
sewardj2e93c502002-04-12 11:12:52 +00001128 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001129 break;
1130# endif
1131
1132 case __NR_getdents: /* syscall 141 */
1133 /* int getdents(unsigned int fd, struct dirent *dirp,
1134 unsigned int count); */
1135 if (VG_(clo_trace_syscalls))
1136 VG_(printf)("getdents ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001137 must_be_writable( tst, "getdents(dirp)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00001138 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001139 if (!VG_(is_kerror)(res) && res > 0)
1140 make_readable( arg2, res );
1141 break;
1142
1143# if defined(__NR_getdents64)
1144 case __NR_getdents64: /* syscall 220 */
1145 /* int getdents(unsigned int fd, struct dirent64 *dirp,
1146 unsigned int count); */
1147 if (VG_(clo_trace_syscalls))
1148 VG_(printf)("getdents64 ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001149 must_be_writable( tst, "getdents64(dirp)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00001150 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001151 if (!VG_(is_kerror)(res) && res > 0)
1152 make_readable( arg2, res );
1153 break;
1154# endif
1155
1156# if defined(__NR_getgroups32)
1157 case __NR_getgroups32: /* syscall 205 */
1158# endif
1159 case __NR_getgroups: /* syscall 80 */
1160 /* int getgroups(int size, gid_t list[]); */
1161 if (VG_(clo_trace_syscalls))
1162 VG_(printf)("getgroups ( %d, %p )\n", arg1, arg2);
1163 if (arg1 > 0)
sewardj8c824512002-04-14 04:16:48 +00001164 must_be_writable ( tst, "getgroups(list)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00001165 arg1 * sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001166 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001167 if (arg1 > 0 && !VG_(is_kerror)(res) && res > 0)
1168 make_readable ( arg2, res * sizeof(gid_t) );
1169 break;
1170
1171 case __NR_getcwd: /* syscall 183 */
1172 /* char *getcwd(char *buf, size_t size); */
1173 if (VG_(clo_trace_syscalls))
1174 VG_(printf)("getcwd ( %p, %d )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001175 must_be_writable( tst, "getcwd(buf)", arg1, arg2 );
sewardj2e93c502002-04-12 11:12:52 +00001176 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001177 if (!VG_(is_kerror)(res) && res != (Addr)NULL)
1178 make_readable ( arg1, arg2 );
1179 /* Not really right -- really we should have the asciiz
1180 string starting at arg1 readable, or up to arg2 bytes,
1181 whichever finishes first. */
1182 break;
1183
1184 case __NR_geteuid: /* syscall 49 */
1185 /* uid_t geteuid(void); */
1186 if (VG_(clo_trace_syscalls))
1187 VG_(printf)("geteuid ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001188 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001189 break;
1190
1191# if defined(__NR_geteuid32)
1192 case __NR_geteuid32: /* syscall 201 */
1193 /* ?? uid_t geteuid32(void); */
1194 if (VG_(clo_trace_syscalls))
1195 VG_(printf)("geteuid32(?) ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001196 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001197 break;
1198# endif
1199
1200 case __NR_getegid: /* syscall 50 */
1201 /* gid_t getegid(void); */
1202 if (VG_(clo_trace_syscalls))
1203 VG_(printf)("getegid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001204 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001205 break;
1206
1207# if defined(__NR_getegid32)
1208 case __NR_getegid32: /* syscall 202 */
1209 /* gid_t getegid32(void); */
1210 if (VG_(clo_trace_syscalls))
1211 VG_(printf)("getegid32 ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001212 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001213 break;
1214# endif
1215
1216 case __NR_getgid: /* syscall 47 */
1217 /* gid_t getgid(void); */
1218 if (VG_(clo_trace_syscalls))
1219 VG_(printf)("getgid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001220 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001221 break;
1222
1223# if defined(__NR_getgid32)
1224 case __NR_getgid32: /* syscall 200 */
1225 /* gid_t getgid32(void); */
1226 if (VG_(clo_trace_syscalls))
1227 VG_(printf)("getgid32 ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001228 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001229 break;
1230# endif
1231
1232 case __NR_getpid: /* syscall 20 */
1233 /* pid_t getpid(void); */
1234 if (VG_(clo_trace_syscalls))
1235 VG_(printf)("getpid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001236 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001237 break;
1238
1239 case __NR_getpgid: /* syscall 132 */
1240 /* pid_t getpgid(pid_t pid); */
1241 if (VG_(clo_trace_syscalls))
1242 VG_(printf)("getpgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00001243 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001244 break;
1245
1246 case __NR_getpgrp: /* syscall 65 */
1247 /* pid_t getpprp(void); */
1248 if (VG_(clo_trace_syscalls))
1249 VG_(printf)("getpgrp ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001250 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001251 break;
1252
1253 case __NR_getppid: /* syscall 64 */
1254 /* pid_t getppid(void); */
1255 if (VG_(clo_trace_syscalls))
1256 VG_(printf)("getppid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001257 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001258 break;
1259
1260 case __NR_getresgid: /* syscall 171 */
1261 /* int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); */
1262 if (VG_(clo_trace_syscalls))
1263 VG_(printf)("getresgid ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001264 must_be_writable ( tst, "getresgid(rgid)", arg1, sizeof(gid_t) );
1265 must_be_writable ( tst, "getresgid(egid)", arg2, sizeof(gid_t) );
1266 must_be_writable ( tst, "getresgid(sgid)", arg3, sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001267 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001268 if (!VG_(is_kerror)(res) && res == 0) {
1269 make_readable ( arg1, sizeof(gid_t) );
1270 make_readable ( arg2, sizeof(gid_t) );
1271 make_readable ( arg3, sizeof(gid_t) );
1272 }
1273 break;
1274
1275# if defined(__NR_getresgid32)
1276 case __NR_getresgid32: /* syscall 211 */
1277 /* int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); */
1278 if (VG_(clo_trace_syscalls))
1279 VG_(printf)("getresgid32 ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001280 must_be_writable ( tst, "getresgid32(rgid)", arg1, sizeof(gid_t) );
1281 must_be_writable ( tst, "getresgid32(egid)", arg2, sizeof(gid_t) );
1282 must_be_writable ( tst, "getresgid32(sgid)", arg3, sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001283 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001284 if (!VG_(is_kerror)(res) && res == 0) {
1285 make_readable ( arg1, sizeof(gid_t) );
1286 make_readable ( arg2, sizeof(gid_t) );
1287 make_readable ( arg3, sizeof(gid_t) );
1288 }
1289 break;
1290# endif
1291
1292 case __NR_getresuid: /* syscall 165 */
1293 /* int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); */
1294 if (VG_(clo_trace_syscalls))
1295 VG_(printf)("getresuid ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001296 must_be_writable ( tst, "getresuid(ruid)", arg1, sizeof(uid_t) );
1297 must_be_writable ( tst, "getresuid(euid)", arg2, sizeof(uid_t) );
1298 must_be_writable ( tst, "getresuid(suid)", arg3, sizeof(uid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001299 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001300 if (!VG_(is_kerror)(res) && res == 0) {
1301 make_readable ( arg1, sizeof(uid_t) );
1302 make_readable ( arg2, sizeof(uid_t) );
1303 make_readable ( arg3, sizeof(uid_t) );
1304 }
1305 break;
1306
1307# if defined(__NR_getresuid32)
1308 case __NR_getresuid32: /* syscall 209 */
1309 /* int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); */
1310 if (VG_(clo_trace_syscalls))
1311 VG_(printf)("getresuid32 ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001312 must_be_writable ( tst, "getresuid32(ruid)", arg1, sizeof(uid_t) );
1313 must_be_writable ( tst, "getresuid32(euid)", arg2, sizeof(uid_t) );
1314 must_be_writable ( tst, "getresuid32(suid)", arg3, sizeof(uid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001315 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001316 if (!VG_(is_kerror)(res) && res == 0) {
1317 make_readable ( arg1, sizeof(uid_t) );
1318 make_readable ( arg2, sizeof(uid_t) );
1319 make_readable ( arg3, sizeof(uid_t) );
1320 }
1321 break;
1322# endif
1323
1324# if defined(__NR_ugetrlimit)
1325 case __NR_ugetrlimit: /* syscall 191 */
1326# endif
1327 case __NR_getrlimit: /* syscall 76 */
1328 /* int getrlimit (int resource, struct rlimit *rlim); */
1329 if (VG_(clo_trace_syscalls))
1330 VG_(printf)("getrlimit ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001331 must_be_writable( tst, "getrlimit(rlim)", arg2,
1332 sizeof(struct rlimit) );
sewardj2e93c502002-04-12 11:12:52 +00001333 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001334 if (!VG_(is_kerror)(res) && res == 0)
1335 make_readable( arg2, sizeof(struct rlimit) );
1336 break;
1337
1338 case __NR_getrusage: /* syscall 77 */
1339 /* int getrusage (int who, struct rusage *usage); */
1340 if (VG_(clo_trace_syscalls))
1341 VG_(printf)("getrusage ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001342 must_be_writable( tst, "getrusage(usage)", arg2,
1343 sizeof(struct rusage) );
sewardj2e93c502002-04-12 11:12:52 +00001344 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001345 if (!VG_(is_kerror)(res) && res == 0)
1346 make_readable(arg2, sizeof(struct rusage) );
1347 break;
1348
1349 case __NR_gettimeofday: /* syscall 78 */
1350 /* int gettimeofday(struct timeval *tv, struct timezone *tz); */
1351 if (VG_(clo_trace_syscalls))
1352 VG_(printf)("gettimeofday ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001353 must_be_writable( tst, "gettimeofday(tv)", arg1,
1354 sizeof(struct timeval) );
sewardjde4a1d02002-03-22 01:27:54 +00001355 if (arg2 != 0)
sewardj8c824512002-04-14 04:16:48 +00001356 must_be_writable( tst, "gettimeofday(tz)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00001357 sizeof(struct timezone) );
sewardj2e93c502002-04-12 11:12:52 +00001358 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001359 if (!VG_(is_kerror)(res) && res == 0) {
1360 make_readable( arg1, sizeof(struct timeval) );
1361 if (arg2 != 0)
1362 make_readable( arg2, sizeof(struct timezone) );
1363 }
1364 break;
1365
1366 case __NR_getuid: /* syscall 24 */
1367 /* uid_t getuid(void); */
1368 if (VG_(clo_trace_syscalls))
1369 VG_(printf)("getuid ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001370 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001371 break;
1372
1373# if defined(__NR_getuid32)
1374 case __NR_getuid32: /* syscall 199 */
1375 /* ???uid_t getuid32(void); */
1376 if (VG_(clo_trace_syscalls))
1377 VG_(printf)("getuid32 ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001378 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001379 break;
1380# endif
1381
1382 case __NR_ipc: /* syscall 117 */
1383 /* int ipc ( unsigned int call, int first, int second,
1384 int third, void *ptr, long fifth); */
1385 {
sewardj2e93c502002-04-12 11:12:52 +00001386 UInt arg6 = tst->m_ebp;
sewardjde4a1d02002-03-22 01:27:54 +00001387
1388 if (VG_(clo_trace_syscalls))
1389 VG_(printf)("ipc ( %d, %d, %d, %d, %p, %d )\n",
1390 arg1,arg2,arg3,arg4,arg5,arg6);
1391 switch (arg1 /* call */) {
1392 case 1: /* IPCOP_semop */
sewardj8c824512002-04-14 04:16:48 +00001393 must_be_readable ( tst, "semop(sops)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001394 arg3 * sizeof(struct sembuf) );
sewardj2e93c502002-04-12 11:12:52 +00001395 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001396 break;
sewardj5b9e3502002-03-29 04:35:08 +00001397 case 2: /* IPCOP_semget */
1398 case 3: /* IPCOP_semctl */
sewardj2e93c502002-04-12 11:12:52 +00001399 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001400 break;
1401 case 11: /* IPCOP_msgsnd */
1402 {
1403 struct msgbuf *msgp = (struct msgbuf *)arg5;
1404 Int msgsz = arg3;
1405
sewardj8c824512002-04-14 04:16:48 +00001406 must_be_readable ( tst, "msgsnd(msgp->mtype)",
sewardj5b9e3502002-03-29 04:35:08 +00001407 (UInt)&msgp->mtype, sizeof(msgp->mtype) );
sewardj8c824512002-04-14 04:16:48 +00001408 must_be_readable ( tst, "msgsnd(msgp->mtext)",
sewardj5b9e3502002-03-29 04:35:08 +00001409 (UInt)msgp->mtext, msgsz );
1410
sewardj2e93c502002-04-12 11:12:52 +00001411 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001412 break;
1413 }
1414 case 12: /* IPCOP_msgrcv */
1415 {
sewardj59c255c2002-04-27 02:06:15 +00001416 struct msgbuf *msgp;
sewardj5b9e3502002-03-29 04:35:08 +00001417 Int msgsz = arg3;
sewardj59c255c2002-04-27 02:06:15 +00001418
1419 msgp = (struct msgbuf *)safe_dereference(
1420 (Addr) (&((struct ipc_kludge *)arg5)->msgp), 0 );
sewardj5b9e3502002-03-29 04:35:08 +00001421
sewardj59c255c2002-04-27 02:06:15 +00001422 must_be_writable ( tst, "msgrcv(msgp->mtype)",
sewardj5b9e3502002-03-29 04:35:08 +00001423 (UInt)&msgp->mtype, sizeof(msgp->mtype) );
sewardj59c255c2002-04-27 02:06:15 +00001424 must_be_writable ( tst, "msgrcv(msgp->mtext)",
sewardj5b9e3502002-03-29 04:35:08 +00001425 (UInt)msgp->mtext, msgsz );
1426
sewardj2e93c502002-04-12 11:12:52 +00001427 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001428
1429 if ( !VG_(is_kerror)(res) && res > 0 ) {
1430 make_readable ( (UInt)&msgp->mtype, sizeof(msgp->mtype) );
1431 make_readable ( (UInt)msgp->mtext, res );
1432 }
1433 break;
1434 }
1435 case 13: /* IPCOP_msgget */
sewardj2e93c502002-04-12 11:12:52 +00001436 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001437 break;
1438 case 14: /* IPCOP_msgctl */
1439 {
1440 switch (arg3 /* cmd */) {
1441 case IPC_STAT:
sewardj8c824512002-04-14 04:16:48 +00001442 must_be_writable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001443 sizeof(struct msqid_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001444 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001445 if ( !VG_(is_kerror)(res) && res > 0 ) {
1446 make_readable ( arg5, sizeof(struct msqid_ds) );
1447 }
1448 break;
1449 case IPC_SET:
sewardj8c824512002-04-14 04:16:48 +00001450 must_be_readable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001451 sizeof(struct msqid_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001452 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001453 break;
sewardjc9add3b2002-04-16 01:58:19 +00001454# if defined(IPC_64)
sewardj5b9e3502002-03-29 04:35:08 +00001455 case IPC_STAT|IPC_64:
sewardj8c824512002-04-14 04:16:48 +00001456 must_be_writable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001457 sizeof(struct msqid64_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001458 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001459 if ( !VG_(is_kerror)(res) && res > 0 ) {
1460 make_readable ( arg5, sizeof(struct msqid64_ds) );
1461 }
1462 break;
sewardjc9add3b2002-04-16 01:58:19 +00001463# endif
1464# if defined(IPC_64)
sewardj5b9e3502002-03-29 04:35:08 +00001465 case IPC_SET|IPC_64:
sewardj8c824512002-04-14 04:16:48 +00001466 must_be_readable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001467 sizeof(struct msqid64_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001468 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001469 break;
sewardjc9add3b2002-04-16 01:58:19 +00001470# endif
sewardj5b9e3502002-03-29 04:35:08 +00001471 default:
sewardj2e93c502002-04-12 11:12:52 +00001472 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001473 break;
1474 }
1475 break;
1476 }
sewardjde4a1d02002-03-22 01:27:54 +00001477 case 21: /* IPCOP_shmat */
1478 {
1479 Int shmid = arg2;
1480 Int shmflag = arg3;
1481 UInt addr;
1482
sewardj2e93c502002-04-12 11:12:52 +00001483 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001484
1485 if ( VG_(is_kerror) ( res ) )
1486 break;
1487
1488 /* force readability. before the syscall it is
1489 * indeed uninitialized, as can be seen in
1490 * glibc/sysdeps/unix/sysv/linux/shmat.c */
1491 make_readable ( arg4, sizeof( ULong ) );
1492
1493 addr = safe_dereference ( arg4, 0 );
1494 if ( addr > 0 ) {
1495 UInt segmentSize = get_shm_size ( shmid );
1496 if ( segmentSize > 0 ) {
1497 if ( shmflag & SHM_RDONLY )
1498 make_readable ( addr, segmentSize );
1499 else
1500 make_readwritable ( addr, segmentSize );
1501 }
1502 }
1503 break;
1504 }
1505 case 22: /* IPCOP_shmdt */
sewardj2e93c502002-04-12 11:12:52 +00001506 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001507 /* ### FIXME: this should call make_noaccess on the
1508 * area passed to shmdt. But there's no way to
1509 * figure out the size of the shared memory segment
1510 * just from the address... Maybe we want to keep a
1511 * copy of the exiting mappings inside valgrind? */
1512 break;
1513 case 23: /* IPCOP_shmget */
sewardj2e93c502002-04-12 11:12:52 +00001514 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001515 break;
1516 case 24: /* IPCOP_shmctl */
sewardj2390bb52002-05-09 17:45:06 +00001517 /* Subject: shmctl: The True Story
1518 Date: Thu, 9 May 2002 18:07:23 +0100 (BST)
1519 From: Reuben Thomas <rrt@mupsych.org>
1520 To: Julian Seward <jseward@acm.org>
1521
1522 1. As you suggested, the syscall subop is in arg1.
1523
1524 2. There are a couple more twists, so the arg order
1525 is actually:
1526
1527 arg1 syscall subop
1528 arg2 file desc
1529 arg3 shm operation code (can have IPC_64 set)
1530 arg4 0 ??? is arg3-arg4 a 64-bit quantity when IPC_64
1531 is defined?
1532 arg5 pointer to buffer
1533
1534 3. With this in mind, I've amended the case as below:
1535 */
1536 {
1537 UInt cmd = arg3;
1538 Bool out_arg = False;
1539 if ( arg5 ) {
1540# if defined(IPC_64)
1541 cmd = cmd & (~IPC_64);
1542# endif
sewardj2a8cda12002-05-10 22:51:26 +00001543 out_arg = cmd == SHM_STAT || cmd == IPC_STAT;
sewardj2390bb52002-05-09 17:45:06 +00001544 if ( out_arg )
1545 must_be_writable( tst,
1546 "shmctl(SHM_STAT or IPC_STAT,buf)",
1547 arg5, sizeof(struct shmid_ds) );
1548 else
1549 must_be_readable( tst,
1550 "shmctl(SHM_XXXX,buf)",
1551 arg5, sizeof(struct shmid_ds) );
1552 }
1553 KERNEL_DO_SYSCALL(tid,res);
1554 if ( arg5 && !VG_(is_kerror)(res) && res == 0 && out_arg )
1555 make_readable( arg5, sizeof(struct shmid_ds) );
sewardjde4a1d02002-03-22 01:27:54 +00001556 }
sewardj84b380a2002-05-08 01:31:15 +00001557 break;
sewardjde4a1d02002-03-22 01:27:54 +00001558 default:
1559 VG_(message)(Vg_DebugMsg,
1560 "FATAL: unhandled syscall(ipc) %d",
1561 arg1 );
1562 VG_(panic)("... bye!\n");
1563 break; /*NOTREACHED*/
1564 }
1565 }
1566 break;
1567
1568 case __NR_ioctl: /* syscall 54 */
1569 /* int ioctl(int d, int request, ...)
1570 [The "third" argument is traditionally char *argp,
1571 and will be so named for this discussion.]
1572 */
1573 /*
1574 VG_(message)(
1575 Vg_DebugMsg,
1576 "is an IOCTL, request = 0x%x, d = %d, argp = 0x%x",
1577 arg2,arg1,arg3);
1578 */
1579 if (VG_(clo_trace_syscalls))
1580 VG_(printf)("ioctl ( %d, 0x%x, %p )\n",arg1,arg2,arg3);
1581 switch (arg2 /* request */) {
1582 case TCSETS:
1583 case TCSETSW:
1584 case TCSETSF:
sewardj730e4d32002-05-09 18:40:45 +00001585 must_be_readable( tst, "ioctl(TCSET{S,SW,SF})", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001586 VKI_SIZEOF_STRUCT_TERMIOS );
sewardj2e93c502002-04-12 11:12:52 +00001587 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001588 break;
1589 case TCGETS:
sewardj8c824512002-04-14 04:16:48 +00001590 must_be_writable( tst, "ioctl(TCGETS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001591 VKI_SIZEOF_STRUCT_TERMIOS );
sewardj2e93c502002-04-12 11:12:52 +00001592 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001593 if (!VG_(is_kerror)(res) && res == 0)
1594 make_readable ( arg3, VKI_SIZEOF_STRUCT_TERMIOS );
1595 break;
sewardj2f0de322002-03-24 10:17:25 +00001596 case TCSETA:
sewardj730e4d32002-05-09 18:40:45 +00001597 case TCSETAW:
1598 case TCSETAF:
1599 must_be_readable( tst, "ioctl(TCSET{A,AW,AF})", arg3,
sewardj2f0de322002-03-24 10:17:25 +00001600 VKI_SIZEOF_STRUCT_TERMIO );
sewardj2e93c502002-04-12 11:12:52 +00001601 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +00001602 break;
1603 case TCGETA:
sewardj8c824512002-04-14 04:16:48 +00001604 must_be_writable( tst, "ioctl(TCGETA)", arg3,
sewardj2f0de322002-03-24 10:17:25 +00001605 VKI_SIZEOF_STRUCT_TERMIO );
sewardj2e93c502002-04-12 11:12:52 +00001606 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +00001607 if (!VG_(is_kerror)(res) && res == 0)
1608 make_readable ( arg3, VKI_SIZEOF_STRUCT_TERMIO );
1609 break;
sewardjde4a1d02002-03-22 01:27:54 +00001610 case TCSBRK:
sewardj835021e2002-05-22 12:03:54 +00001611 case TCXONC:
sewardjde4a1d02002-03-22 01:27:54 +00001612 case TCSBRKP:
1613 case TCFLSH:
1614 /* These just take an int by value */
sewardj2e93c502002-04-12 11:12:52 +00001615 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001616 break;
1617 case TIOCGWINSZ:
sewardj8c824512002-04-14 04:16:48 +00001618 must_be_writable( tst, "ioctl(TIOCGWINSZ)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001619 sizeof(struct winsize) );
sewardj2e93c502002-04-12 11:12:52 +00001620 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001621 if (!VG_(is_kerror)(res) && res == 0)
1622 make_readable ( arg3, sizeof(struct winsize) );
1623 break;
1624 case TIOCSWINSZ:
sewardj8c824512002-04-14 04:16:48 +00001625 must_be_readable( tst, "ioctl(TIOCSWINSZ)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001626 sizeof(struct winsize) );
sewardj2e93c502002-04-12 11:12:52 +00001627 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001628 break;
sewardj19fe3d02002-03-29 04:39:00 +00001629 case TIOCGPGRP:
1630 /* Get process group ID for foreground processing group. */
sewardj8c824512002-04-14 04:16:48 +00001631 must_be_writable( tst, "ioctl(TIOCGPGRP)", arg3,
sewardj19fe3d02002-03-29 04:39:00 +00001632 sizeof(pid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001633 KERNEL_DO_SYSCALL(tid,res);
sewardj19fe3d02002-03-29 04:39:00 +00001634 if (!VG_(is_kerror)(res) && res == 0)
1635 make_readable ( arg3, sizeof(pid_t) );
sewardja4da9372002-05-21 00:44:02 +00001636 break;
1637 case TIOCSPGRP:
1638 /* Set a process group ID? */
1639 must_be_writable( tst, "ioctl(TIOCGPGRP)", arg3,
1640 sizeof(pid_t) );
1641 KERNEL_DO_SYSCALL(tid,res);
1642 if (!VG_(is_kerror)(res) && res == 0)
1643 make_readable ( arg3, sizeof(pid_t) );
1644 break;
sewardjde4a1d02002-03-22 01:27:54 +00001645 case TIOCGPTN: /* Get Pty Number (of pty-mux device) */
sewardj8c824512002-04-14 04:16:48 +00001646 must_be_writable(tst, "ioctl(TIOCGPTN)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001647 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001648 if (!VG_(is_kerror)(res) && res == 0)
1649 make_readable ( arg3, sizeof(int));
1650 break;
sewardj73f1f072002-03-29 14:22:46 +00001651 case TIOCSCTTY:
1652 /* Just takes an int value. */
sewardj2e93c502002-04-12 11:12:52 +00001653 KERNEL_DO_SYSCALL(tid,res);
sewardj73f1f072002-03-29 14:22:46 +00001654 break;
sewardjde4a1d02002-03-22 01:27:54 +00001655 case TIOCSPTLCK: /* Lock/unlock Pty */
sewardj8c824512002-04-14 04:16:48 +00001656 must_be_readable( tst, "ioctl(TIOCSPTLCK)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001657 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001658 break;
1659 case FIONBIO:
sewardj8c824512002-04-14 04:16:48 +00001660 must_be_readable( tst, "ioctl(FIONBIO)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001661 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001662 break;
1663 case FIOASYNC:
sewardj8c824512002-04-14 04:16:48 +00001664 must_be_readable( tst, "ioctl(FIOASYNC)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001665 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001666 break;
1667 case FIONREAD:
sewardj8c824512002-04-14 04:16:48 +00001668 must_be_writable( tst, "ioctl(FIONREAD)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001669 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001670 if (!VG_(is_kerror)(res) && res == 0)
1671 make_readable( arg3, sizeof(int) );
1672 break;
1673
1674 /* If you get compilation problems here, change the #if
1675 1 to #if 0 and get rid of <scsi/sg.h> in
1676 vg_unsafe.h. */
1677# if 1
1678 case SG_SET_COMMAND_Q:
sewardj8c824512002-04-14 04:16:48 +00001679 must_be_readable( tst, "ioctl(SG_SET_COMMAND_Q)",
1680 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001681 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001682 break;
1683# if defined(SG_IO)
1684 case SG_IO:
sewardj8c824512002-04-14 04:16:48 +00001685 must_be_writable( tst, "ioctl(SG_IO)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001686 sizeof(struct sg_io_hdr) );
sewardj2e93c502002-04-12 11:12:52 +00001687 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001688 if (!VG_(is_kerror)(res) && res == 0)
1689 make_readable (arg3, sizeof(struct sg_io_hdr));
1690 break;
1691# endif /* SG_IO */
1692 case SG_GET_SCSI_ID:
1693 /* Note: sometimes sg_scsi_id is called sg_scsi_id_t */
sewardj8c824512002-04-14 04:16:48 +00001694 must_be_writable( tst, "ioctl(SG_GET_SCSI_ID)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001695 sizeof(struct sg_scsi_id) );
sewardj2e93c502002-04-12 11:12:52 +00001696 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001697 if (!VG_(is_kerror)(res) && res == 0)
1698 make_readable (arg3, sizeof(struct sg_scsi_id));
1699 break;
1700 case SG_SET_RESERVED_SIZE:
sewardj8c824512002-04-14 04:16:48 +00001701 must_be_readable( tst, "ioctl(SG_SET_RESERVED_SIZE)",
sewardjde4a1d02002-03-22 01:27:54 +00001702 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001703 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001704 break;
1705 case SG_SET_TIMEOUT:
sewardj8c824512002-04-14 04:16:48 +00001706 must_be_readable( tst, "ioctl(SG_SET_TIMEOUT)", arg3,
1707 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001708 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001709 break;
1710 case SG_GET_RESERVED_SIZE:
sewardj8c824512002-04-14 04:16:48 +00001711 must_be_writable( tst, "ioctl(SG_GET_RESERVED_SIZE)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001712 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001713 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001714 if (!VG_(is_kerror)(res) && res == 0)
1715 make_readable (arg3, sizeof(int));
1716 break;
1717 case SG_GET_TIMEOUT:
sewardj8c824512002-04-14 04:16:48 +00001718 must_be_writable( tst, "ioctl(SG_GET_TIMEOUT)", arg3,
1719 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001720 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001721 if (!VG_(is_kerror)(res) && res == 0)
1722 make_readable (arg3, sizeof(int));
1723 break;
1724 case SG_GET_VERSION_NUM:
sewardj8c824512002-04-14 04:16:48 +00001725 must_be_readable( tst, "ioctl(SG_GET_VERSION_NUM)",
sewardjde4a1d02002-03-22 01:27:54 +00001726 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001727 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001728 break;
1729# endif
1730
1731 case IIOCGETCPS:
1732 /* In early 2.4 kernels, ISDN_MAX_CHANNELS was only defined
1733 * when KERNEL was. I never saw a larger value than 64 though */
1734# ifndef ISDN_MAX_CHANNELS
1735# define ISDN_MAX_CHANNELS 64
1736# endif
sewardj8c824512002-04-14 04:16:48 +00001737 must_be_writable( tst, "ioctl(IIOCGETCPS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001738 ISDN_MAX_CHANNELS
1739 * 2 * sizeof(unsigned long) );
sewardj2e93c502002-04-12 11:12:52 +00001740 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001741 if (!VG_(is_kerror)(res) && res == 0)
1742 make_readable ( arg3, ISDN_MAX_CHANNELS
1743 * 2 * sizeof(unsigned long) );
1744 break;
1745 case IIOCNETGPN:
sewardj8c824512002-04-14 04:16:48 +00001746 must_be_readable( tst, "ioctl(IIOCNETGPN)",
sewardjde4a1d02002-03-22 01:27:54 +00001747 (UInt)&((isdn_net_ioctl_phone *)arg3)->name,
1748 sizeof(((isdn_net_ioctl_phone *)arg3)->name) );
sewardj8c824512002-04-14 04:16:48 +00001749 must_be_writable( tst, "ioctl(IIOCNETGPN)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001750 sizeof(isdn_net_ioctl_phone) );
sewardj2e93c502002-04-12 11:12:52 +00001751 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001752 if (!VG_(is_kerror)(res) && res == 0)
1753 make_readable ( arg3, sizeof(isdn_net_ioctl_phone) );
1754 break;
1755
1756 /* These all use struct ifreq AFAIK */
1757 case SIOCGIFINDEX:
1758 case SIOCGIFFLAGS: /* get flags */
1759 case SIOCGIFHWADDR: /* Get hardware address */
1760 case SIOCGIFMTU: /* get MTU size */
1761 case SIOCGIFADDR: /* get PA address */
1762 case SIOCGIFNETMASK: /* get network PA mask */
1763 case SIOCGIFMETRIC: /* get metric */
1764 case SIOCGIFMAP: /* Get device parameters */
1765 case SIOCGIFTXQLEN: /* Get the tx queue length */
1766 case SIOCGIFDSTADDR: /* get remote PA address */
1767 case SIOCGIFBRDADDR: /* get broadcast PA address */
1768 case SIOCGIFNAME: /* get iface name */
sewardj8c824512002-04-14 04:16:48 +00001769 must_be_writable(tst, "ioctl(SIOCGIFINDEX)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001770 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001771 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001772 if (!VG_(is_kerror)(res) && res == 0)
1773 make_readable (arg3, sizeof(struct ifreq));
1774 break;
1775 case SIOCGIFCONF: /* get iface list */
1776 /* WAS:
1777 must_be_writable("ioctl(SIOCGIFCONF)", arg3,
1778 sizeof(struct ifconf));
sewardj2e93c502002-04-12 11:12:52 +00001779 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001780 if (!VG_(is_kerror)(res) && res == 0)
1781 make_readable (arg3, sizeof(struct ifconf));
1782 */
sewardj8c824512002-04-14 04:16:48 +00001783 must_be_readable(tst, "ioctl(SIOCGIFCONF)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001784 sizeof(struct ifconf));
1785 if ( arg3 ) {
1786 // TODO len must be readable and writable
1787 // buf pointer only needs to be readable
1788 struct ifconf *ifc = (struct ifconf *) arg3;
sewardj8c824512002-04-14 04:16:48 +00001789 must_be_writable(tst, "ioctl(SIOCGIFCONF).ifc_buf",
sewardjde4a1d02002-03-22 01:27:54 +00001790 (Addr)(ifc->ifc_buf), (UInt)(ifc->ifc_len) );
1791 }
sewardj2e93c502002-04-12 11:12:52 +00001792 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001793 if (!VG_(is_kerror)(res) && res == 0 && arg3 ) {
1794 struct ifconf *ifc = (struct ifconf *) arg3;
1795 make_readable ( (Addr)(ifc->ifc_buf), (UInt)(ifc->ifc_len) );
1796 }
1797 break;
1798 case SIOCGSTAMP:
sewardj8c824512002-04-14 04:16:48 +00001799 must_be_writable(tst, "ioctl(SIOCGSTAMP)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001800 sizeof(struct timeval));
sewardj2e93c502002-04-12 11:12:52 +00001801 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001802 if (!VG_(is_kerror)(res) && res == 0)
1803 make_readable (arg3, sizeof(struct timeval));
1804 break;
1805 case SIOCGRARP: /* get RARP table entry */
1806 case SIOCGARP: /* get ARP table entry */
sewardj8c824512002-04-14 04:16:48 +00001807 must_be_writable(tst, "ioctl(SIOCGARP)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001808 sizeof(struct arpreq));
sewardj2e93c502002-04-12 11:12:52 +00001809 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001810 if (!VG_(is_kerror)(res) && res == 0)
1811 make_readable (arg3, sizeof(struct arpreq));
1812 break;
1813
1814 case SIOCSIFFLAGS: /* set flags */
1815 case SIOCSIFMAP: /* Set device parameters */
1816 case SIOCSIFTXQLEN: /* Set the tx queue length */
1817 case SIOCSIFDSTADDR: /* set remote PA address */
1818 case SIOCSIFBRDADDR: /* set broadcast PA address */
1819 case SIOCSIFNETMASK: /* set network PA mask */
1820 case SIOCSIFMETRIC: /* set metric */
1821 case SIOCSIFADDR: /* set PA address */
1822 case SIOCSIFMTU: /* set MTU size */
1823 case SIOCSIFHWADDR: /* set hardware address */
sewardj8c824512002-04-14 04:16:48 +00001824 must_be_readable(tst,"ioctl(SIOCSIFFLAGS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001825 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001826 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001827 break;
1828 /* Routing table calls. */
1829 case SIOCADDRT: /* add routing table entry */
1830 case SIOCDELRT: /* delete routing table entry */
sewardj8c824512002-04-14 04:16:48 +00001831 must_be_readable(tst,"ioctl(SIOCADDRT/DELRT)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001832 sizeof(struct rtentry));
sewardj2e93c502002-04-12 11:12:52 +00001833 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001834 break;
1835
1836 /* RARP cache control calls. */
1837 case SIOCDRARP: /* delete RARP table entry */
1838 case SIOCSRARP: /* set RARP table entry */
1839 /* ARP cache control calls. */
1840 case SIOCSARP: /* set ARP table entry */
1841 case SIOCDARP: /* delete ARP table entry */
sewardj8c824512002-04-14 04:16:48 +00001842 must_be_readable(tst, "ioctl(SIOCSIFFLAGS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001843 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001844 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001845 break;
1846
1847 case SIOCSPGRP:
sewardj8c824512002-04-14 04:16:48 +00001848 must_be_readable( tst, "ioctl(SIOCSPGRP)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001849 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001850 break;
1851
1852 /* linux/soundcard interface (OSS) */
1853 case SNDCTL_SEQ_GETOUTCOUNT:
1854 case SNDCTL_SEQ_GETINCOUNT:
1855 case SNDCTL_SEQ_PERCMODE:
1856 case SNDCTL_SEQ_TESTMIDI:
1857 case SNDCTL_SEQ_RESETSAMPLES:
1858 case SNDCTL_SEQ_NRSYNTHS:
1859 case SNDCTL_SEQ_NRMIDIS:
1860 case SNDCTL_SEQ_GETTIME:
1861 case SNDCTL_DSP_GETFMTS:
1862 case SNDCTL_DSP_GETTRIGGER:
1863 case SNDCTL_DSP_GETODELAY:
1864# if defined(SNDCTL_DSP_GETSPDIF)
1865 case SNDCTL_DSP_GETSPDIF:
1866# endif
1867 case SNDCTL_DSP_GETCAPS:
1868 case SOUND_PCM_READ_RATE:
1869 case SOUND_PCM_READ_CHANNELS:
1870 case SOUND_PCM_READ_BITS:
1871 case (SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
1872 case SOUND_PCM_READ_FILTER:
sewardj8c824512002-04-14 04:16:48 +00001873 must_be_writable(tst,"ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
1874 arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001875 sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001876 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001877 if (!VG_(is_kerror)(res) && res == 0)
1878 make_readable (arg3, sizeof(int));
1879 break;
1880 case SNDCTL_SEQ_CTRLRATE:
1881 case SNDCTL_DSP_SPEED:
1882 case SNDCTL_DSP_STEREO:
1883 case SNDCTL_DSP_GETBLKSIZE:
1884 case SNDCTL_DSP_CHANNELS:
1885 case SOUND_PCM_WRITE_FILTER:
1886 case SNDCTL_DSP_SUBDIVIDE:
1887 case SNDCTL_DSP_SETFRAGMENT:
sewardj8a5089d2002-03-24 11:43:56 +00001888# if defined(SNDCTL_DSP_GETCHANNELMASK)
sewardjde4a1d02002-03-22 01:27:54 +00001889 case SNDCTL_DSP_GETCHANNELMASK:
sewardj8a5089d2002-03-24 11:43:56 +00001890# endif
1891# if defined(SNDCTL_DSP_BIND_CHANNEL)
sewardjde4a1d02002-03-22 01:27:54 +00001892 case SNDCTL_DSP_BIND_CHANNEL:
sewardj8a5089d2002-03-24 11:43:56 +00001893# endif
sewardjde4a1d02002-03-22 01:27:54 +00001894 case SNDCTL_TMR_TIMEBASE:
1895 case SNDCTL_TMR_TEMPO:
1896 case SNDCTL_TMR_SOURCE:
1897 case SNDCTL_MIDI_PRETIME:
1898 case SNDCTL_MIDI_MPUMODE:
sewardj8c824512002-04-14 04:16:48 +00001899 must_be_readable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX "
1900 "(SIOWR, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001901 arg3, sizeof(int));
sewardj8c824512002-04-14 04:16:48 +00001902 must_be_writable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX "
1903 "(SIOWR, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001904 arg3, sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001905 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001906 break;
1907 case SNDCTL_DSP_GETOSPACE:
1908 case SNDCTL_DSP_GETISPACE:
sewardj8c824512002-04-14 04:16:48 +00001909 must_be_writable(tst,
1910 "ioctl(SNDCTL_XXX|SOUND_XXX "
sewardjde4a1d02002-03-22 01:27:54 +00001911 "(SIOR, audio_buf_info))", arg3,
1912 sizeof(audio_buf_info));
sewardj2e93c502002-04-12 11:12:52 +00001913 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001914 if (!VG_(is_kerror)(res) && res == 0)
1915 make_readable (arg3, sizeof(audio_buf_info));
1916 break;
1917 case SNDCTL_DSP_SETTRIGGER:
sewardj8c824512002-04-14 04:16:48 +00001918 must_be_readable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001919 arg3, sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001920 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001921 break;
sewardj0aa4c252002-04-27 02:20:14 +00001922
1923 /* Real Time Clock (/dev/rtc) ioctls */
sewardjfbe18b92002-05-10 00:46:59 +00001924# ifndef GLIBC_2_1
sewardj0aa4c252002-04-27 02:20:14 +00001925 case RTC_UIE_ON:
1926 case RTC_UIE_OFF:
1927 case RTC_AIE_ON:
1928 case RTC_AIE_OFF:
1929 case RTC_PIE_ON:
1930 case RTC_PIE_OFF:
1931 case RTC_IRQP_SET:
1932 KERNEL_DO_SYSCALL(tid,res);
1933 break;
1934 case RTC_RD_TIME:
1935 case RTC_ALM_READ:
1936 must_be_writable(tst, "ioctl(RTC_RD_TIME/ALM_READ)", arg3,
1937 sizeof(struct rtc_time));
1938 KERNEL_DO_SYSCALL(tid,res);
1939 if (!VG_(is_kerror) && res == 0)
1940 make_readable(arg3, sizeof(struct rtc_time));
1941 break;
1942 case RTC_ALM_SET:
1943 must_be_readable(tst, "ioctl(RTC_ALM_SET)", arg3,
1944 sizeof(struct rtc_time));
1945 KERNEL_DO_SYSCALL(tid,res);
1946 break;
1947 case RTC_IRQP_READ:
1948 must_be_writable(tst, "ioctl(RTC_IRQP_READ)", arg3,
1949 sizeof(unsigned long));
1950 KERNEL_DO_SYSCALL(tid,res);
1951 if(!VG_(is_kerror) && res == 0)
1952 make_readable(arg3, sizeof(unsigned long));
1953 break;
sewardjfbe18b92002-05-10 00:46:59 +00001954# endif /* GLIBC_2_1 */
sewardjeea0f2e2002-04-27 02:28:19 +00001955
1956 /* CD ROM stuff (??) */
1957 case CDROMSUBCHNL:
1958 must_be_readable(tst, "ioctl(CDROMSUBCHNL (cdsc_format, char))",
1959 (int) &(((struct cdrom_subchnl *) arg3)->cdsc_format),
1960 sizeof(((struct cdrom_subchnl *) arg3)->cdsc_format));
1961 must_be_writable(tst, "ioctl(CDROMSUBCHNL)", arg3,
1962 sizeof(struct cdrom_subchnl));
1963 KERNEL_DO_SYSCALL(tid,res);
1964 if (!VG_(is_kerror)(res) && res == 0)
1965 make_readable (arg3, sizeof(struct cdrom_subchnl));
1966 break;
1967 case CDROMREADTOCHDR:
1968 must_be_writable(tst, "ioctl(CDROMREADTOCHDR)", arg3,
1969 sizeof(struct cdrom_tochdr));
1970 KERNEL_DO_SYSCALL(tid,res);
1971 if (!VG_(is_kerror)(res) && res == 0)
1972 make_readable (arg3, sizeof(struct cdrom_tochdr));
1973 break;
1974 case CDROMREADTOCENTRY:
1975 must_be_readable(tst, "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
1976 (int) &(((struct cdrom_tocentry *) arg3)->cdte_format),
1977 sizeof(((struct cdrom_tocentry *) arg3)->cdte_format));
1978 must_be_readable(tst, "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
1979 (int) &(((struct cdrom_tocentry *) arg3)->cdte_track),
1980 sizeof(((struct cdrom_tocentry *) arg3)->cdte_track));
1981 must_be_writable(tst, "ioctl(CDROMREADTOCENTRY)", arg3,
1982 sizeof(struct cdrom_tocentry));
1983 KERNEL_DO_SYSCALL(tid,res);
1984 if (!VG_(is_kerror)(res) && res == 0)
1985 make_readable (arg3, sizeof(struct cdrom_tochdr));
1986 break;
1987 case CDROMPLAYMSF:
1988 must_be_readable(tst, "ioctl(CDROMPLAYMSF)", arg3,
1989 sizeof(struct cdrom_msf));
1990 KERNEL_DO_SYSCALL(tid,res);
1991 break;
sewardjde4a1d02002-03-22 01:27:54 +00001992 /* We don't have any specific information on it, so
1993 try to do something reasonable based on direction and
1994 size bits. The encoding scheme is described in
sewardja4da9372002-05-21 00:44:02 +00001995 /usr/include/asm/ioctl.h.
1996
1997 According to Simon Hausmann, _IOC_READ means the kernel
1998 writes a value to the ioctl value passed from the user
1999 space and the other way around with _IOC_WRITE. */
sewardjde4a1d02002-03-22 01:27:54 +00002000 default: {
2001 UInt dir = _IOC_DIR(arg2);
2002 UInt size = _IOC_SIZE(arg2);
2003 if (/* size == 0 || */ dir == _IOC_NONE) {
2004 VG_(message)(Vg_UserMsg,
2005 "Warning: noted but unhandled ioctl 0x%x"
2006 " with no size/direction hints",
2007 arg2);
2008 VG_(message)(Vg_UserMsg,
2009 " This could cause spurious value errors"
2010 " to appear.");
2011 VG_(message)(Vg_UserMsg,
2012 " See README_MISSING_SYSCALL_OR_IOCTL for guidance on"
2013 " writing a proper wrapper." );
2014 } else {
sewardjde4a1d02002-03-22 01:27:54 +00002015 if ((dir & _IOC_WRITE) && size > 0)
sewardja4da9372002-05-21 00:44:02 +00002016 must_be_readable(tst, "ioctl(generic)", arg3, size);
2017 if ((dir & _IOC_READ) && size > 0)
sewardj8c824512002-04-14 04:16:48 +00002018 must_be_writable(tst, "ioctl(generic)", arg3, size);
sewardjde4a1d02002-03-22 01:27:54 +00002019 }
sewardj2e93c502002-04-12 11:12:52 +00002020 KERNEL_DO_SYSCALL(tid,res);
sewardja4da9372002-05-21 00:44:02 +00002021 if (size > 0 && (dir & _IOC_READ)
sewardjde4a1d02002-03-22 01:27:54 +00002022 && !VG_(is_kerror)(res) && res == 0)
2023 make_readable (arg3, size);
2024 break;
2025 }
2026 }
2027 break;
2028
2029 case __NR_kill: /* syscall 37 */
2030 /* int kill(pid_t pid, int sig); */
2031 if (VG_(clo_trace_syscalls))
2032 VG_(printf)("kill ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00002033 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002034 break;
2035
2036 case __NR_link: /* syscall 9 */
2037 /* int link(const char *oldpath, const char *newpath); */
2038 if (VG_(clo_trace_syscalls))
2039 VG_(printf)("link ( %p, %p)\n", arg1, arg2);
sewardj8c824512002-04-14 04:16:48 +00002040 must_be_readable_asciiz( tst, "link(oldpath)", arg1);
2041 must_be_readable_asciiz( tst, "link(newpath)", arg2);
sewardj2e93c502002-04-12 11:12:52 +00002042 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002043 break;
2044
2045 case __NR_lseek: /* syscall 19 */
2046 /* off_t lseek(int fildes, off_t offset, int whence); */
2047 if (VG_(clo_trace_syscalls))
2048 VG_(printf)("lseek ( %d, %d, %d )\n",arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +00002049 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002050 break;
2051
2052 case __NR__llseek: /* syscall 140 */
2053 /* int _llseek(unsigned int fd, unsigned long offset_high,
2054 unsigned long offset_low,
2055 loff_t * result, unsigned int whence); */
2056 if (VG_(clo_trace_syscalls))
2057 VG_(printf)("llseek ( %d, 0x%x, 0x%x, %p, %d )\n",
2058 arg1,arg2,arg3,arg4,arg5);
sewardj8c824512002-04-14 04:16:48 +00002059 must_be_writable( tst, "llseek(result)", arg4, sizeof(loff_t));
sewardj2e93c502002-04-12 11:12:52 +00002060 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002061 if (!VG_(is_kerror)(res) && res == 0)
2062 make_readable( arg4, sizeof(loff_t) );
2063 break;
2064
2065 case __NR_lstat: /* syscall 107 */
2066 /* int lstat(const char *file_name, struct stat *buf); */
2067 if (VG_(clo_trace_syscalls))
2068 VG_(printf)("lstat ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002069 must_be_readable_asciiz( tst, "lstat(file_name)", arg1 );
2070 must_be_writable( tst, "lstat(buf)", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +00002071 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002072 if (!VG_(is_kerror)(res) && res == 0) {
2073 make_readable( arg2, sizeof(struct stat) );
2074 }
2075 break;
2076
2077# if defined(__NR_lstat64)
2078 case __NR_lstat64: /* syscall 196 */
2079 /* int lstat64(const char *file_name, struct stat64 *buf); */
2080 if (VG_(clo_trace_syscalls))
2081 VG_(printf)("lstat64 ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002082 must_be_readable_asciiz( tst, "lstat64(file_name)", arg1 );
2083 must_be_writable( tst, "lstat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00002084 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002085 if (!VG_(is_kerror)(res) && res == 0) {
2086 make_readable( arg2, sizeof(struct stat64) );
2087 }
2088 break;
2089# endif
2090
2091 case __NR_mkdir: /* syscall 39 */
2092 /* int mkdir(const char *pathname, mode_t mode); */
2093 if (VG_(clo_trace_syscalls))
2094 VG_(printf)("mkdir ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002095 must_be_readable_asciiz( tst, "mkdir(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002096 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002097 break;
2098
2099# if defined(__NR_mmap2)
2100 case __NR_mmap2: /* syscall 192 */
2101 /* My impression is that this is exactly like __NR_mmap
2102 except that all 6 args are passed in regs, rather than in
2103 a memory-block. */
2104 /* void* mmap(void *start, size_t length, int prot,
2105 int flags, int fd, off_t offset);
2106 */
2107 {
sewardj2e93c502002-04-12 11:12:52 +00002108 UInt arg6 = tst->m_ebp;
sewardjde4a1d02002-03-22 01:27:54 +00002109 if (VG_(clo_trace_syscalls))
2110 VG_(printf)("mmap2 ( %p, %d, %d, %d, %d, %d )\n",
2111 arg1, arg2, arg3, arg4, arg5, arg6 );
sewardj2e93c502002-04-12 11:12:52 +00002112 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002113 /* !!! shouldn't we also be doing the symtab loading stuff as
2114 in __NR_mmap ? */
2115 if (!VG_(is_kerror)(res))
2116 approximate_mmap_permissions( (Addr)res, arg2, arg3 );
2117 }
2118 break;
2119# endif
2120
2121 case __NR_mmap: /* syscall 90 */
2122 /* void* mmap(void *start, size_t length, int prot,
2123 int flags, int fd, off_t offset);
2124 */
2125 {
2126 Bool arg_block_readable
2127 = VG_(clo_instrument)
2128 ? VGM_(check_readable)(arg1, 6*sizeof(UInt), NULL)
2129 : True;
sewardj8c824512002-04-14 04:16:48 +00002130 must_be_readable( tst, "mmap(args)", arg1, 6*sizeof(UInt) );
sewardjde4a1d02002-03-22 01:27:54 +00002131 if (arg_block_readable) {
2132 UInt* arg_block = (UInt*)arg1;
2133 UInt arg6;
2134 arg1 = arg_block[0];
2135 arg2 = arg_block[1];
2136 arg3 = arg_block[2];
2137 arg4 = arg_block[3];
2138 arg5 = arg_block[4];
2139 arg6 = arg_block[5];
2140 if (VG_(clo_trace_syscalls))
2141 VG_(printf)("mmap ( %p, %d, %d, %d, %d, %d )\n",
2142 arg1, arg2, arg3, arg4, arg5, arg6 );
2143 }
sewardj2e93c502002-04-12 11:12:52 +00002144 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002145 if (arg_block_readable && !VG_(is_kerror)(res))
2146 approximate_mmap_permissions( (Addr)res, arg2, arg3 );
2147 if (arg_block_readable && !VG_(is_kerror)(res)
2148 && (arg3 & PROT_EXEC)) {
2149 /* The client mmap'ed a segment with executable
2150 permissions. Tell the symbol-table loader, so that it
2151 has an opportunity to pick up more symbols if this mmap
2152 was caused by the client loading a new .so via
2153 dlopen(). This is important for debugging KDE. */
2154 VG_(read_symbols)();
2155 }
2156 }
2157
2158 break;
2159
2160 case __NR_mprotect: /* syscall 125 */
2161 /* int mprotect(const void *addr, size_t len, int prot); */
2162 /* should addr .. addr+len-1 be checked before the call? */
2163 if (VG_(clo_trace_syscalls))
2164 VG_(printf)("mprotect ( %p, %d, %d )\n", arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +00002165 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002166 if (!VG_(is_kerror)(res))
2167 approximate_mmap_permissions ( arg1, arg2, arg3 );
2168 break;
2169
2170 case __NR_munmap: /* syscall 91 */
2171 /* int munmap(void *start, size_t length); */
2172 /* should start .. start+length-1 be checked before the call? */
2173 if (VG_(clo_trace_syscalls))
2174 VG_(printf)("munmap ( %p, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00002175 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002176 if (!VG_(is_kerror)(res)) {
2177 /* Mash around start and length so that the area passed to
2178 make_noaccess() exactly covers an integral number of
2179 pages. If we don't do that, our idea of addressible
2180 memory diverges from that of the kernel's, which causes
2181 the leak detector to crash. */
sewardj18d75132002-05-16 11:06:21 +00002182 Bool munmap_exe;
sewardjde4a1d02002-03-22 01:27:54 +00002183 Addr start = arg1;
2184 Addr length = arg2;
2185 while ((start % VKI_BYTES_PER_PAGE) > 0) { start--; length++; }
2186 while (((start+length) % VKI_BYTES_PER_PAGE) > 0) { length++; }
2187 /*
2188 VG_(printf)("MUNMAP: correct (%p for %d) to (%p for %d) %s\n",
2189 arg1, arg2, start, length, (arg1!=start || arg2!=length)
2190 ? "CHANGE" : "");
2191 */
2192 make_noaccess( start, length );
2193 /* Tell our symbol table machinery about this, so that if
2194 this happens to be a .so being unloaded, the relevant
2195 symbols are removed too. */
sewardj18d75132002-05-16 11:06:21 +00002196 munmap_exe = VG_(symtab_notify_munmap) ( start, length );
2197 if (munmap_exe)
2198 VG_(invalidate_translations) ( start, length );
sewardjde4a1d02002-03-22 01:27:54 +00002199 }
2200 break;
2201
2202 case __NR_nanosleep: /* syscall 162 */
2203 /* int nanosleep(const struct timespec *req, struct timespec *rem); */
2204 if (VG_(clo_trace_syscalls))
2205 VG_(printf)("nanosleep ( %p, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002206 must_be_readable ( tst, "nanosleep(req)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +00002207 sizeof(struct timespec) );
2208 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002209 must_be_writable ( tst, "nanosleep(rem)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002210 sizeof(struct timespec) );
sewardj2e93c502002-04-12 11:12:52 +00002211 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002212 /* Somewhat bogus ... is only written by the kernel if
2213 res == -1 && errno == EINTR. */
2214 if (!VG_(is_kerror)(res) && arg2 != (UInt)NULL)
2215 make_readable ( arg2, sizeof(struct timespec) );
2216 break;
2217
2218 case __NR__newselect: /* syscall 142 */
2219 /* int select(int n,
2220 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
2221 struct timeval *timeout);
2222 */
2223 if (VG_(clo_trace_syscalls))
2224 VG_(printf)("newselect ( %d, %p, %p, %p, %p )\n",
2225 arg1,arg2,arg3,arg4,arg5);
2226 if (arg2 != 0)
sewardj8c824512002-04-14 04:16:48 +00002227 must_be_readable( tst, "newselect(readfds)",
sewardjde4a1d02002-03-22 01:27:54 +00002228 arg2, arg1/8 /* __FD_SETSIZE/8 */ );
2229 if (arg3 != 0)
sewardj8c824512002-04-14 04:16:48 +00002230 must_be_readable( tst, "newselect(writefds)",
sewardjde4a1d02002-03-22 01:27:54 +00002231 arg3, arg1/8 /* __FD_SETSIZE/8 */ );
2232 if (arg4 != 0)
sewardj8c824512002-04-14 04:16:48 +00002233 must_be_readable( tst, "newselect(exceptfds)",
sewardjde4a1d02002-03-22 01:27:54 +00002234 arg4, arg1/8 /* __FD_SETSIZE/8 */ );
2235 if (arg5 != 0)
sewardj8c824512002-04-14 04:16:48 +00002236 must_be_readable( tst, "newselect(timeout)", arg5,
sewardjde4a1d02002-03-22 01:27:54 +00002237 sizeof(struct timeval) );
sewardj2e93c502002-04-12 11:12:52 +00002238 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002239 break;
2240
2241 case __NR_open: /* syscall 5 */
2242 /* int open(const char *pathname, int flags); */
2243 if (VG_(clo_trace_syscalls))
2244 VG_(printf)("open ( %p(%s), %d ) --> ",arg1,arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002245 must_be_readable_asciiz( tst, "open(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002246 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002247 if (VG_(clo_trace_syscalls))
2248 VG_(printf)("%d\n",res);
2249 break;
2250
2251 case __NR_pipe: /* syscall 42 */
2252 /* int pipe(int filedes[2]); */
2253 if (VG_(clo_trace_syscalls))
2254 VG_(printf)("pipe ( %p ) ...\n", arg1);
sewardj8c824512002-04-14 04:16:48 +00002255 must_be_writable( tst, "pipe(filedes)", arg1, 2*sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00002256 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002257 if (!VG_(is_kerror)(res))
2258 make_readable ( arg1, 2*sizeof(int) );
2259 if (VG_(clo_trace_syscalls) && !VG_(is_kerror)(res))
sewardj2e93c502002-04-12 11:12:52 +00002260 VG_(printf)("SYSCALL[%d] pipe --> (rd %d, wr %d)\n",
2261 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +00002262 ((UInt*)arg1)[0], ((UInt*)arg1)[1] );
2263 break;
2264
2265 case __NR_poll: /* syscall 168 */
2266 /* struct pollfd {
2267 int fd; -- file descriptor
2268 short events; -- requested events
2269 short revents; -- returned events
2270 };
2271 int poll(struct pollfd *ufds, unsigned int nfds,
2272 int timeout)
2273 */
2274 if (VG_(clo_trace_syscalls))
sewardja4da9372002-05-21 00:44:02 +00002275 VG_(printf)("poll ( %p, %d, %d )\n",arg1,arg2,arg3);
sewardjde4a1d02002-03-22 01:27:54 +00002276 /* In fact some parts of this struct should be readable too.
2277 This should be fixed properly. */
sewardj8c824512002-04-14 04:16:48 +00002278 must_be_writable( tst, "poll(ufds)",
2279 arg1, arg2 * sizeof(struct pollfd) );
sewardj2e93c502002-04-12 11:12:52 +00002280 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002281 if (!VG_(is_kerror)(res) && res > 0) {
2282 Int i;
2283 struct pollfd * arr = (struct pollfd *)arg1;
2284 for (i = 0; i < arg2; i++)
2285 make_readable( (Addr)(&arr[i].revents), sizeof(Short) );
2286 }
2287 break;
2288
sewardjde4a1d02002-03-22 01:27:54 +00002289 case __NR_readlink: /* syscall 85 */
2290 /* int readlink(const char *path, char *buf, size_t bufsiz); */
2291 if (VG_(clo_trace_syscalls))
2292 VG_(printf)("readlink ( %p, %p, %d )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002293 must_be_readable_asciiz( tst, "readlink(path)", arg1 );
2294 must_be_writable ( tst, "readlink(buf)", arg2,arg3 );
sewardj2e93c502002-04-12 11:12:52 +00002295 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002296 if (!VG_(is_kerror)(res) && res > 0) {
2297 make_readable ( arg2, res );
2298 }
2299 break;
2300
2301 case __NR_readv: { /* syscall 145 */
2302 /* int readv(int fd, const struct iovec * vector, size_t count); */
2303 UInt i;
2304 struct iovec * vec;
2305 if (VG_(clo_trace_syscalls))
2306 VG_(printf)("readv ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002307 must_be_readable( tst, "readv(vector)",
sewardjde4a1d02002-03-22 01:27:54 +00002308 arg2, arg3 * sizeof(struct iovec) );
2309 /* ToDo: don't do any of the following if the vector is invalid */
2310 vec = (struct iovec *)arg2;
2311 for (i = 0; i < arg3; i++)
sewardj8c824512002-04-14 04:16:48 +00002312 must_be_writable( tst, "readv(vector[...])",
sewardjde4a1d02002-03-22 01:27:54 +00002313 (UInt)vec[i].iov_base,vec[i].iov_len );
sewardj2e93c502002-04-12 11:12:52 +00002314 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002315 if (!VG_(is_kerror)(res) && res > 0) {
2316 /* res holds the number of bytes read. */
2317 for (i = 0; i < arg3; i++) {
2318 Int nReadThisBuf = vec[i].iov_len;
2319 if (nReadThisBuf > res) nReadThisBuf = res;
2320 make_readable( (UInt)vec[i].iov_base, nReadThisBuf );
2321 res -= nReadThisBuf;
2322 if (res < 0) VG_(panic)("vg_wrap_syscall: readv: res < 0");
2323 }
2324 }
2325 break;
2326 }
2327
2328 case __NR_rename: /* syscall 38 */
2329 /* int rename(const char *oldpath, const char *newpath); */
2330 if (VG_(clo_trace_syscalls))
2331 VG_(printf)("rename ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +00002332 must_be_readable_asciiz( tst, "rename(oldpath)", arg1 );
2333 must_be_readable_asciiz( tst, "rename(newpath)", arg2 );
sewardj2e93c502002-04-12 11:12:52 +00002334 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002335 break;
2336
2337 case __NR_rmdir: /* syscall 40 */
2338 /* int rmdir(const char *pathname); */
2339 if (VG_(clo_trace_syscalls))
2340 VG_(printf)("rmdir ( %p )\n", arg1);
sewardj8c824512002-04-14 04:16:48 +00002341 must_be_readable_asciiz( tst, "rmdir(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002342 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002343 break;
2344
sewardja4d4e482002-05-03 21:18:11 +00002345 case __NR_sched_setparam: /* syscall 154 */
2346 /* int sched_setparam(pid_t pid, const struct sched_param *p); */
sewardj705d3cb2002-05-23 13:13:12 +00002347 if (VG_(clo_trace_syscalls))
sewardja4d4e482002-05-03 21:18:11 +00002348 VG_(printf)("sched_setparam ( %d, %p )\n", arg1, arg2 );
2349 must_be_readable( tst, "sched_setparam(ptr)",
2350 arg2, sizeof(struct sched_param) );
2351 KERNEL_DO_SYSCALL(tid,res);
2352 if (!VG_(is_kerror)(res))
2353 make_readable( arg2, sizeof(struct sched_param) );
2354 break;
2355
2356 case __NR_sched_getparam: /* syscall 155 */
2357 /* int sched_getparam(pid_t pid, struct sched_param *p); */
sewardj705d3cb2002-05-23 13:13:12 +00002358 if (VG_(clo_trace_syscalls))
sewardja4d4e482002-05-03 21:18:11 +00002359 VG_(printf)("sched_getparam ( %d, %p )\n", arg1, arg2 );
2360 must_be_writable( tst, "sched_getparam(ptr)",
2361 arg2, sizeof(struct sched_param) );
2362 KERNEL_DO_SYSCALL(tid,res);
2363 if (!VG_(is_kerror)(res))
2364 make_readable( arg2, sizeof(struct sched_param) );
2365 break;
2366
2367 case __NR_sched_yield: /* syscall 158 */
2368 /* int sched_yield(void); */
sewardj705d3cb2002-05-23 13:13:12 +00002369 if (VG_(clo_trace_syscalls))
sewardja4d4e482002-05-03 21:18:11 +00002370 VG_(printf)("sched_yield ()\n" );
sewardj2e93c502002-04-12 11:12:52 +00002371 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002372 break;
2373
2374 case __NR_select: /* syscall 82 */
2375 /* struct sel_arg_struct {
2376 unsigned long n;
2377 fd_set *inp, *outp, *exp;
2378 struct timeval *tvp;
2379 };
2380 int old_select(struct sel_arg_struct *arg);
2381 */
2382 {
2383 Bool arg_block_readable
2384 = VG_(clo_instrument)
2385 ? VGM_(check_readable)(arg1, 5*sizeof(UInt), NULL)
2386 : True;
sewardj8c824512002-04-14 04:16:48 +00002387 must_be_readable ( tst, "select(args)", arg1, 5*sizeof(UInt) );
sewardjde4a1d02002-03-22 01:27:54 +00002388 if (arg_block_readable) {
2389 UInt* arg_struct = (UInt*)arg1;
2390 arg1 = arg_struct[0];
2391 arg2 = arg_struct[1];
2392 arg3 = arg_struct[2];
2393 arg4 = arg_struct[3];
2394 arg5 = arg_struct[4];
2395
2396 if (VG_(clo_trace_syscalls))
2397 VG_(printf)("select ( %d, %p, %p, %p, %p )\n",
2398 arg1,arg2,arg3,arg4,arg5);
2399 if (arg2 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002400 must_be_readable(tst, "select(readfds)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002401 arg1/8 /* __FD_SETSIZE/8 */ );
2402 if (arg3 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002403 must_be_readable(tst, "select(writefds)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00002404 arg1/8 /* __FD_SETSIZE/8 */ );
2405 if (arg4 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002406 must_be_readable(tst, "select(exceptfds)", arg4,
sewardjde4a1d02002-03-22 01:27:54 +00002407 arg1/8 /* __FD_SETSIZE/8 */ );
2408 if (arg5 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002409 must_be_readable(tst, "select(timeout)", arg5,
sewardjde4a1d02002-03-22 01:27:54 +00002410 sizeof(struct timeval) );
2411 }
2412 }
sewardj2e93c502002-04-12 11:12:52 +00002413 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002414 break;
2415
2416 case __NR_setitimer: /* syscall 104 */
2417 /* setitimer(int which, const struct itimerval *value,
2418 struct itimerval *ovalue); */
2419 if (VG_(clo_trace_syscalls))
2420 VG_(printf)("setitimer ( %d, %p, %p )\n", arg1,arg2,arg3);
sewardj55314d42002-05-23 17:14:54 +00002421 if (arg2 != (Addr)NULL)
2422 must_be_readable(tst, "setitimer(value)",
2423 arg2, sizeof(struct itimerval) );
sewardjde4a1d02002-03-22 01:27:54 +00002424 if (arg3 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002425 must_be_writable(tst, "setitimer(ovalue)",
sewardjde4a1d02002-03-22 01:27:54 +00002426 arg3, sizeof(struct itimerval));
sewardj2e93c502002-04-12 11:12:52 +00002427 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002428 if (!VG_(is_kerror)(res) && arg3 != (Addr)NULL) {
2429 make_readable(arg3, sizeof(struct itimerval));
2430 }
2431 break;
2432
2433# if defined(__NR_setfsgid32)
2434 case __NR_setfsgid32: /* syscall 216 */
2435 /* int setfsgid(uid_t fsgid); */
2436 if (VG_(clo_trace_syscalls))
2437 VG_(printf)("setfsgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002438 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002439 break;
2440# endif
2441
2442# if defined(__NR_setgid32)
2443 case __NR_setgid32: /* syscall 214 */
2444# endif
2445 case __NR_setgid: /* syscall 46 */
2446 /* int setgid(gid_t gid); */
2447 if (VG_(clo_trace_syscalls))
2448 VG_(printf)("setgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002449 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002450 break;
2451
2452 case __NR_setsid: /* syscall 66 */
2453 /* pid_t setsid(void); */
2454 if (VG_(clo_trace_syscalls))
2455 VG_(printf)("setsid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00002456 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002457 break;
2458
2459# if defined(__NR_setgroups32)
2460 case __NR_setgroups32: /* syscall 206 */
sewardj2f0de322002-03-24 10:17:25 +00002461# endif
2462 case __NR_setgroups: /* syscall 81 */
sewardjde4a1d02002-03-22 01:27:54 +00002463 /* int setgroups(size_t size, const gid_t *list); */
2464 if (VG_(clo_trace_syscalls))
2465 VG_(printf)("setgroups ( %d, %p )\n", arg1, arg2);
2466 if (arg1 > 0)
sewardj8c824512002-04-14 04:16:48 +00002467 must_be_readable ( tst, "setgroups(list)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002468 arg1 * sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00002469 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002470 break;
sewardjde4a1d02002-03-22 01:27:54 +00002471
2472 case __NR_setpgid: /* syscall 57 */
2473 /* int setpgid(pid_t pid, pid_t pgid); */
2474 if (VG_(clo_trace_syscalls))
2475 VG_(printf)("setpgid ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002476 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002477 break;
2478
2479# if defined(__NR_setregid32)
2480 case __NR_setregid32: /* syscall 204 */
2481 /* int setregid(gid_t rgid, gid_t egid); */
2482 if (VG_(clo_trace_syscalls))
2483 VG_(printf)("setregid32(?) ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002484 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002485 break;
2486# endif
2487
2488# if defined(__NR_setresuid32)
2489 case __NR_setresuid32: /* syscall 208 */
2490 /* int setresuid(uid_t ruid, uid_t euid, uid_t suid); */
2491 if (VG_(clo_trace_syscalls))
2492 VG_(printf)("setresuid32(?) ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +00002493 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002494 break;
2495# endif
2496
2497# if defined(__NR_setreuid32)
2498 case __NR_setreuid32: /* syscall 203 */
2499# endif
2500 case __NR_setreuid: /* syscall 70 */
2501 /* int setreuid(uid_t ruid, uid_t euid); */
2502 if (VG_(clo_trace_syscalls))
2503 VG_(printf)("setreuid ( 0x%x, 0x%x )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002504 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002505 break;
2506
2507 case __NR_setrlimit: /* syscall 75 */
2508 /* int setrlimit (int resource, const struct rlimit *rlim); */
2509 if (VG_(clo_trace_syscalls))
2510 VG_(printf)("setrlimit ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002511 must_be_readable( tst, "setrlimit(rlim)", arg2, sizeof(struct rlimit) );
sewardj2e93c502002-04-12 11:12:52 +00002512 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002513 break;
2514
2515# if defined(__NR_setuid32)
2516 case __NR_setuid32: /* syscall 213 */
2517# endif
2518 case __NR_setuid: /* syscall 23 */
2519 /* int setuid(uid_t uid); */
2520 if (VG_(clo_trace_syscalls))
2521 VG_(printf)("setuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002522 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002523 break;
2524
2525 case __NR_socketcall: /* syscall 102 */
2526 /* int socketcall(int call, unsigned long *args); */
2527 if (VG_(clo_trace_syscalls))
2528 VG_(printf)("socketcall ( %d, %p )\n",arg1,arg2);
2529 switch (arg1 /* request */) {
2530
2531 case SYS_SOCKETPAIR:
2532 /* int socketpair(int d, int type, int protocol, int sv[2]); */
sewardj8c824512002-04-14 04:16:48 +00002533 must_be_readable( tst, "socketcall.socketpair(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002534 arg2, 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002535 must_be_writable( tst, "socketcall.socketpair(sv)",
sewardjde4a1d02002-03-22 01:27:54 +00002536 ((UInt*)arg2)[3], 2*sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00002537 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002538 if (!VG_(is_kerror)(res))
2539 make_readable ( ((UInt*)arg2)[3], 2*sizeof(int) );
2540 break;
2541
2542 case SYS_SOCKET:
2543 /* int socket(int domain, int type, int protocol); */
sewardj8c824512002-04-14 04:16:48 +00002544 must_be_readable( tst, "socketcall.socket(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002545 arg2, 3*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002546 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002547 break;
2548
2549 case SYS_BIND:
2550 /* int bind(int sockfd, struct sockaddr *my_addr,
2551 int addrlen); */
sewardj8c824512002-04-14 04:16:48 +00002552 must_be_readable( tst, "socketcall.bind(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002553 arg2, 3*sizeof(Addr) );
sewardjc483e8f2002-05-03 21:01:35 +00002554 must_be_readable_sockaddr( tst, "socketcall.bind(my_addr.%s)",
2555 (struct sockaddr *) (((UInt*)arg2)[1]), ((UInt*)arg2)[2]);
sewardj2e93c502002-04-12 11:12:52 +00002556 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002557 break;
sewardjc483e8f2002-05-03 21:01:35 +00002558
sewardjde4a1d02002-03-22 01:27:54 +00002559 case SYS_LISTEN:
2560 /* int listen(int s, int backlog); */
sewardj8c824512002-04-14 04:16:48 +00002561 must_be_readable( tst, "socketcall.listen(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002562 arg2, 2*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002563 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002564 break;
2565
2566 case SYS_ACCEPT: {
2567 /* int accept(int s, struct sockaddr *addr, int *p_addrlen); */
2568 Addr addr;
2569 Addr p_addrlen;
2570 UInt addrlen_in, addrlen_out;
sewardj8c824512002-04-14 04:16:48 +00002571 must_be_readable( tst, "socketcall.accept(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002572 arg2, 3*sizeof(Addr) );
2573 addr = ((UInt*)arg2)[1];
2574 p_addrlen = ((UInt*)arg2)[2];
2575 if (p_addrlen != (Addr)NULL) {
sewardj8c824512002-04-14 04:16:48 +00002576 must_be_readable ( tst, "socketcall.accept(addrlen)",
sewardjde4a1d02002-03-22 01:27:54 +00002577 p_addrlen, sizeof(int) );
2578 addrlen_in = safe_dereference( p_addrlen, 0 );
sewardj8c824512002-04-14 04:16:48 +00002579 must_be_writable ( tst, "socketcall.accept(addr)",
sewardjde4a1d02002-03-22 01:27:54 +00002580 addr, addrlen_in );
2581 }
sewardj2e93c502002-04-12 11:12:52 +00002582 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002583 if (!VG_(is_kerror)(res) && res >= 0 && p_addrlen != (Addr)NULL) {
2584 addrlen_out = safe_dereference( p_addrlen, 0 );
2585 if (addrlen_out > 0)
2586 make_readable( addr, addrlen_out );
2587 }
2588 break;
2589 }
2590
2591 case SYS_SENDTO:
2592 /* int sendto(int s, const void *msg, int len,
2593 unsigned int flags,
2594 const struct sockaddr *to, int tolen); */
sewardj8c824512002-04-14 04:16:48 +00002595 must_be_readable( tst, "socketcall.sendto(args)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002596 6*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002597 must_be_readable( tst, "socketcall.sendto(msg)",
sewardjde4a1d02002-03-22 01:27:54 +00002598 ((UInt*)arg2)[1], /* msg */
2599 ((UInt*)arg2)[2] /* len */ );
sewardjc483e8f2002-05-03 21:01:35 +00002600 must_be_readable_sockaddr( tst, "socketcall.sendto(to.%s)",
2601 (struct sockaddr *) (((UInt*)arg2)[4]), ((UInt*)arg2)[5]);
sewardj2e93c502002-04-12 11:12:52 +00002602 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002603 break;
2604
2605 case SYS_SEND:
2606 /* int send(int s, const void *msg, size_t len, int flags); */
sewardj8c824512002-04-14 04:16:48 +00002607 must_be_readable( tst, "socketcall.send(args)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002608 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002609 must_be_readable( tst, "socketcall.send(msg)",
sewardjde4a1d02002-03-22 01:27:54 +00002610 ((UInt*)arg2)[1], /* msg */
2611 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002612 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002613 break;
2614
2615 case SYS_RECVFROM:
2616 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
2617 struct sockaddr *from, int *fromlen); */
sewardj8c824512002-04-14 04:16:48 +00002618 must_be_readable( tst, "socketcall.recvfrom(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002619 arg2, 6*sizeof(Addr) );
2620 if ( ((UInt*)arg2)[4] /* from */ != 0) {
sewardj8c824512002-04-14 04:16:48 +00002621 must_be_readable( tst, "socketcall.recvfrom(fromlen)",
sewardjde4a1d02002-03-22 01:27:54 +00002622 ((UInt*)arg2)[5] /* fromlen */,
2623 sizeof(int) );
sewardj8c824512002-04-14 04:16:48 +00002624 must_be_writable( tst, "socketcall.recvfrom(from)",
sewardjde4a1d02002-03-22 01:27:54 +00002625 ((UInt*)arg2)[4], /*from*/
2626 safe_dereference( (Addr)
2627 ((UInt*)arg2)[5], 0 ) );
2628 }
sewardj8c824512002-04-14 04:16:48 +00002629 must_be_writable( tst, "socketcall.recvfrom(buf)",
sewardjde4a1d02002-03-22 01:27:54 +00002630 ((UInt*)arg2)[1], /* buf */
2631 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002632 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002633 if (!VG_(is_kerror)(res) && res >= 0) {
2634 make_readable( ((UInt*)arg2)[1], /* buf */
2635 ((UInt*)arg2)[2] /* len */ );
2636 if ( ((UInt*)arg2)[4] /* from */ != 0) {
2637 make_readable(
2638 ((UInt*)arg2)[4], /*from*/
2639 safe_dereference( (Addr) ((UInt*)arg2)[5], 0 ) );
2640 }
2641 }
2642 /* phew! */
2643 break;
2644
2645 case SYS_RECV:
2646 /* int recv(int s, void *buf, int len, unsigned int flags); */
2647 /* man 2 recv says:
2648 The recv call is normally used only on a connected socket
2649 (see connect(2)) and is identical to recvfrom with a NULL
2650 from parameter.
2651 */
sewardj8c824512002-04-14 04:16:48 +00002652 must_be_readable( tst, "socketcall.recv(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002653 arg2, 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002654 must_be_writable( tst, "socketcall.recv(buf)",
sewardjde4a1d02002-03-22 01:27:54 +00002655 ((UInt*)arg2)[1], /* buf */
2656 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002657 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002658 if (!VG_(is_kerror)(res) && res >= 0
2659 && ((UInt*)arg2)[1] != (UInt)NULL) {
2660 make_readable( ((UInt*)arg2)[1], /* buf */
2661 ((UInt*)arg2)[2] /* len */ );
2662 }
2663 break;
2664
sewardjc483e8f2002-05-03 21:01:35 +00002665 case SYS_CONNECT:
sewardjde4a1d02002-03-22 01:27:54 +00002666 /* int connect(int sockfd,
2667 struct sockaddr *serv_addr, int addrlen ); */
sewardj8c824512002-04-14 04:16:48 +00002668 must_be_readable( tst, "socketcall.connect(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002669 arg2, 3*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002670 must_be_readable( tst, "socketcall.connect(serv_addr.sa_family)",
sewardjde4a1d02002-03-22 01:27:54 +00002671 ((UInt*)arg2)[1], /* serv_addr */
2672 sizeof (sa_family_t));
sewardjc483e8f2002-05-03 21:01:35 +00002673 must_be_readable_sockaddr( tst,
2674 "socketcall.connect(serv_addr.%s)",
2675 (struct sockaddr *) (((UInt*)arg2)[1]), ((UInt*)arg2)[2]);
sewardj2e93c502002-04-12 11:12:52 +00002676 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002677 break;
sewardjde4a1d02002-03-22 01:27:54 +00002678
2679 case SYS_SETSOCKOPT:
2680 /* int setsockopt(int s, int level, int optname,
2681 const void *optval, int optlen); */
sewardj8c824512002-04-14 04:16:48 +00002682 must_be_readable( tst, "socketcall.setsockopt(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002683 arg2, 5*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002684 must_be_readable( tst, "socketcall.setsockopt(optval)",
sewardjde4a1d02002-03-22 01:27:54 +00002685 ((UInt*)arg2)[3], /* optval */
2686 ((UInt*)arg2)[4] /* optlen */ );
sewardj2e93c502002-04-12 11:12:52 +00002687 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002688 break;
2689
2690 case SYS_GETSOCKOPT:
2691 /* int setsockopt(int s, int level, int optname,
2692 void *optval, socklen_t *optlen); */
sewardj8c824512002-04-14 04:16:48 +00002693 must_be_readable( tst, "socketcall.getsockopt(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002694 arg2, 5*sizeof(Addr) );
2695 {
2696 Addr optval_p = ((UInt*)arg2)[3];
2697 Addr optlen_p = ((UInt*)arg2)[4];
sewardj8c824512002-04-14 04:16:48 +00002698 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
sewardjde4a1d02002-03-22 01:27:54 +00002699 UInt optlen_after;
2700 UInt optlen = safe_dereference ( optlen_p, 0 );
2701 if (optlen > 0)
sewardj8c824512002-04-14 04:16:48 +00002702 must_be_writable( tst, "socketcall.getsockopt(optval)",
sewardjde4a1d02002-03-22 01:27:54 +00002703 optval_p, optlen );
sewardj2e93c502002-04-12 11:12:52 +00002704 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002705 optlen_after = safe_dereference ( optlen_p, 0 );
2706 if (!VG_(is_kerror)(res) && optlen > 0 && optlen_after > 0)
2707 make_readable( optval_p, optlen_after );
2708 }
2709 break;
2710
2711 case SYS_GETSOCKNAME:
2712 /* int getsockname(int s, struct sockaddr* name,
2713 int* namelen) */
sewardj8c824512002-04-14 04:16:48 +00002714 must_be_readable( tst, "socketcall.getsockname(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002715 arg2, 3*sizeof(Addr) );
2716 {
2717 UInt namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2718 if (namelen > 0)
sewardj8c824512002-04-14 04:16:48 +00002719 must_be_writable( tst, "socketcall.getsockname(name)",
sewardjde4a1d02002-03-22 01:27:54 +00002720 ((UInt*)arg2)[1], namelen );
sewardj2e93c502002-04-12 11:12:52 +00002721 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002722 if (!VG_(is_kerror)(res)) {
2723 namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2724 if (namelen > 0
2725 && ((UInt*)arg2)[1] != (UInt)NULL)
2726 make_readable( ((UInt*)arg2)[1], namelen );
2727 }
2728 }
2729 break;
2730
2731 case SYS_GETPEERNAME:
2732 /* int getpeername(int s, struct sockaddr* name,
2733 int* namelen) */
sewardj8c824512002-04-14 04:16:48 +00002734 must_be_readable( tst, "socketcall.getpeername(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002735 arg2, 3*sizeof(Addr) );
2736 {
2737 UInt namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2738 if (namelen > 0)
sewardj8c824512002-04-14 04:16:48 +00002739 must_be_writable( tst, "socketcall.getpeername(name)",
sewardjde4a1d02002-03-22 01:27:54 +00002740 ((UInt*)arg2)[1], namelen );
sewardj2e93c502002-04-12 11:12:52 +00002741 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002742 if (!VG_(is_kerror)(res)) {
2743 namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2744 if (namelen > 0
2745 && ((UInt*)arg2)[1] != (UInt)NULL)
2746 make_readable( ((UInt*)arg2)[1], namelen );
2747 }
2748 }
2749 break;
2750
2751 case SYS_SHUTDOWN:
2752 /* int shutdown(int s, int how); */
sewardj8c824512002-04-14 04:16:48 +00002753 must_be_readable( tst, "socketcall.shutdown(args)",
2754 arg2, 2*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002755 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002756 break;
2757
2758 case SYS_SENDMSG:
2759 {
2760 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
2761
2762 /* this causes warnings, and I don't get why. glibc bug?
2763 * (after all it's glibc providing the arguments array)
2764 must_be_readable( "socketcall.sendmsg(args)",
2765 arg2, 3*sizeof(Addr) );
2766 */
2767
2768 struct msghdr *msg = (struct msghdr *)((UInt *)arg2)[ 1 ];
sewardj8c824512002-04-14 04:16:48 +00002769 msghdr_foreachfield ( tst, msg, must_be_readable_sendmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002770
sewardj2e93c502002-04-12 11:12:52 +00002771 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002772 break;
2773 }
2774
2775 case SYS_RECVMSG:
2776 {
2777 /* int recvmsg(int s, struct msghdr *msg, int flags); */
2778
2779 /* this causes warnings, and I don't get why. glibc bug?
2780 * (after all it's glibc providing the arguments array)
2781 must_be_readable( "socketcall.recvmsg(args)",
2782 arg2, 3*sizeof(Addr) );
2783 */
2784
2785 struct msghdr *msg = (struct msghdr *)((UInt *)arg2)[ 1 ];
sewardj8c824512002-04-14 04:16:48 +00002786 msghdr_foreachfield ( tst, msg, must_be_writable_recvmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002787
sewardj2e93c502002-04-12 11:12:52 +00002788 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002789
2790 if ( !VG_(is_kerror)( res ) )
sewardj8c824512002-04-14 04:16:48 +00002791 msghdr_foreachfield( tst, msg, make_readable_recvmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002792
2793 break;
2794 }
2795
2796 default:
2797 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",arg1);
2798 VG_(panic)("... bye!\n");
2799 break; /*NOTREACHED*/
2800 }
2801 break;
2802
2803 case __NR_stat: /* syscall 106 */
2804 /* int stat(const char *file_name, struct stat *buf); */
2805 if (VG_(clo_trace_syscalls))
2806 VG_(printf)("stat ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002807 must_be_readable_asciiz( tst, "stat(file_name)", arg1 );
2808 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +00002809 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002810 if (!VG_(is_kerror)(res))
2811 make_readable( arg2, sizeof(struct stat) );
2812 break;
2813
2814 case __NR_statfs: /* syscall 99 */
2815 /* int statfs(const char *path, struct statfs *buf); */
2816 if (VG_(clo_trace_syscalls))
2817 VG_(printf)("statfs ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002818 must_be_readable_asciiz( tst, "statfs(path)", arg1 );
2819 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct statfs) );
sewardj2e93c502002-04-12 11:12:52 +00002820 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002821 if (!VG_(is_kerror)(res))
2822 make_readable( arg2, sizeof(struct statfs) );
2823 break;
2824
2825 case __NR_symlink: /* syscall 83 */
2826 /* int symlink(const char *oldpath, const char *newpath); */
2827 if (VG_(clo_trace_syscalls))
2828 VG_(printf)("symlink ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002829 must_be_readable_asciiz( tst, "symlink(oldpath)", arg1 );
2830 must_be_readable_asciiz( tst, "symlink(newpath)", arg2 );
sewardj2e93c502002-04-12 11:12:52 +00002831 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002832 break;
2833
2834# if defined(__NR_stat64)
2835 case __NR_stat64: /* syscall 195 */
2836 /* int stat64(const char *file_name, struct stat64 *buf); */
2837 if (VG_(clo_trace_syscalls))
2838 VG_(printf)("stat64 ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002839 must_be_readable_asciiz( tst, "stat64(file_name)", arg1 );
2840 must_be_writable( tst, "stat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00002841 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002842 if (!VG_(is_kerror)(res))
2843 make_readable( arg2, sizeof(struct stat64) );
2844 break;
2845# endif
2846
2847# if defined(__NR_fstat64)
2848 case __NR_fstat64: /* syscall 197 */
2849 /* int fstat64(int filedes, struct stat64 *buf); */
2850 if (VG_(clo_trace_syscalls))
2851 VG_(printf)("fstat64 ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002852 must_be_writable( tst, "fstat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00002853 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002854 if (!VG_(is_kerror)(res))
2855 make_readable( arg2, sizeof(struct stat64) );
2856 break;
2857# endif
2858
2859 case __NR_sysinfo: /* syscall 116 */
2860 /* int sysinfo(struct sysinfo *info); */
2861 if (VG_(clo_trace_syscalls))
2862 VG_(printf)("sysinfo ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002863 must_be_writable( tst, "sysinfo(info)", arg1, sizeof(struct sysinfo) );
sewardj2e93c502002-04-12 11:12:52 +00002864 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002865 if (!VG_(is_kerror)(res))
2866 make_readable( arg1, sizeof(struct sysinfo) );
2867 break;
2868
2869 case __NR_time: /* syscall 13 */
2870 /* time_t time(time_t *t); */
2871 if (VG_(clo_trace_syscalls))
2872 VG_(printf)("time ( %p )\n",arg1);
2873 if (arg1 != (UInt)NULL) {
sewardj8c824512002-04-14 04:16:48 +00002874 must_be_writable( tst, "time", arg1, sizeof(time_t) );
sewardjde4a1d02002-03-22 01:27:54 +00002875 }
sewardj2e93c502002-04-12 11:12:52 +00002876 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002877 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2878 make_readable( arg1, sizeof(time_t) );
2879 }
2880 break;
2881
2882 case __NR_times: /* syscall 43 */
2883 /* clock_t times(struct tms *buf); */
2884 if (VG_(clo_trace_syscalls))
2885 VG_(printf)("times ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002886 must_be_writable( tst, "times(buf)", arg1, sizeof(struct tms) );
sewardj2e93c502002-04-12 11:12:52 +00002887 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002888 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2889 make_readable( arg1, sizeof(struct tms) );
2890 }
2891 break;
2892
2893 case __NR_truncate: /* syscall 92 */
2894 /* int truncate(const char *path, size_t length); */
2895 if (VG_(clo_trace_syscalls))
2896 VG_(printf)("truncate ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002897 must_be_readable_asciiz( tst, "truncate(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002898 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002899 break;
2900
2901 case __NR_umask: /* syscall 60 */
2902 /* mode_t umask(mode_t mask); */
2903 if (VG_(clo_trace_syscalls))
2904 VG_(printf)("umask ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002905 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002906 break;
2907
2908 case __NR_unlink: /* syscall 10 */
2909 /* int unlink(const char *pathname) */
2910 if (VG_(clo_trace_syscalls))
2911 VG_(printf)("ulink ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002912 must_be_readable_asciiz( tst, "unlink(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002913 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002914 break;
2915
2916 case __NR_uname: /* syscall 122 */
2917 /* int uname(struct utsname *buf); */
2918 if (VG_(clo_trace_syscalls))
2919 VG_(printf)("uname ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002920 must_be_writable( tst, "uname(buf)", arg1, sizeof(struct utsname) );
sewardj2e93c502002-04-12 11:12:52 +00002921 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002922 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2923 make_readable( arg1, sizeof(struct utsname) );
2924 }
2925 break;
2926
2927 case __NR_utime: /* syscall 30 */
2928 /* int utime(const char *filename, struct utimbuf *buf); */
2929 if (VG_(clo_trace_syscalls))
2930 VG_(printf)("utime ( %p, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002931 must_be_readable_asciiz( tst, "utime(filename)", arg1 );
sewardjde4a1d02002-03-22 01:27:54 +00002932 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002933 must_be_readable( tst, "utime(buf)", arg2,
2934 sizeof(struct utimbuf) );
sewardj2e93c502002-04-12 11:12:52 +00002935 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002936 break;
2937
2938 case __NR_wait4: /* syscall 114 */
2939 /* pid_t wait4(pid_t pid, int *status, int options,
2940 struct rusage *rusage) */
2941 if (VG_(clo_trace_syscalls))
2942 VG_(printf)("wait4 ( %d, %p, %d, %p )\n",
2943 arg1,arg2,arg3,arg4);
2944 if (arg2 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002945 must_be_writable( tst, "wait4(status)", arg2, sizeof(int) );
sewardjde4a1d02002-03-22 01:27:54 +00002946 if (arg4 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002947 must_be_writable( tst, "wait4(rusage)", arg4,
2948 sizeof(struct rusage) );
sewardj2e93c502002-04-12 11:12:52 +00002949 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002950 if (!VG_(is_kerror)(res)) {
2951 if (arg2 != (Addr)NULL)
2952 make_readable( arg2, sizeof(int) );
2953 if (arg4 != (Addr)NULL)
2954 make_readable( arg4, sizeof(struct rusage) );
2955 }
2956 break;
2957
sewardjde4a1d02002-03-22 01:27:54 +00002958 case __NR_writev: { /* syscall 146 */
2959 /* int writev(int fd, const struct iovec * vector, size_t count); */
2960 UInt i;
2961 struct iovec * vec;
2962 if (VG_(clo_trace_syscalls))
2963 VG_(printf)("writev ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002964 must_be_readable( tst, "writev(vector)",
sewardjde4a1d02002-03-22 01:27:54 +00002965 arg2, arg3 * sizeof(struct iovec) );
2966 /* ToDo: don't do any of the following if the vector is invalid */
2967 vec = (struct iovec *)arg2;
2968 for (i = 0; i < arg3; i++)
sewardj8c824512002-04-14 04:16:48 +00002969 must_be_readable( tst, "writev(vector[...])",
sewardjde4a1d02002-03-22 01:27:54 +00002970 (UInt)vec[i].iov_base,vec[i].iov_len );
sewardj2e93c502002-04-12 11:12:52 +00002971 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002972 break;
2973 }
2974
2975 /*-------------------------- SIGNALS --------------------------*/
2976
2977 /* Normally set to 1, so that Valgrind's signal-simulation machinery
2978 is engaged. Sometimes useful to disable (set to 0), for
2979 debugging purposes, to make clients more deterministic. */
2980# define SIGNAL_SIMULATION 1
2981
sewardj2342c972002-05-22 23:34:20 +00002982 case __NR_sigaltstack: /* syscall 186 */
2983 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
2984 if (VG_(clo_trace_syscalls))
2985 VG_(printf)("sigaltstack ( %p, %p )\n",arg1,arg2);
2986 if (arg1 != (UInt)NULL) {
2987 must_be_readable( tst, "sigaltstack(ss)",
2988 arg1, sizeof(vki_kstack_t) );
2989 }
2990 if (arg2 != (UInt)NULL) {
2991 must_be_writable( tst, "sigaltstack(ss)",
2992 arg1, sizeof(vki_kstack_t) );
2993 }
2994# if SIGNAL_SIMULATION
2995 VG_(do__NR_sigaltstack) (tid);
2996 res = tst->m_eax;
2997# else
2998 KERNEL_DO_SYSCALL(tid,res);
2999# endif
3000 if (!VG_(is_kerror)(res) && res == 0 && arg2 != (UInt)NULL)
3001 make_readable( arg2, sizeof(vki_kstack_t));
3002 break;
3003
sewardjde4a1d02002-03-22 01:27:54 +00003004 case __NR_rt_sigaction:
3005 case __NR_sigaction:
3006 /* int sigaction(int signum, struct k_sigaction *act,
3007 struct k_sigaction *oldact); */
3008 if (VG_(clo_trace_syscalls))
3009 VG_(printf)("sigaction ( %d, %p, %p )\n",arg1,arg2,arg3);
3010 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00003011 must_be_readable( tst, "sigaction(act)",
sewardjde4a1d02002-03-22 01:27:54 +00003012 arg2, sizeof(vki_ksigaction));
3013 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00003014 must_be_writable( tst, "sigaction(oldact)",
sewardjde4a1d02002-03-22 01:27:54 +00003015 arg3, sizeof(vki_ksigaction));
3016 /* We do this one ourselves! */
3017# if SIGNAL_SIMULATION
sewardj2e93c502002-04-12 11:12:52 +00003018 VG_(do__NR_sigaction)(tid);
3019 res = tst->m_eax;
sewardjde4a1d02002-03-22 01:27:54 +00003020# else
3021 /* debugging signals; when we don't handle them. */
sewardj2e93c502002-04-12 11:12:52 +00003022 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00003023# endif
3024 if (!VG_(is_kerror)(res) && res == 0 && arg3 != (UInt)NULL)
3025 make_readable( arg3, sizeof(vki_ksigaction));
3026 break;
3027
3028 case __NR_rt_sigprocmask:
3029 case __NR_sigprocmask:
3030 /* int sigprocmask(int how, k_sigset_t *set,
3031 k_sigset_t *oldset); */
3032 if (VG_(clo_trace_syscalls))
3033 VG_(printf)("sigprocmask ( %d, %p, %p )\n",arg1,arg2,arg3);
3034 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00003035 must_be_readable( tst, "sigprocmask(set)",
sewardjde4a1d02002-03-22 01:27:54 +00003036 arg2, sizeof(vki_ksigset_t));
3037 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00003038 must_be_writable( tst, "sigprocmask(oldset)",
sewardjde4a1d02002-03-22 01:27:54 +00003039 arg3, sizeof(vki_ksigset_t));
sewardj018f7622002-05-15 21:13:39 +00003040# if SIGNAL_SIMULATION
3041 VG_(do__NR_sigprocmask) ( tid,
3042 arg1 /*how*/,
3043 (vki_ksigset_t*) arg2,
3044 (vki_ksigset_t*) arg3 );
3045 res = tst->m_eax;
3046# else
sewardj2e93c502002-04-12 11:12:52 +00003047 KERNEL_DO_SYSCALL(tid,res);
sewardj018f7622002-05-15 21:13:39 +00003048# endif
sewardjde4a1d02002-03-22 01:27:54 +00003049 if (!VG_(is_kerror)(res) && res == 0 && arg3 != (UInt)NULL)
3050 make_readable( arg3, sizeof(vki_ksigset_t));
sewardjde4a1d02002-03-22 01:27:54 +00003051 break;
3052
3053 default:
3054 VG_(message)
3055 (Vg_DebugMsg,"FATAL: unhandled syscall: %d",syscallno);
3056 VG_(message)
3057 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
3058 VG_(message)
3059 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
3060 VG_(unimplemented)("no wrapper for the above system call");
3061 vg_assert(3+3 == 7);
3062 break; /*NOTREACHED*/
3063 }
3064
sewardjde4a1d02002-03-22 01:27:54 +00003065 /* { void zzzmemscan(void); zzzmemscan(); } */
3066
sewardj126a41f2002-05-07 23:45:03 +00003067 if (! VG_(first_and_last_secondaries_look_plausible)())
sewardjde4a1d02002-03-22 01:27:54 +00003068 sane_before_call = False;
3069
3070 if (sane_before_call && (!sane_after_call)) {
sewardj2e93c502002-04-12 11:12:52 +00003071 VG_(message)(Vg_DebugMsg, "perform_assumed_nonblocking_syscall: ");
sewardjde4a1d02002-03-22 01:27:54 +00003072 VG_(message)(Vg_DebugMsg,
3073 "probable sanity check failure for syscall number %d\n",
3074 syscallno );
3075 VG_(panic)("aborting due to the above ... bye!");
3076 }
3077
3078 VGP_POPCC;
3079}
3080
3081
sewardj2e93c502002-04-12 11:12:52 +00003082
3083/* Perform pre- and post- actions for a blocking syscall, but do not
3084 do the syscall itself. If res is NULL, the pre-syscall actions are
3085 to be performed. If res is non-NULL, the post-syscall actions are
3086 to be performed, and *res is assumed to hold the result of the
3087 syscall. This slightly strange scheme makes it impossible to
3088 mistakenly use the value of *res in the pre-syscall actions.
3089
3090 This doesn't actually do the syscall itself, it is important to
3091 observe.
3092
3093 Because %eax is used both for the syscall number before the call
3094 and the result value afterwards, we can't reliably use it to get
3095 the syscall number. So the caller has to pass it explicitly.
3096*/
sewardj8c824512002-04-14 04:16:48 +00003097void VG_(check_known_blocking_syscall) ( ThreadId tid,
sewardj2e93c502002-04-12 11:12:52 +00003098 Int syscallno,
3099 Int* /*IN*/ res )
3100{
sewardj018f7622002-05-15 21:13:39 +00003101 ThreadState* tst;
3102 Bool sane_before_post, sane_after_post;
3103 UInt arg1, arg2, arg3;
3104
sewardj2e93c502002-04-12 11:12:52 +00003105 VGP_PUSHCC(VgpSyscall);
3106
sewardj018f7622002-05-15 21:13:39 +00003107 vg_assert(VG_(is_valid_tid)(tid));
3108 sane_before_post = True;
3109 sane_after_post = True;
3110 tst = & VG_(threads)[tid];
3111 arg1 = tst->m_ebx;
3112 arg2 = tst->m_ecx;
3113 arg3 = tst->m_edx;
3114 /*
3115 arg4 = tst->m_esi;
3116 arg5 = tst->m_edi;
3117 */
3118
sewardj2e93c502002-04-12 11:12:52 +00003119 if (res != NULL
sewardj126a41f2002-05-07 23:45:03 +00003120 && ! VG_(first_and_last_secondaries_look_plausible)())
sewardj2e93c502002-04-12 11:12:52 +00003121 sane_before_post = False;
3122
3123 switch (syscallno) {
3124
3125 case __NR_read: /* syscall 3 */
3126 /* size_t read(int fd, void *buf, size_t count); */
3127 if (res == NULL) {
3128 /* PRE */
3129 if (VG_(clo_trace_syscalls))
3130 VG_(printf)(
3131 "SYSCALL--PRE[%d,%d] read ( %d, %p, %d )\n",
3132 VG_(getpid)(), tid,
3133 arg1, arg2, arg3);
sewardj8c824512002-04-14 04:16:48 +00003134 must_be_writable( tst, "read(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00003135 } else {
3136 /* POST */
3137 if (VG_(clo_trace_syscalls))
3138 VG_(printf)(
3139 "SYSCALL-POST[%d,%d] read ( %d, %p, %d ) --> %d\n",
3140 VG_(getpid)(), tid,
3141 arg1, arg2, arg3, *res);
3142 if (!VG_(is_kerror)(*res) && *res > 0) {
3143 make_readable( arg2, *res );
3144 }
3145 }
3146 break;
3147
3148 case __NR_write: /* syscall 4 */
3149 /* size_t write(int fd, const void *buf, size_t count); */
3150 if (res == NULL) {
3151 /* PRE */
3152 if (VG_(clo_trace_syscalls))
3153 VG_(printf)(
3154 "SYSCALL--PRE[%d,%d] write ( %d, %p, %d )\n",
3155 VG_(getpid)(), tid,
3156 arg1, arg2, arg3);
sewardj8c824512002-04-14 04:16:48 +00003157 must_be_readable( tst, "write(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00003158 } else {
3159 /* POST */
3160 if (VG_(clo_trace_syscalls))
3161 VG_(printf)(
3162 "SYSCALL-POST[%d,%d] write ( %d, %p, %d ) --> %d\n",
3163 VG_(getpid)(), tid,
3164 arg1, arg2, arg3, *res);
3165 }
3166 break;
3167
3168 default:
3169 VG_(printf)("check_known_blocking_syscall: unexpected %d\n",
3170 syscallno);
3171 VG_(panic)("check_known_blocking_syscall");
3172 /*NOTREACHED*/
3173 break;
3174 }
3175
3176 if (res != NULL) { /* only check after syscall */
sewardj126a41f2002-05-07 23:45:03 +00003177 if (! VG_(first_and_last_secondaries_look_plausible)())
sewardj2e93c502002-04-12 11:12:52 +00003178 sane_after_post = False;
3179
3180 if (sane_before_post && (!sane_after_post)) {
3181 VG_(message)(Vg_DebugMsg, "perform_known_blocking_syscall: ");
3182 VG_(message)(Vg_DebugMsg,
3183 "probable sanity check failure for syscall number %d\n",
3184 syscallno );
3185 VG_(panic)("aborting due to the above ... bye!");
3186 }
3187 }
3188
3189 VGP_POPCC;
3190}
3191
3192
sewardjde4a1d02002-03-22 01:27:54 +00003193/*--------------------------------------------------------------------*/
3194/*--- end vg_syscall_mem.c ---*/
3195/*--------------------------------------------------------------------*/