The _KERNEL define is overloaded to mean two things, which results in frequent
errors. 1. It means we are compiling the kernel. 2. It means we are compiling
a userland program that looks at kernel data structures.

Just because we need data structures doesn't mean we want everything else in
the kernel. In particular, the kernel environment uses different headers to
declare common features like NULL and types, so a header that thinks it's in
the kernel will subinclude different headers, breaking userland.

Here's the start of a fix. A new define, _KERNEL_INTERFACE, is used to
indicate that we are specifically asking for data structures. It doesn't
export functions or macros that aren't used in userland.

I tweaked one header file, sys/file.h, to use this interface. This reduces the
amount of extraneous material exposed to userland, like
extern int maxfiles;    /* kernel limit on number of open files */
Userland cannot access the kernel variable maxfiles simply by declaring it
extern, so this is useless and can only cause conflict.

Next, I looked at netstat. Turns out netstat is defining _KERNEL in some
places it doesn't even need to, so I deleted them. Then I changed the one
place that did need _KERNEL to _KERNEL_INTERFACE before including file.h.


Index: sys/sys/file.h
===================================================================
RCS file: /cvs/src/sys/sys/file.h,v
retrieving revision 1.38
diff -u -p -r1.38 file.h
--- sys/sys/file.h      23 Aug 2016 23:28:02 -0000      1.38
+++ sys/sys/file.h      9 Sep 2016 13:50:09 -0000
@@ -57,6 +57,31 @@ struct       fileops {
        int     (*fo_close)(struct file *, struct proc *);
 };
 
+#define FIF_HASLOCK            0x01    /* descriptor holds advisory lock */
+#define FIF_LARVAL             0x02    /* not fully constructed, don't use */
+
+#define FILE_IS_USABLE(fp) \
+       (((fp)->f_iflags & FIF_LARVAL) == 0)
+
+#define FREF(fp)       do { (fp)->f_count++; } while (0)
+#define FRELE(fp,p)    (--(fp)->f_count == 0 ? fdrop(fp, p) : 0)
+
+#define FILE_SET_MATURE(fp,p) do {                             \
+       (fp)->f_iflags &= ~FIF_LARVAL;                          \
+       FRELE(fp, p);                                           \
+} while (0)
+
+int    fdrop(struct file *, struct proc *);
+
+LIST_HEAD(filelist, file);
+extern struct filelist filehead;       /* head of list of open files */
+extern int maxfiles;                   /* kernel limit on number of open files 
*/
+extern int numfiles;                   /* actual number of open files */
+extern struct fileops vnops;           /* vnode operations for files */
+
+#endif /* _KERNEL */
+
+#if defined(_KERNEL) || defined(_KERNEL_INTERFACE)
 /*
  * Kernel descriptor table.
  * One entry for each open kernel vnode and socket.
@@ -81,27 +106,4 @@ struct file {
        u_int64_t f_rbytes;     /* total bytes read */
        u_int64_t f_wbytes;     /* total bytes written */
 };
-
-#define FIF_HASLOCK            0x01    /* descriptor holds advisory lock */
-#define FIF_LARVAL             0x02    /* not fully constructed, don't use */
-
-#define FILE_IS_USABLE(fp) \
-       (((fp)->f_iflags & FIF_LARVAL) == 0)
-
-#define FREF(fp)       do { (fp)->f_count++; } while (0)
-#define FRELE(fp,p)    (--(fp)->f_count == 0 ? fdrop(fp, p) : 0)
-
-#define FILE_SET_MATURE(fp,p) do {                             \
-       (fp)->f_iflags &= ~FIF_LARVAL;                          \
-       FRELE(fp, p);                                           \
-} while (0)
-
-int    fdrop(struct file *, struct proc *);
-
-LIST_HEAD(filelist, file);
-extern struct filelist filehead;       /* head of list of open files */
-extern int maxfiles;                   /* kernel limit on number of open files 
*/
-extern int numfiles;                   /* actual number of open files */
-extern struct fileops vnops;           /* vnode operations for files */
-
-#endif /* _KERNEL */
+#endif
Index: usr.bin/netstat/inet.c
===================================================================
RCS file: /cvs/src/usr.bin/netstat/inet.c,v
retrieving revision 1.151
diff -u -p -r1.151 inet.c
--- usr.bin/netstat/inet.c      2 Sep 2016 09:39:32 -0000       1.151
+++ usr.bin/netstat/inet.c      9 Sep 2016 13:52:18 -0000
@@ -37,9 +37,9 @@
 #include <sys/domain.h>
 #include <sys/protosw.h>
 #include <sys/sysctl.h>
-#define _KERNEL
+#define _KERNEL_INTERFACE
 #include <sys/file.h>
-#undef _KERNEL
+#undef _KERNEL_INTERFACE
 
 #include <net/route.h>
 #include <netinet/in.h>
Index: usr.bin/netstat/route.c
===================================================================
RCS file: /cvs/src/usr.bin/netstat/route.c,v
retrieving revision 1.100
diff -u -p -r1.100 route.c
--- usr.bin/netstat/route.c     27 Aug 2016 04:13:43 -0000      1.100
+++ usr.bin/netstat/route.c     9 Sep 2016 13:51:56 -0000
@@ -38,10 +38,8 @@
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
-#define _KERNEL
 #include <net/route.h>
 #include <netinet/ip_ipsp.h>
-#undef _KERNEL
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
Index: usr.bin/netstat/unix.c
===================================================================
RCS file: /cvs/src/usr.bin/netstat/unix.c,v
retrieving revision 1.29
diff -u -p -r1.29 unix.c
--- usr.bin/netstat/unix.c      27 Aug 2016 04:07:42 -0000      1.29
+++ usr.bin/netstat/unix.c      9 Sep 2016 13:53:29 -0000
@@ -41,10 +41,10 @@
 #include <sys/time.h>
 #include <sys/un.h>
 #include <sys/unpcb.h>
-#define _KERNEL
 #include <sys/ucred.h>
+#define _KERNEL_INTERFACE
 #include <sys/file.h>
-#undef _KERNEL
+#undef _KERNEL_INTERFACE
 
 #include <netinet/in.h>
 

Reply via email to