Significantly improved SYSV IPC call handling. Unfortunately some of
this stuff doesn't use safe_dereference when it should.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@38 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/ChangeLog b/ChangeLog
index 5683545..14cf886 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-03-29 Tom Hughes <thh@cyberscience.com>
+
+ * vg_syscall_mem.c: Significantly improved SYSV IPC call
+ handling. Unfortunately some of this stuff doesn't use
+ safe_dereference when it should.
+
2002-03-27 Frederic Gobry <gobry@puck.ch>
* configure.in: added support for maintainer mode. Now, to
diff --git a/coregrind/vg_unsafe.h b/coregrind/vg_unsafe.h
index 9fa9153..52c459b 100644
--- a/coregrind/vg_unsafe.h
+++ b/coregrind/vg_unsafe.h
@@ -46,6 +46,9 @@
#include <net/if.h> /* for struct ifreq et al */
#include <net/if_arp.h> /* for struct arpreq */
#include <net/route.h> /* for struct rtentry */
+#include <asm/ipc.h> /* for struct ipc_kludge */
+#include <linux/msg.h> /* for struct msgbuf */
+#include <linux/sem.h> /* for struct sembuf */
#include <linux/isdn.h> /* for ISDN ioctls */
#include <linux/module.h> /* for struct module */
diff --git a/vg_syscall_mem.c b/vg_syscall_mem.c
index 0f585d9..ce660f4 100644
--- a/vg_syscall_mem.c
+++ b/vg_syscall_mem.c
@@ -1114,14 +1114,83 @@
arg1,arg2,arg3,arg4,arg5,arg6);
switch (arg1 /* call */) {
case 1: /* IPCOP_semop */
- case 2: /* IPCOP_semget */
- case 3: /* IPCOP_semctl */
- case 11: /* IPCOP_msgsnd */
- case 12: /* IPCOP_msgrcv */
- case 13: /* IPCOP_msgget */
- case 14: /* IPCOP_msgctl */
+ must_be_readable ( "semop(sops)", arg5,
+ arg3 * sizeof(struct sembuf) );
KERNEL_DO_SYSCALL(res);
break;
+ case 2: /* IPCOP_semget */
+ case 3: /* IPCOP_semctl */
+ KERNEL_DO_SYSCALL(res);
+ break;
+ case 11: /* IPCOP_msgsnd */
+ {
+ struct msgbuf *msgp = (struct msgbuf *)arg5;
+ Int msgsz = arg3;
+
+ must_be_readable ( "msgsnd(msgp->mtype)",
+ (UInt)&msgp->mtype, sizeof(msgp->mtype) );
+ must_be_readable ( "msgsnd(msgp->mtext)",
+ (UInt)msgp->mtext, msgsz );
+
+ KERNEL_DO_SYSCALL(res);
+ break;
+ }
+ case 12: /* IPCOP_msgrcv */
+ {
+ struct msgbuf *msgp = ((struct ipc_kludge *)arg5)->msgp;
+ Int msgsz = arg3;
+
+ must_be_writable ( "msgsnd(msgp->mtype)",
+ (UInt)&msgp->mtype, sizeof(msgp->mtype) );
+ must_be_writable ( "msgsnd(msgp->mtext)",
+ (UInt)msgp->mtext, msgsz );
+
+ KERNEL_DO_SYSCALL(res);
+
+ if ( !VG_(is_kerror)(res) && res > 0 ) {
+ make_readable ( (UInt)&msgp->mtype, sizeof(msgp->mtype) );
+ make_readable ( (UInt)msgp->mtext, res );
+ }
+ break;
+ }
+ case 13: /* IPCOP_msgget */
+ KERNEL_DO_SYSCALL(res);
+ break;
+ case 14: /* IPCOP_msgctl */
+ {
+ switch (arg3 /* cmd */) {
+ case IPC_STAT:
+ must_be_writable ( "msgctl(buf)", arg5,
+ sizeof(struct msqid_ds) );
+ KERNEL_DO_SYSCALL(res);
+ if ( !VG_(is_kerror)(res) && res > 0 ) {
+ make_readable ( arg5, sizeof(struct msqid_ds) );
+ }
+ break;
+ case IPC_SET:
+ must_be_readable ( "msgctl(buf)", arg5,
+ sizeof(struct msqid_ds) );
+ KERNEL_DO_SYSCALL(res);
+ break;
+ case IPC_STAT|IPC_64:
+ must_be_writable ( "msgctl(buf)", arg5,
+ sizeof(struct msqid64_ds) );
+ KERNEL_DO_SYSCALL(res);
+ if ( !VG_(is_kerror)(res) && res > 0 ) {
+ make_readable ( arg5, sizeof(struct msqid64_ds) );
+ }
+ break;
+ case IPC_SET|IPC_64:
+ must_be_readable ( "msgctl(buf)", arg5,
+ sizeof(struct msqid64_ds) );
+ KERNEL_DO_SYSCALL(res);
+ break;
+ default:
+ KERNEL_DO_SYSCALL(res);
+ break;
+ }
+ break;
+ }
case 21: /* IPCOP_shmat */
{
Int shmid = arg2;
diff --git a/vg_unsafe.h b/vg_unsafe.h
index 9fa9153..52c459b 100644
--- a/vg_unsafe.h
+++ b/vg_unsafe.h
@@ -46,6 +46,9 @@
#include <net/if.h> /* for struct ifreq et al */
#include <net/if_arp.h> /* for struct arpreq */
#include <net/route.h> /* for struct rtentry */
+#include <asm/ipc.h> /* for struct ipc_kludge */
+#include <linux/msg.h> /* for struct msgbuf */
+#include <linux/sem.h> /* for struct sembuf */
#include <linux/isdn.h> /* for ISDN ioctls */
#include <linux/module.h> /* for struct module */