apply(1): Fix segmentation faults

2018-03-21 Thread Tobias Stoeckmann
Hi,

this patch merges FreeBSD bin/95079 into our apply(1) implementation.
As we do not have an sbuf implementation, I have reworked the code
to properly handle string operations. Turns out that this fixes an
out of boundary write as well and made the code much more readable.

While reviewing the code and merging the fix, I have encountered
and fixed another issue when the magic character ' ' is used. A NULL
pointer dereference could occur, like:

$ apply -a ' ' 2to3 test.py
Segmentation fault (core dumped)

This case as well as the ones fixed by FreeBSD are inserted into
our regression tests, for which I have unfortunately already
committed the directory. Oops.

Is it okay to commit at this time of release cycle? If not, I'm
gathering feedback and review anyway. Feel free to comment!


Tobias

Index: regress/usr.bin/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/src/regress/usr.bin/Makefile,v
retrieving revision 1.42
diff -u -p -u -p -r1.42 Makefile
--- regress/usr.bin/Makefile28 Jun 2017 15:09:41 -  1.42
+++ regress/usr.bin/Makefile21 Mar 2018 20:53:01 -
@@ -1,7 +1,7 @@
 #  $OpenBSD: Makefile,v 1.42 2017/06/28 15:09:41 anton Exp $
=20
-SUBDIR+=3D basename bc calendar colrm column cut dc diff diff3 dirname doas
-SUBDIR+=3D file fmt fold grep gzip
+SUBDIR+=3D apply basename bc calendar colrm column cut dc diff diff3 dirna=
me
+SUBDIR+=3D doas file fmt fold grep gzip
 SUBDIR+=3D jot lastcomm m4 mail mandoc openssl rev sdiff sed signify sort =
tsort
 SUBDIR+=3D ul wc xargs
=20
Index: regress/usr.bin/apply/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: regress/usr.bin/apply/Makefile
diff -N regress/usr.bin/apply/Makefile
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/usr.bin/apply/Makefile  21 Mar 2018 20:53:01 -
@@ -0,0 +1,55 @@
+# $OpenBSD$
+
+APPLY?=3D  apply
+CLEANFILES=3D  *.res
+
+REGRESS_TARGETS=3Dt1 t2 t3 t4 t5 t6
+
+# .in: input file
+# .out: desired output
+
+# t1: uses arguments multiple times (from FreeBSD bin/95079)
+# t2: overflows ARG_MAX (from FreeBSD bin/95079)
+# t3: debugs -0 call
+# t4: debugs -2 call
+# t5: uses magic character '&'
+# t6: uses magic character ' ' with command starting with a number
+
+t1:
+   @echo ${*}
+   @(${APPLY} "echo %1 %1 %1 %1" `cat ${*}.in` > ${*}.res)
+   @cmp -s ${*}.out ${.CURDIR}/${*}.res || \
+   (echo "XXX ${*} failed" && false)
+
+t2:
+   @echo ${*}
+   @ARG_MAX=3D`getconf ARG_MAX`;\
+   ARG_MAX_HALF=3D$$((ARG_MAX / 2)); \
+   ! ${APPLY} "echo %1 %1 %1" \
+   `jot $$ARG_MAX_HALF 1 1 | tr -d '\n'` > ${*}.res 2>&1
+
+t3:
+   @echo ${*}
+   @(${APPLY} -0 -d who 1 2 3 4 5 > ${*}.res)
+   @cmp -s ${*}.out ${.CURDIR}/${*}.res || \
+   (echo "XXX ${*} failed" && false)
+
+t4:
+   @echo ${*}
+   @(${APPLY} -2 -d cmp a1 b1 a2 b2 a3 b3 > ${*}.res)
+   @cmp -s ${*}.out ${.CURDIR}/${*}.res || \
+   (echo "XXX ${*} failed" && false)
+
+t5:
+   @echo ${*}
+   @(${APPLY} -a "&" "echo &2 &1" hello world > ${*}.res)
+   @cmp -s ${*}.out ${.CURDIR}/${*}.res || \
+   (echo "XXX ${*} failed" && false)
+
+t6:
+   @echo ${*}
+   @(${APPLY} -a " " -d "2to3  1" test.py > ${*}.res)
+   @cmp -s ${*}.out ${.CURDIR}/${*}.res || \
+   (echo "XXX ${*} failed" && false)
+
+.include 
Index: regress/usr.bin/apply/t1.in
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: regress/usr.bin/apply/t1.in
diff -N regress/usr.bin/apply/t1.in
--- /dev/null   1 Jan 1970 00:00:00 -
+++ regress/usr.bin/apply/t1.in 21 Mar 2018 20:53:01 -
@@ -0,0 +1 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234=
567890123456789012345678901234567890123456789012345678901234567890123456789=
012345678901234567890123456789012345678901234567890123456789012345678901234=
567890123456789012345678901234567890123456789012345678901234567890123456789=
012345678901234567890123456789012345678901234567890123456789012345678901234=
567890123456789012345678901234567890123456789012345678901234567890123456789=
012345678901234567890123456789012345678901234567890123456789012
Index: regress/usr.bin/apply/t1.out
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: regress/usr.bin/apply/t1.out
diff -N regress/usr.bin/apply/t1.out
--- /dev/null   1 

