Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171147599
D56616.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D56616.id.diff
View Options
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -454,6 +454,7 @@
void bp_flush(struct buf_pr *b);
void fill_table(struct _ipfw_insn *cmd, char *av, uint8_t opcode,
struct tidx *tstate);
+int ipfw_detect_u32_kbi(void);
/* tables.c */
struct _ipfw_obj_ctlv;
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -33,6 +33,7 @@
#include <jail.h>
#include <netdb.h>
#include <pwd.h>
+#include <osreldate.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
@@ -5829,6 +5830,107 @@
}
}
+/*
+ * Detect 32 bit ipfw KBI by presence of XGET v=1.
+ *
+ * 32-bit KBI was introduced in 1500034. Report 32-bit KBI for osreldate equal
+ * or greater than 1500034. For lower values, jailed status must be checked to
+ * make sure getosreldate() returned a real value as jail init can be
+ * instructed to override this value (see jail(8)). In case we're in a jail,
+ * use ipfw socket to detect 32-bit KBI using ophandler probes.
+ *
+ * Return:
+ * 2 - 32-bit opcode KBI detected despite of getosreldate() retval
+ * 1 - 32-bit opcode KBI detected
+ * 0 - 16-bit opcode KBI detected
+ * -1 - an error occurred
+ */
+
+int
+ipfw_detect_u32_kbi(void)
+{
+ ipfw_obj_lheader *hdr = NULL;
+ ipfw_sopt_info *info;
+ socklen_t len;
+ size_t need;
+ uint32_t i;
+ int s, opver, ret = -1;
+
+ if (getosreldate() >= 1500034)
+ return (1);
+
+ /* Make more checks for lower osreldate values */
+ s = 0;
+ need = sizeof(s);
+ sysctlbyname("security.jail.jailed", &s, &need, NULL, 0);
+
+ /* We're not in a jail, value from getosreldate() is real */
+ if (s == 0)
+ return (0);
+
+ /*
+ * We're in a jail, osreldate may be altered. Use ipfw socket to
+ * decide.
+ */
+ s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+ if (s < 0)
+ return (-1);
+
+ /*
+ * ipfw code @ RELENG_15 can register 61 sockopt handlers.
+ * Pre-allocate enough to evade realloc()
+ */
+ need = sizeof(ipfw_obj_lheader) + (64 * sizeof(ipfw_sopt_info));
+
+ opver = 0;
+ for (i = 4; i >= 0; i--) {
+ hdr = realloc(hdr, need);
+ memset(hdr, 0, need);
+ if (hdr == NULL)
+ break;
+
+ hdr->opheader.opcode = IP_FW_DUMP_SOPTCODES;
+ hdr->opheader.version = opver;
+ hdr->size = need;
+
+ /* Check DUMP_SOPTCODES v=1 existance */
+ len = need;
+ if (getsockopt(s, IPPROTO_IP, IP_FW3, hdr, &len) != 0) {
+ if (errno == ENOMEM) {
+ need = hdr->size;
+ continue;
+ }
+ /* Does not exist. 32-bit KBI? */
+ if (errno == EINVAL && opver == 0) {
+ opver = 1;
+ continue;
+ }
+ /* Report an error */
+ ret = -1;
+ break;
+ }
+ /* Fetched soptcodes successfully */
+ info = (ipfw_sopt_info *)(hdr + 1);
+ for (i = 0; i < hdr->count; i++) {
+ if (info[i].opcode != IP_FW_XGET)
+ continue;
+ if (info[i].version == 0) {
+ ret = 0;
+ break;
+ }
+ if (info[i].version == 1) {
+ ret = 2;
+ break;
+ }
+ }
+ break;
+ }
+
+ free(hdr);
+ close(s);
+ return (ret);
+}
+
static int
ipfw_get_tracked_ifaces(ipfw_obj_lheader **polh)
{
diff --git a/sbin/ipfw/main.c b/sbin/ipfw/main.c
--- a/sbin/ipfw/main.c
+++ b/sbin/ipfw/main.c
@@ -18,7 +18,6 @@
* Command line interface for IP firewall facility
*/
-#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
@@ -31,8 +30,6 @@
#include <unistd.h>
#include <libgen.h>
-#include <osreldate.h>
-
#include "ipfw2.h"
static void
@@ -673,6 +670,7 @@
int
main(int ac, char *av[])
{
+ int ret;
#if defined(_WIN32) && defined(TCC)
{
WSADATA wsaData;
@@ -697,17 +695,19 @@
* KBI-incompatibility detected, check for availability of ipfw/dnctl15
* binaries and run them instead
*/
- if (getosreldate() >= 1500000) {
+ ret = ipfw_detect_u32_kbi();
+ if (ret > 0) {
const char *releng15_progname;
- int ret;
if (g_co.prog == cmdline_prog_ipfw)
releng15_progname = "/sbin/ipfw15";
else
releng15_progname = "/sbin/dnctl15";
- printf("WARNING! KBI incompatibility for ipfw is detected,"
- " trying to run %s.\n", releng15_progname);
+ if (ret == 1)
+ printf("WARNING! KBI incompatibility for ipfw is"
+ " detected, trying to run %s.\n",
+ releng15_progname);
if ((ret = execv(releng15_progname, av)) < 0) {
printf("execv(%s) error: %s\n", releng15_progname,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 10, 12:29 AM (7 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38614889
Default Alt Text
D56616.id.diff (4 KB)
Attached To
Mode
D56616: Add ipfw 32-bit KBI detection via ophandler version
Attached
Detach File
Event Timeline
Log In to Comment