Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src fix a race condition between path resolution in userland



details:   https://anonhg.NetBSD.org/src/rev/a63835c8bb04
branches:  trunk
changeset: 550914:a63835c8bb04
user:      cb <cb%NetBSD.org@localhost>
date:      Mon Aug 25 09:12:42 2003 +0000

description:
fix a race condition between path resolution in userland
and the subsequent namei(): inform the kernel portion of
valid filenames and then disallow symlink lookups for
those filenames by means of a hook in namei().
with suggestions from provos@

also, add (currently unused) seqnr field to struct
systrace_replace, from provos@

diffstat:

 bin/systrace/intercept-translate.c |   6 +-
 bin/systrace/intercept.c           |  35 ++++++++++----
 bin/systrace/intercept.h           |  14 +++--
 bin/systrace/netbsd-syscalls.c     |  14 ++++-
 bin/systrace/openbsd-syscalls.c    |   7 +-
 bin/systrace/systrace.c            |  30 +++++------
 bin/systrace/systrace.h            |   4 +-
 sys/kern/kern_systrace.c           |  94 +++++++++++++++++++++++++++++++------
 sys/kern/vfs_lookup.c              |  12 ++++-
 sys/sys/systrace.h                 |  11 ++++-
 10 files changed, 166 insertions(+), 61 deletions(-)

diffs (truncated from 672 to 300 lines):

diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/intercept-translate.c
--- a/bin/systrace/intercept-translate.c        Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/intercept-translate.c        Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intercept-translate.c,v 1.5 2002/08/28 03:52:45 itojun Exp $   */
+/*     $NetBSD: intercept-translate.c,v 1.6 2003/08/25 09:12:45 cb Exp $       */
 /*     $OpenBSD: intercept-translate.c,v 1.9 2002/08/01 20:16:45 provos Exp $  */
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: intercept-translate.c,v 1.5 2002/08/28 03:52:45 itojun Exp $");
+__RCSID("$NetBSD: intercept-translate.c,v 1.6 2003/08/25 09:12:45 cb Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -147,6 +147,7 @@
 
        trans->trans_size = len;
        memcpy(trans->trans_data, name, len);
+       trans->trans_flags = ICTRANS_NOLINKS;
 
        return (0);
 }
@@ -217,6 +218,7 @@
 
        trans->trans_size = len;
        memcpy(trans->trans_data, name, len);
+       trans->trans_flags = ICTRANS_NOLINKS;
 
        return (0);
 }
diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/intercept.c
--- a/bin/systrace/intercept.c  Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/intercept.c  Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intercept.c,v 1.18 2003/08/02 14:45:08 provos Exp $    */
+/*     $NetBSD: intercept.c,v 1.19 2003/08/25 09:12:45 cb Exp $        */
 /*     $OpenBSD: intercept.c,v 1.29 2002/08/28 03:30:27 itojun Exp $   */
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: intercept.c,v 1.18 2003/08/02 14:45:08 provos Exp $");
+__RCSID("$NetBSD: intercept.c,v 1.19 2003/08/25 09:12:45 cb Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -61,7 +61,7 @@
        char emulation[16];
 
        short (*cb)(int, pid_t, int, const char *, int, const char *, void *,
-           int, struct intercept_tlq *, void *);
+           int, struct intercept_replace *, struct intercept_tlq *, void *);
        void *cb_arg;
 
        struct intercept_tlq tls;
@@ -184,7 +184,7 @@
 int
 intercept_register_sccb(char *emulation, char *name,
     short (*cb)(int, pid_t, int, const char *, int, const char *, void *, int,
-       struct intercept_tlq *, void *),
+       struct intercept_replace *, struct intercept_tlq *, void *),
     void *cbarg)
 {
        struct intercept_syscall *tmp;
@@ -511,7 +511,7 @@
 
 int
 intercept_replace_add(struct intercept_replace *repl, int off,
-    u_char *addr, size_t len)
+    u_char *addr, size_t len, u_int flags)
 {
        int ind = repl->num;
 
@@ -521,6 +521,7 @@
        repl->ind[ind] = off;
        repl->address[ind] = addr;
        repl->len[ind] = len;
+       repl->flags[ind] = flags;
 
        repl->num++;
 
@@ -528,12 +529,13 @@
 }
 
 int