dhclient hw_addr savvy

2018-03-21 Thread sven falempin
With no TABS because i m an idiot

so use :%s/   /^->/g
îs CTRL+V right, and -> is TAB

Index: bpf.c
===
RCS file: /cvs/src/sbin/dhclient/bpf.c,v
retrieving revision 1.69
diff -u -p -r1.69 bpf.c
--- bpf.c   20 Sep 2017 18:28:14 -  1.69
+++ bpf.c   21 Mar 2018 17:39:09 -
@@ -115,18 +115,27 @@ struct bpf_insn dhcp_bpf_filter[] = {

/* Make sure it's a UDP packet. */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
-   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
+   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 10),

/* Make sure this isn't a fragment. */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
-   BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
+   BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 8, 0),

/* Get the IP header length. */
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),

/* Make sure it's to the right port. */
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
-   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),  /* patch */
+   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 5),  /* patch */
+
+   /* MAC zero will be replaced into Patch the server port etc*/
+   /* check bootp.hw.addr 2 bytes */
+   BPF_STMT(BPF_LD + BPF_H + BPF_IND, 50),
+BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x, 0, 3),
+
+/* check bootp.hw.addr 4 bytes */
+BPF_STMT(BPF_LD + BPF_W + BPF_IND, 52),
+BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x, 0, 1),

/* If we passed all the tests, ask for the whole packet. */
BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1),
@@ -142,13 +151,6 @@ int dhcp_bpf_filter_len = sizeof(dhcp_bp
  * 'ip and udp and src port bootps and dst port (bootps or bootpc)'
  */
 struct bpf_insn dhcp_bpf_wfilter[] = {
-   BPF_STMT(BPF_LD + BPF_B + BPF_IND, 14),
-   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (IPVERSION << 4) + 5, 0, 12),
-
-   /* Make sure this is an IP packet. */
-   BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
-   BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
-
/* Make sure it's a UDP packet. */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
@@ -178,11 +180,13 @@ struct bpf_insn dhcp_bpf_wfilter[] = {
 int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn);

 int
-configure_bpf_sock(int bfdesc)
+configure_bpf_sock(int bfdesc, uint8_t * hw_address)
 {
struct bpf_version   v;
struct bpf_program   p;
int  flag = 1, sz;
+   uint32_t bits;
+   uint16_t bits16;

/* Make sure the BPF version is in range. */
if (ioctl(bfdesc, BIOCVERSION, ) == -1)
@@ -213,11 +217,16 @@ configure_bpf_sock(int bfdesc)
p.bf_insns = dhcp_bpf_filter;

/* Patch the server port into the BPF program.
+* also patch MAC
 *
 * N.B.: changes to filter program may require changes to the
 * insn number(s) used below!
 */
dhcp_bpf_filter[8].k = LOCAL_PORT;
+   memcpy(, hw_address, sizeof(bits16));
+   dhcp_bpf_filter[10].k = ntohs(bits16);
+   memcpy(, hw_address + 2, sizeof(bits));
+   dhcp_bpf_filter[12].k = ntohl(bits);

if (ioctl(bfdesc, BIOCSETF, ) == -1)
fatal("BIOCSETF");
Index: dhclient.c
===
RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
retrieving revision 1.565
diff -u -p -r1.565 dhclient.c
--- dhclient.c  28 Feb 2018 22:16:56 -  1.565
+++ dhclient.c  21 Mar 2018 17:39:10 -
@@ -636,7 +636,7 @@ main(int argc, char *argv[])
/* Register the interface. */
ifi->ufdesc = get_udp_sock(ifi->rdomain);
ifi->bfdesc = get_bpf_sock(ifi->name);
-   ifi->rbuf_max = configure_bpf_sock(ifi->bfdesc);
+   ifi->rbuf_max = configure_bpf_sock(ifi->bfdesc,(uint8_t
*)&(ifi->hw_address));
ifi->rbuf = malloc(ifi->rbuf_max);
if (ifi->rbuf == NULL)
fatal("bpf input buffer");
Index: dhcpd.h
===
RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
retrieving revision 1.254
diff -u -p -r1.254 dhcpd.h
--- dhcpd.h 28 Feb 2018 22:16:56 -  1.254
+++ dhcpd.h 21 Mar 2018 17:39:10 -
@@ -190,7 +190,7 @@ void parse_warn(char *);
 /* bpf.c */
 int get_bpf_sock(char *);
 int get_udp_sock(int);
-int configure_bpf_sock(int);
+int configure_bpf_sock(int, uint8_t *);
 ssize_t send_packet(struct interface_info *, struct in_addr,
 struct in_addr, const char *);
 ssize_t receive_packet(struct interface_info *,
struct sockaddr_in *,
[1]-[iBase63]-[/usr/src/sbin/dhclient]

Tested ( i just go a lease inside a rdomain