-intercept_replace(int fd, pid_t pid, struct intercept_replace *repl)
+intercept_replace(int fd, pid_t pid, u_int16_t seqnr,
+    struct intercept_replace *repl)
 {
        if (repl->num == 0)
                return (0);
 
-       return (intercept.replace(fd, pid, repl));
+       return (intercept.replace(fd, pid, seqnr, repl));
 }
 
 char *
@@ -762,10 +764,23 @@
                                break;
                }
 
-               if (!ic_abort)
+               if (!ic_abort) {
+                       struct intercept_replace repl;
+
+                       intercept_replace_init(&repl);
+
                        action = (*sc->cb)(fd, pid, policynr, name, code,
-                           emulation, args, argsize, &sc->tls, sc->cb_arg);
-               else
+                           emulation, args, argsize, &repl,
+                           &sc->tls, sc->cb_arg);
+
+                       if (action < ICPOLICY_NEVER) {
+                               /* If we can not rewrite the arguments,
+                                * system call fails.
+                                */
+                               if (intercept_replace(fd, pid, seqnr, &repl) == -1)
+                                       action = ICPOLICY_NEVER;
+                       }
+               } else
                        action = ICPOLICY_NEVER;
        } else if (intercept_gencb != NULL)
                action = (*intercept_gencb)(fd, pid, policynr, name, code,
diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/intercept.h
--- a/bin/systrace/intercept.h  Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/intercept.h  Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intercept.h,v 1.12 2003/08/02 14:29:33 provos Exp $    */
+/*     $NetBSD: intercept.h,v 1.13 2003/08/25 09:12:45 cb Exp $        */
 /*     $OpenBSD: intercept.h,v 1.11 2002/08/04 04:15:50 provos Exp $   */
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -57,7 +57,7 @@
        int (*newpolicy)(int);
        int (*assignpolicy)(int, pid_t, int);
        int (*policy)(int, int, int, short);
-       int (*replace)(int, pid_t, struct intercept_replace *);
+       int (*replace)(int, pid_t, u_int16_t, struct intercept_replace *);
        void (*clonepid)(struct intercept_pid *, struct intercept_pid *);
        void (*freepid)(struct intercept_pid *);
 };
@@ -76,6 +76,8 @@
 
 #define ICFLAGS_RESULT 1
 
+#define ICTRANS_NOLINKS        1       /* translation should have no symlinks */
+
 /* Privilege elevation */
 struct elevate {
 #define ELEVATE_UID    0x01
@@ -122,6 +124,7 @@
        void *trans_data;
        size_t trans_size;
        char *trans_print;
+       u_int trans_flags;
        TAILQ_ENTRY(intercept_translate) next;
 };
 
@@ -130,6 +133,7 @@
        int ind[INTERCEPT_MAXSYSCALLARGS];
        u_char *address[INTERCEPT_MAXSYSCALLARGS];
        size_t len[INTERCEPT_MAXSYSCALLARGS];
+       u_int flags[INTERCEPT_MAXSYSCALLARGS];
 };
 
 TAILQ_HEAD(intercept_tlq, intercept_translate);
@@ -148,12 +152,12 @@
 void intercept_policy_free(int);
 
 int intercept_replace_init(struct intercept_replace *);
-int intercept_replace_add(struct intercept_replace *, int, u_char *, size_t);
-int intercept_replace(int, pid_t, struct intercept_replace *);
+int intercept_replace_add(struct intercept_replace *, int, u_char *, size_t, u_int);
+int intercept_replace(int, pid_t, u_int16_t, struct intercept_replace *);
 
 int intercept_register_sccb(char *, char *,
     short (*)(int, pid_t, int, const char *, int, const char *, void *, int,
-       struct intercept_tlq *, void *),
+       struct intercept_replace *, struct intercept_tlq *, void *),
     void *);
 void *intercept_sccb_cbarg(char *, char *);
 
diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/netbsd-syscalls.c
--- a/bin/systrace/netbsd-syscalls.c    Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/netbsd-syscalls.c    Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd-syscalls.c,v 1.12 2003/06/03 04:33:44 provos Exp $      */
+/*     $NetBSD: netbsd-syscalls.c,v 1.13 2003/08/25 09:12:45 cb Exp $  */
 
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: netbsd-syscalls.c,v 1.12 2003/06/03 04:33:44 provos Exp $");
+__RCSID("$NetBSD: netbsd-syscalls.c,v 1.13 2003/08/25 09:12:45 cb Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -158,7 +158,7 @@
 static int nbsd_newpolicy(int);
 static int nbsd_assignpolicy(int, pid_t, int);
 static int nbsd_modifypolicy(int, int, int, short);
-static int nbsd_replace(int, pid_t, struct intercept_replace *);
+static int nbsd_replace(int, pid_t, u_int16_t, struct intercept_replace *);
 static int nbsd_io(int, pid_t, int, void *, u_char *, size_t);
 static int nbsd_setcwd(int, pid_t);
 static int nbsd_restcwd(int);
@@ -447,7 +447,8 @@
 }
 
 static int
-nbsd_replace(int fd, pid_t pid, struct intercept_replace *repl)
+nbsd_replace(int fd, pid_t pid, u_int16_t seqnr,
+    struct intercept_replace *repl)
 {
        struct systrace_replace replace;
        size_t len, off;
@@ -458,6 +459,7 @@
        }
 
        replace.strr_pid = pid;
+       replace.strr_seqnr = seqnr;
        replace.strr_nrepl = repl->num;
        replace.strr_base = malloc(len);
        replace.strr_len = len;
@@ -475,6 +477,10 @@
                replace.strr_off[i] = off;
                memcpy(replace.strr_base + off,
                    repl->address[i], repl->len[i]);
+               if (repl->flags[i] & ICTRANS_NOLINKS) {
+                       replace.strr_flags[i] = SYSTR_NOLINKS;
+               } else
+                       replace.strr_flags[i] = 0;
 
                off += repl->len[i];
        }
diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/openbsd-syscalls.c
--- a/bin/systrace/openbsd-syscalls.c   Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/openbsd-syscalls.c   Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: openbsd-syscalls.c,v 1.8 2003/06/03 04:33:44 provos Exp $      */
+/*     $NetBSD: openbsd-syscalls.c,v 1.9 2003/08/25 09:12:45 cb Exp $  */
 /*     $OpenBSD: openbsd-syscalls.c,v 1.12 2002/08/28 03:30:27 itojun Exp $    */
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -133,7 +133,7 @@
 static int obsd_newpolicy(int);
 static int obsd_assignpolicy(int, pid_t, int);
 static int obsd_modifypolicy(int, int, int, short);
-static int obsd_replace(int, pid_t, struct intercept_replace *);
+static int obsd_replace(int, pid_t, u_int16_t, struct intercept_replace *);
 static int obsd_io(int, pid_t, int, void *, u_char *, size_t);
 static int obsd_setcwd(int, pid_t);
 static int obsd_restcwd(int);
@@ -429,7 +429,8 @@
 }
 
 static int
-obsd_replace(int fd, pid_t pid, struct intercept_replace *repl)
+obsd_replace(int fd, pid_t pid, u_int16_t seqnr,
+    struct intercept_replace *repl)
 {
        struct systrace_replace replace;
        size_t len, off;
diff -r 9f1ee1edf1a8 -r a63835c8bb04 bin/systrace/systrace.c
--- a/bin/systrace/systrace.c   Mon Aug 25 09:05:13 2003 +0000
+++ b/bin/systrace/systrace.c   Mon Aug 25 09:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: systrace.c,v 1.22 2003/08/02 14:31:10 provos Exp $     */
+/*     $NetBSD: systrace.c,v 1.23 2003/08/25 09:12:46 cb Exp $ */
 /*     $OpenBSD: systrace.c,v 1.32 2002/08/05 23:27:53 provos Exp $    */
 /*
  * Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -118,9 +118,6 @@
        p = output + strlen(output);
        size = outlen - strlen(output);
 
-       if (repl != NULL)
-               intercept_replace_init(repl);
-
        if (tls == NULL)
                return;
 
@@ -137,19 +134,21 @@
 
                if (repl != NULL && tl->trans_size)
                        intercept_replace_add(repl, tl->off,
-                           tl->trans_data, tl->trans_size);
+                           tl->trans_data, tl->trans_size,
+                           tl->trans_flags);
        }



Home | Main Index | Thread Index | Old Index