From 8e644b001d5ccc90e4ab3eb9a19792125baf4011 Mon Sep 17 00:00:00 2001 From: purplerain Date: Wed, 21 Jun 2023 15:35:02 +0000 Subject: [PATCH] sync --- lib/libc/stdio/open_memstream.c | 3 +- lib/libc/stdio/open_wmemstream.c | 5 +- lib/libcrypto/Makefile | 3 +- lib/libcrypto/bn/arch/aarch64/bn_arch.h | 16 +++- lib/libcrypto/bn/bn_internal.h | 14 ++- lib/libcrypto/bn/bn_lib.c | 33 +------- lib/libcrypto/bn/bn_local.h | 4 +- lib/libcrypto/bn/bn_primitives.c | 65 ++++++++++++++ regress/lib/libcrypto/bn/bn_cmp.c | 26 +++++- regress/lib/libcrypto/bn/bn_mul_div.c | 82 +++++++++++++++++- regress/lib/libcrypto/bn/bn_unit.c | 17 +++- sbin/disklabel/disklabel.c | 4 +- sbin/disklabel/editor.c | 33 ++++---- sbin/disklabel/extern.h | 8 +- sys/dev/fdt/rkpinctrl.c | 6 +- usr.bin/ssh/mux.c | 29 +++++-- usr.bin/ssh/readconf.c | 10 ++- usr.bin/ssh/servconf.c | 10 ++- usr.bin/ssh/ssh-keyscan.c | 9 +- usr.bin/ssh/ssh.1 | 6 +- usr.bin/ssh/ssh.c | 6 +- usr.bin/ssh/sshkey.c | 7 +- usr.bin/ssh/sshkey.h | 4 +- usr.bin/tmux/popup.c | 4 +- usr.sbin/ospf6ctl/ospf6ctl.8 | 7 +- usr.sbin/ospf6ctl/ospf6ctl.c | 8 +- usr.sbin/ospf6ctl/parser.c | 3 +- usr.sbin/ospf6ctl/parser.h | 3 +- usr.sbin/ospf6d/control.c | 3 +- usr.sbin/ospf6d/database.c | 9 +- usr.sbin/ospf6d/kroute.c | 108 +++++++++++++++++++++--- usr.sbin/ospf6d/lsupdate.c | 15 ++-- usr.sbin/ospf6d/ospf6.h | 6 +- usr.sbin/ospf6d/ospf6d.c | 5 +- usr.sbin/ospf6d/ospf6d.h | 4 +- usr.sbin/ospf6d/ospfe.c | 57 +++++++------ usr.sbin/ospf6d/packet.c | 18 ++-- usr.sbin/ospfd/lsupdate.c | 4 +- usr.sbin/relayd/check_tcp.c | 36 ++++---- usr.sbin/relayd/relayd.h | 3 +- usr.sbin/relayd/util.c | 64 +++++++------- 41 files changed, 541 insertions(+), 216 deletions(-) create mode 100644 lib/libcrypto/bn/bn_primitives.c diff --git a/lib/libc/stdio/open_memstream.c b/lib/libc/stdio/open_memstream.c index 6ee5a5c27..7b063e374 100644 --- a/lib/libc/stdio/open_memstream.c +++ b/lib/libc/stdio/open_memstream.c @@ -1,4 +1,4 @@ -/* $OpenBSD: open_memstream.c,v 1.8 2019/05/02 08:30:10 yasuoka Exp $ */ +/* $OpenBSD: open_memstream.c,v 1.9 2023/06/21 13:11:49 claudio Exp $ */ /* * Copyright (c) 2011 Martin Pieuchot @@ -53,7 +53,6 @@ memstream_write(void *v, const char *b, int l) p = recallocarray(st->string, st->size, sz, 1); if (!p) return (-1); - bzero(p + st->size, sz - st->size); *st->pbuf = st->string = p; st->size = sz; } diff --git a/lib/libc/stdio/open_wmemstream.c b/lib/libc/stdio/open_wmemstream.c index aceef3515..01dd78276 100644 --- a/lib/libc/stdio/open_wmemstream.c +++ b/lib/libc/stdio/open_wmemstream.c @@ -1,4 +1,4 @@ -/* $OpenBSD: open_wmemstream.c,v 1.8 2015/09/12 16:23:14 guenther Exp $ */ +/* $OpenBSD: open_wmemstream.c,v 1.9 2023/06/21 13:11:49 claudio Exp $ */ /* * Copyright (c) 2011 Martin Pieuchot @@ -52,10 +52,9 @@ wmemstream_write(void *v, const char *b, int l) if (sz < end + 1) sz = end + 1; - p = reallocarray(st->string, sz, sizeof(wchar_t)); + p = recallocarray(st->string, st->size, sz, sizeof(wchar_t)); if (!p) return (-1); - bzero(p + st->size, (sz - st->size) * sizeof(wchar_t)); *st->pbuf = st->string = p; st->size = sz; } diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile index 89bd94d79..6fe129bcd 100644 --- a/lib/libcrypto/Makefile +++ b/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.130 2023/06/11 05:35:43 tb Exp $ +# $OpenBSD: Makefile,v 1.131 2023/06/21 07:41:55 jsing Exp $ LIB= crypto LIBREBUILD=y @@ -195,6 +195,7 @@ SRCS+= bn_mod_sqrt.c SRCS+= bn_mont.c SRCS+= bn_mul.c SRCS+= bn_prime.c +SRCS+= bn_primitives.c SRCS+= bn_rand.c SRCS+= bn_recp.c SRCS+= bn_shift.c diff --git a/lib/libcrypto/bn/arch/aarch64/bn_arch.h b/lib/libcrypto/bn/arch/aarch64/bn_arch.h index aa780e09e..66de3682d 100644 --- a/lib/libcrypto/bn/arch/aarch64/bn_arch.h +++ b/lib/libcrypto/bn/arch/aarch64/bn_arch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_arch.h,v 1.11 2023/06/17 15:40:46 jsing Exp $ */ +/* $OpenBSD: bn_arch.h,v 1.12 2023/06/21 07:56:43 jsing Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -24,6 +24,20 @@ #if defined(__GNUC__) +#define HAVE_BN_CLZW + +static inline int +bn_clzw(BN_ULONG w) +{ + BN_ULONG n; + + __asm__ ("clz %[n], %[w]" + : [n]"=r"(n) + : [w]"r"(w)); + + return n; +} + #define HAVE_BN_ADDW static inline void diff --git a/lib/libcrypto/bn/bn_internal.h b/lib/libcrypto/bn/bn_internal.h index 5f86e2133..b712b736f 100644 --- a/lib/libcrypto/bn/bn_internal.h +++ b/lib/libcrypto/bn/bn_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_internal.h,v 1.12 2023/06/12 16:17:24 jsing Exp $ */ +/* $OpenBSD: bn_internal.h,v 1.14 2023/06/21 07:48:41 jsing Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -22,6 +22,10 @@ #ifndef HEADER_BN_INTERNAL_H #define HEADER_BN_INTERNAL_H +int bn_word_clz(BN_ULONG w); + +int bn_bitsize(const BIGNUM *bn); + #ifndef HAVE_BN_CT_NE_ZERO static inline int bn_ct_ne_zero(BN_ULONG w) @@ -54,6 +58,14 @@ bn_ct_eq_zero_mask(BN_ULONG w) } #endif +#ifndef HAVE_BN_CLZW +static inline int +bn_clzw(BN_ULONG w) +{ + return bn_word_clz(w); +} +#endif + /* * Big number primitives are named as the operation followed by a suffix * that indicates the number of words that it operates on, where 'w' means diff --git a/lib/libcrypto/bn/bn_lib.c b/lib/libcrypto/bn/bn_lib.c index 389dd3ff3..bac0290ef 100644 --- a/lib/libcrypto/bn/bn_lib.c +++ b/lib/libcrypto/bn/bn_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_lib.c,v 1.86 2023/04/30 19:15:48 tb Exp $ */ +/* $OpenBSD: bn_lib.c,v 1.88 2023/06/21 07:48:41 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -159,41 +159,16 @@ BN_value_one(void) return &bn_value_one; } -#ifndef HAVE_BN_WORD_CLZ -int -bn_word_clz(BN_ULONG w) -{ - BN_ULONG bits, mask, shift; - - bits = shift = BN_BITS2; - mask = 0; - - while ((shift >>= 1) != 0) { - bits += (shift & mask) - (shift & ~mask); - mask = bn_ct_ne_zero_mask(w >> bits); - } - bits += 1 & mask; - - bits -= bn_ct_eq_zero(w); - - return BN_BITS2 - bits; -} -#endif - int BN_num_bits_word(BN_ULONG w) { - return BN_BITS2 - bn_word_clz(w); + return BN_BITS2 - bn_clzw(w); } int -BN_num_bits(const BIGNUM *a) +BN_num_bits(const BIGNUM *bn) { - int i = a->top - 1; - - if (BN_is_zero(a)) - return 0; - return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); + return bn_bitsize(bn); } void diff --git a/lib/libcrypto/bn/bn_local.h b/lib/libcrypto/bn/bn_local.h index 78b4157d1..c86e4d032 100644 --- a/lib/libcrypto/bn/bn_local.h +++ b/lib/libcrypto/bn/bn_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_local.h,v 1.22 2023/05/10 12:21:55 tb Exp $ */ +/* $OpenBSD: bn_local.h,v 1.23 2023/06/21 07:41:55 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -259,8 +259,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); -int bn_word_clz(BN_ULONG w); - void bn_correct_top(BIGNUM *a); int bn_expand(BIGNUM *a, int bits); int bn_wexpand(BIGNUM *a, int words); diff --git a/lib/libcrypto/bn/bn_primitives.c b/lib/libcrypto/bn/bn_primitives.c new file mode 100644 index 000000000..66427a904 --- /dev/null +++ b/lib/libcrypto/bn/bn_primitives.c @@ -0,0 +1,65 @@ +/* $OpenBSD: bn_primitives.c,v 1.2 2023/06/21 07:48:41 jsing Exp $ */ +/* + * Copyright (c) 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "bn_arch.h" +#include "bn_internal.h" +#include "bn_local.h" + +#ifndef HAVE_BN_CLZW +#ifndef HAVE_BN_WORD_CLZ +int +bn_word_clz(BN_ULONG w) +{ + BN_ULONG bits, mask, shift; + + bits = shift = BN_BITS2; + mask = 0; + + while ((shift >>= 1) != 0) { + bits += (shift & mask) - (shift & ~mask); + mask = bn_ct_ne_zero_mask(w >> bits); + } + bits += 1 & mask; + + bits -= bn_ct_eq_zero(w); + + return BN_BITS2 - bits; +} +#endif +#endif + +#ifndef HAVE_BN_BITSIZE +int +bn_bitsize(const BIGNUM *bn) +{ + BN_ULONG n = 0, x = 0; + BN_ULONG mask, w; + int i = 0; + + while (i < bn->top) { + w = bn->d[i]; + mask = bn_ct_ne_zero_mask(w); + n = ((BN_ULONG)i & mask) | (n & ~mask); + x = (w & mask) | (x & ~mask); + i++; + } + + return (n + 1) * BN_BITS2 - bn_clzw(x); +} +#endif diff --git a/regress/lib/libcrypto/bn/bn_cmp.c b/regress/lib/libcrypto/bn/bn_cmp.c index 2f5c7c02e..047fac3ba 100644 --- a/regress/lib/libcrypto/bn/bn_cmp.c +++ b/regress/lib/libcrypto/bn/bn_cmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_cmp.c,v 1.1 2022/11/30 02:51:05 jsing Exp $ */ +/* $OpenBSD: bn_cmp.c,v 1.2 2023/06/21 07:16:08 jsing Exp $ */ /* * Copyright (c) 2022 Joel Sing * @@ -75,6 +75,30 @@ struct bn_cmp_test bn_cmp_tests[] = { .cmp = -1, .ucmp = 1, }, + { + .a = "1ffffffffffffffff", + .b = "00000000000000001ffffffffffffffff", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "-1ffffffffffffffff", + .b = "-00000000000000001ffffffffffffffff", + .cmp = 0, + .ucmp = 0, + }, + { + .a = "1ffffffffffffffff", + .b = "-00000000000000001ffffffffffffffff", + .cmp = 1, + .ucmp = 0, + }, + { + .a = "-1ffffffffffffffff", + .b = "00000000000000001ffffffffffffffff", + .cmp = -1, + .ucmp = 0, + }, }; #define N_BN_CMP_TESTS \ diff --git a/regress/lib/libcrypto/bn/bn_mul_div.c b/regress/lib/libcrypto/bn/bn_mul_div.c index 810c7cde1..625d5e318 100644 --- a/regress/lib/libcrypto/bn/bn_mul_div.c +++ b/regress/lib/libcrypto/bn/bn_mul_div.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_mul_div.c,v 1.6 2023/04/11 05:53:53 jsing Exp $ */ +/* $OpenBSD: bn_mul_div.c,v 1.7 2023/06/21 07:18:10 jsing Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -405,6 +405,84 @@ benchmark_bn_mul_sqr(void) } } +static int +test_bn_sqr(void) +{ + BN_CTX *bn_ctx = NULL; + BIGNUM *a, *r; + int failed = 1; + + if ((bn_ctx = BN_CTX_new()) == NULL) + errx(1, "BN_CTX_new"); + + BN_CTX_start(bn_ctx); + + if ((a = BN_CTX_get(bn_ctx)) == NULL) + errx(1, "BN_new"); + if ((r = BN_CTX_get(bn_ctx)) == NULL) + errx(1, "BN_new"); + + /* Square of a new BN. */ + if (!BN_sqr(r, a, bn_ctx)) { + fprintf(stderr, "FAIL: BN_sqr() on new BN failed\n"); + goto failure; + } + if (!BN_is_zero(r)) { + fprintf(stderr, "FAIL: BN_sqr() on new BN is not zero\n"); + goto failure; + } + + /* Square of BN that is explicitly set to zero. */ + if (!BN_set_word(a, 0)) { + fprintf(stderr, "FAIL: BN_set_word(0) failed\n"); + goto failure; + } + if (!BN_sqr(r, a, bn_ctx)) { + fprintf(stderr, "FAIL: BN_sqr(0) failed\n"); + goto failure; + } + if (!BN_is_zero(r)) { + fprintf(stderr, "FAIL: BN_sqr(0) != 0\n"); + goto failure; + } + + /* Square of BN with value one. */ + if (!BN_set_word(a, 1)) { + fprintf(stderr, "FAIL: BN_set_word(1) failed\n"); + goto failure; + } + if (!BN_sqr(r, a, bn_ctx)) { + fprintf(stderr, "FAIL: BN_sqr(1) failed\n"); + goto failure; + } + if (BN_get_word(r) != 1) { + fprintf(stderr, "FAIL: BN_sqr(1) != 1\n"); + goto failure; + } + + /* Square of BN with value two. */ + if (!BN_set_word(a, 2)) { + fprintf(stderr, "FAIL: BN_set_word(2) failed\n"); + goto failure; + } + if (!BN_sqr(r, a, bn_ctx)) { + fprintf(stderr, "FAIL: BN_sqr(2) failed\n"); + goto failure; + } + if (BN_get_word(r) != 4) { + fprintf(stderr, "FAIL: BN_sqr(2) != 4\n"); + goto failure; + } + + failed = 0; + + failure: + BN_CTX_end(bn_ctx); + BN_CTX_free(bn_ctx); + + return failed; +} + int main(int argc, char **argv) { @@ -413,6 +491,8 @@ main(int argc, char **argv) if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) benchmark = 1; + failed |= test_bn_sqr(); + if (benchmark && !failed) benchmark_bn_mul_sqr(); diff --git a/regress/lib/libcrypto/bn/bn_unit.c b/regress/lib/libcrypto/bn/bn_unit.c index bc49192b8..3a88bfca6 100644 --- a/regress/lib/libcrypto/bn/bn_unit.c +++ b/regress/lib/libcrypto/bn/bn_unit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_unit.c,v 1.6 2023/06/20 06:46:07 tb Exp $ */ +/* $OpenBSD: bn_unit.c,v 1.7 2023/06/21 07:15:38 jsing Exp $ */ /* * Copyright (c) 2022 Theo Buehler @@ -80,7 +80,7 @@ test_bn_num_bits(void) errx(1, "BN_new"); if ((num_bits = BN_num_bits(bn)) != 0) { - warnx("BN_num_bits(0): want 0, got %d", num_bits); + warnx("BN_num_bits(0): got %d, want 0", num_bits); failed |= 1; } @@ -89,14 +89,23 @@ test_bn_num_bits(void) for (i = 0; i <= 5 * BN_BITS2; i++) { if ((num_bits = BN_num_bits(bn)) != i + 1) { - warnx("BN_num_bits(1 << %d): want %d, got %d", - i, i + 1, num_bits); + warnx("BN_num_bits(1 << %d): got %d, want %d", + i, num_bits, i + 1); failed |= 1; } if (!BN_lshift1(bn, bn)) errx(1, "BN_lshift1"); } + if (BN_hex2bn(&bn, "0000000000000000010000000000000000") != 34) + errx(1, "BN_hex2bn"); + + if ((num_bits = BN_num_bits(bn)) != 65) { + warnx("BN_num_bits(1 << 64) padded: got %d, want %d", + num_bits, 65); + failed |= 1; + } + BN_free(bn); return failed; diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index 031e91975..b520ac4c2 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disklabel.c,v 1.250 2023/06/19 13:45:19 krw Exp $ */ +/* $OpenBSD: disklabel.c,v 1.251 2023/06/21 12:50:09 krw Exp $ */ /* * Copyright (c) 1987, 1993 @@ -1005,7 +1005,7 @@ next: if (errors > 0) mpcopy(mountpoints, omountpoints); - mpfree(omountpoints); + mpfree(omountpoints, DISCARD); return (errors > 0); } diff --git a/sbin/disklabel/editor.c b/sbin/disklabel/editor.c index 183f7e6de..64c534c76 100644 --- a/sbin/disklabel/editor.c +++ b/sbin/disklabel/editor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: editor.c,v 1.410 2023/06/19 13:45:19 krw Exp $ */ +/* $OpenBSD: editor.c,v 1.411 2023/06/21 12:50:09 krw Exp $ */ /* * Copyright (c) 1997-2000 Todd C. Miller @@ -501,9 +501,9 @@ editor(int f) } } done: - mpfree(omountpoints); - mpfree(origmountpoints); - mpfree(tmpmountpoints); + mpfree(omountpoints, DISCARD); + mpfree(origmountpoints, DISCARD); + mpfree(tmpmountpoints, DISCARD); return (error); } @@ -556,10 +556,7 @@ again: if (index >= alloc_table_nitems) return 1; lp = &label; - for (i = 0; i < MAXPARTITIONS; i++) { - free(mountpoints[i]); - mountpoints[i] = NULL; - } + mpfree(mountpoints, KEEP); memcpy(lp, lp_org, sizeof(struct disklabel)); lp->d_npartitions = MAXPARTITIONS; lastalloc = alloc_table[index].sz; @@ -1541,17 +1538,22 @@ mpsave(const struct disklabel *lp) } void -mpfree(char **mp) +mpfree(char **mp, int action) { int part; if (mp == NULL) return; - for (part = 0; part < MAXPARTITIONS; part++) + for (part = 0; part < MAXPARTITIONS; part++) { free(mp[part]); + mp[part] = NULL; + } - free(mp); + if (action == DISCARD) { + free(mp); + mp = NULL; + } } int @@ -1784,13 +1786,10 @@ zero_partitions(struct disklabel *lp) { int i; - for (i = 0; i < MAXPARTITIONS; i++) { - memset(&lp->d_partitions[i], 0, sizeof(struct partition)); - free(mountpoints[i]); - mountpoints[i] = NULL; - } - + memset(lp->d_partitions, 0, sizeof(lp->d_partitions)); DL_SETPSIZE(&lp->d_partitions[RAW_PART], DL_GETDSIZE(lp)); + + mpfree(mountpoints, KEEP); } u_int64_t diff --git a/sbin/disklabel/extern.h b/sbin/disklabel/extern.h index 174ebc4a4..a6c7e3a14 100644 --- a/sbin/disklabel/extern.h +++ b/sbin/disklabel/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.35 2023/01/04 21:08:08 krw Exp $ */ +/* $OpenBSD: extern.h,v 1.36 2023/06/21 12:50:09 krw Exp $ */ /* * Copyright (c) 2003 Theo de Raadt @@ -19,6 +19,10 @@ #define MEG(x) ((x) * 1024LL * (1024 / DEV_BSIZE)) #define GIG(x) (MEG(x) * 1024LL) +/* 'actions' for mpfree(). */ +#define DISCARD 0 +#define KEEP 1 + u_short dkcksum(const struct disklabel *); char canonical_unit(const struct disklabel *, char); double scale(u_int64_t, char, const struct disklabel *); @@ -30,7 +34,7 @@ int editor(int); int editor_allocspace(struct disklabel *); void mpsave(const struct disklabel *); void mpcopy(char **, char **); -void mpfree(char **); +void mpfree(char **, int); void parse_autotable(char *); int writelabel(int, struct disklabel *); diff --git a/sys/dev/fdt/rkpinctrl.c b/sys/dev/fdt/rkpinctrl.c index 6c00073de..d9f499bf3 100644 --- a/sys/dev/fdt/rkpinctrl.c +++ b/sys/dev/fdt/rkpinctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkpinctrl.c,v 1.12 2023/06/19 13:37:22 kettenis Exp $ */ +/* $OpenBSD: rkpinctrl.c,v 1.13 2023/06/21 01:10:17 jsg Exp $ */ /* * Copyright (c) 2017, 2018 Mark Kettenis * @@ -550,8 +550,8 @@ rk3328_pinctrl(uint32_t phandle, void *cookie) bank = pins[i]; idx = pins[i + 1]; mux = pins[i + 2]; - pull = rk3288_pull(bank, idx, pins[i + 3]); - strength = rk3288_strength(bank, idx, pins[i + 3]); + pull = rk3328_pull(bank, idx, pins[i + 3]); + strength = rk3328_strength(bank, idx, pins[i + 3]); if (bank > 3 || idx > 32 || mux > 3) continue; diff --git a/usr.bin/ssh/mux.c b/usr.bin/ssh/mux.c index 7abb5aaef..9968bf926 100644 --- a/usr.bin/ssh/mux.c +++ b/usr.bin/ssh/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.96 2023/03/08 04:43:12 guenther Exp $ */ +/* $OpenBSD: mux.c,v 1.97 2023/06/20 23:59:33 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -947,19 +948,28 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, { Channel *nc; char *chost = NULL; - u_int cport, i, j; - int r, new_fd[2]; + u_int _cport, i, j; + int ok = 0, cport, r, new_fd[2]; struct mux_stdio_confirm_ctx *cctx; if ((r = sshbuf_skip_string(m)) != 0 || /* reserved */ (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 || - (r = sshbuf_get_u32(m, &cport)) != 0) { + (r = sshbuf_get_u32(m, &_cport)) != 0) { free(chost); error_f("malformed message"); return -1; } + if (_cport == (u_int)PORT_STREAMLOCAL) + cport = PORT_STREAMLOCAL; + else if (_cport <= INT_MAX) + cport = (int)_cport; + else { + free(chost); + error_f("invalid port 0x%x", _cport); + return -1; + } - debug2_f("channel %d: stdio fwd to %s:%u", c->self, chost, cport); + debug2_f("channel %d: stdio fwd to %s:%d", c->self, chost, cport); /* Gather fds from client */ for(i = 0; i < 2; i++) { @@ -992,8 +1002,13 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { - if (!ask_permission("Allow forward to %s:%u? ", - chost, cport)) { + if (cport == PORT_STREAMLOCAL) { + ok = ask_permission("Allow forward to path %s", chost); + } else { + ok = ask_permission("Allow forward to [%s]:%d? ", + chost, cport); + } + if (!ok) { debug2_f("stdio fwd refused by user"); reply_error(reply, MUX_S_PERMISSION_DENIED, rid, "Permission denied"); diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 7c1b1b1f4..de70683e5 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.376 2023/03/31 04:23:02 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.377 2023/06/21 05:10:26 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -931,7 +931,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, char **cpptr, ***cppptr, fwdarg[256]; u_int i, *uintptr, uvalue, max_entries = 0; int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; - int remotefwd, dynamicfwd; + int remotefwd, dynamicfwd, ca_only = 0; LogLevel *log_level_ptr; SyslogFacility *log_facility_ptr; long long val64; @@ -1427,6 +1427,7 @@ parse_int: case oHostKeyAlgorithms: charptr = &options->hostkeyalgorithms; + ca_only = 0; parse_pubkey_algos: arg = argv_next(&ac, &av); if (!arg || *arg == '\0') { @@ -1436,7 +1437,7 @@ parse_pubkey_algos: } if (*arg != '-' && !sshkey_names_valid2(*arg == '+' || *arg == '^' ? - arg + 1 : arg, 1)) { + arg + 1 : arg, 1, ca_only)) { error("%s line %d: Bad key types '%s'.", filename, linenum, arg ? arg : ""); goto out; @@ -1447,6 +1448,7 @@ parse_pubkey_algos: case oCASignatureAlgorithms: charptr = &options->ca_sign_algorithms; + ca_only = 1; goto parse_pubkey_algos; case oLogLevel: @@ -2103,10 +2105,12 @@ parse_pubkey_algos: case oHostbasedAcceptedAlgorithms: charptr = &options->hostbased_accepted_algos; + ca_only = 0; goto parse_pubkey_algos; case oPubkeyAcceptedAlgorithms: charptr = &options->pubkey_accepted_algos; + ca_only = 0; goto parse_pubkey_algos; case oAddKeysToAgent: diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 862b02068..1cf331629 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.394 2023/06/05 13:24:36 millert Exp $ */ +/* $OpenBSD: servconf.c,v 1.395 2023/06/21 05:10:26 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1282,6 +1282,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, { char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; + int ca_only = 0; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; ServerOpCodes opcode; @@ -1517,6 +1518,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, case sHostbasedAcceptedAlgorithms: charptr = &options->hostbased_accepted_algos; + ca_only = 0; parse_pubkey_algos: arg = argv_next(&ac, &av); if (!arg || *arg == '\0') @@ -1524,7 +1526,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, filename, linenum); if (*arg != '-' && !sshkey_names_valid2(*arg == '+' || *arg == '^' ? - arg + 1 : arg, 1)) + arg + 1 : arg, 1, ca_only)) fatal("%s line %d: Bad key types '%s'.", filename, linenum, arg ? arg : ""); if (*activep && *charptr == NULL) @@ -1533,18 +1535,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, case sHostKeyAlgorithms: charptr = &options->hostkeyalgorithms; + ca_only = 0; goto parse_pubkey_algos; case sCASignatureAlgorithms: charptr = &options->ca_sign_algorithms; + ca_only = 1; goto parse_pubkey_algos; case sPubkeyAuthentication: intptr = &options->pubkey_authentication; + ca_only = 0; goto parse_flag; case sPubkeyAcceptedAlgorithms: charptr = &options->pubkey_accepted_algos; + ca_only = 0; goto parse_pubkey_algos; case sPubkeyAuthOptions: diff --git a/usr.bin/ssh/ssh-keyscan.c b/usr.bin/ssh/ssh-keyscan.c index 159023dc2..6a43d75fe 100644 --- a/usr.bin/ssh/ssh-keyscan.c +++ b/usr.bin/ssh/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.152 2023/03/31 04:21:56 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.153 2023/06/21 05:06:04 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -18,6 +18,7 @@ #endif #include +#include #include #include #include @@ -125,10 +126,10 @@ fdlim_get(int hard) if (getrlimit(RLIMIT_NOFILE, &rlfd) == -1) return (-1); - if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY) + if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY || + (hard ? rlfd.rlim_max : rlfd.rlim_cur) > INT_MAX) return sysconf(_SC_OPEN_MAX); - else - return hard ? rlfd.rlim_max : rlfd.rlim_cur; + return hard ? rlfd.rlim_max : rlfd.rlim_cur; } static int diff --git a/usr.bin/ssh/ssh.1 b/usr.bin/ssh/ssh.1 index a3d1ba163..3d89c7d7f 100644 --- a/usr.bin/ssh/ssh.1 +++ b/usr.bin/ssh/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.433 2022/11/28 01:37:36 djm Exp $ -.Dd $Mdocdate: November 28 2022 $ +.\" $OpenBSD: ssh.1,v 1.434 2023/06/21 05:08:32 djm Exp $ +.Dd $Mdocdate: June 21 2023 $ .Dt SSH 1 .Os .Sh NAME @@ -614,6 +614,8 @@ flag), (key exchange algorithms), .Ar key (key types), +.Ar key-ca-sign +(valid CA signature algorithms for certificates), .Ar key-cert (certificate key types), .Ar key-plain diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index d31b1a195..5d828f1cd 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.588 2023/04/26 01:36:03 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.589 2023/06/21 05:08:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -767,8 +767,10 @@ main(int ac, char **av) cp = sshkey_alg_list(1, 0, 0, '\n'); else if (strcmp(optarg, "key-plain") == 0) cp = sshkey_alg_list(0, 1, 0, '\n'); + else if (strcmp(optarg, "key-ca-sign") == 0 || + strcasecmp(optarg, "CASignatureAlgorithms") == 0) + cp = sshkey_alg_list(0, 1, 1, '\n'); else if (strcmp(optarg, "key-sig") == 0 || - strcasecmp(optarg, "CASignatureAlgorithms") == 0 || strcasecmp(optarg, "PubkeyAcceptedKeyTypes") == 0 || /* deprecated name */ strcasecmp(optarg, "PubkeyAcceptedAlgorithms") == 0 || strcasecmp(optarg, "HostKeyAlgorithms") == 0 || diff --git a/usr.bin/ssh/sshkey.c b/usr.bin/ssh/sshkey.c index eac9c866e..3b07c92de 100644 --- a/usr.bin/ssh/sshkey.c +++ b/usr.bin/ssh/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.135 2023/03/31 03:22:49 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.136 2023/06/21 05:10:26 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -319,7 +319,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) } int -sshkey_names_valid2(const char *names, int allow_wildcard) +sshkey_names_valid2(const char *names, int allow_wildcard, int plain_only) { char *s, *cp, *p; const struct sshkey_impl *impl; @@ -352,6 +352,9 @@ sshkey_names_valid2(const char *names, int allow_wildcard) } free(s); return 0; + } else if (plain_only && sshkey_type_is_cert(type)) { + free(s); + return 0; } } free(s); diff --git a/usr.bin/ssh/sshkey.h b/usr.bin/ssh/sshkey.h index e90a1eec8..2be16d196 100644 --- a/usr.bin/ssh/sshkey.h +++ b/usr.bin/ssh/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.61 2022/10/28 00:44:44 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.62 2023/06/21 05:10:26 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -258,7 +258,7 @@ int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_private(const EC_KEY *); const char *sshkey_ssh_name(const struct sshkey *); const char *sshkey_ssh_name_plain(const struct sshkey *); -int sshkey_names_valid2(const char *, int); +int sshkey_names_valid2(const char *, int, int); char *sshkey_alg_list(int, int, int, char); int sshkey_from_blob(const u_char *, size_t, struct sshkey **); diff --git a/usr.bin/tmux/popup.c b/usr.bin/tmux/popup.c index cafbc168c..b172f4026 100644 --- a/usr.bin/tmux/popup.c +++ b/usr.bin/tmux/popup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: popup.c,v 1.49 2023/06/08 11:17:28 nicm Exp $ */ +/* $OpenBSD: popup.c,v 1.50 2023/06/21 06:28:18 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -788,6 +788,8 @@ popup_editor(struct client *c, const char *buf, size_t len, if (fd == -1) return (-1); f = fdopen(fd, "w"); + if (f == NULL) + return (-1); if (fwrite(buf, len, 1, f) != 1) { fclose(f); return (-1); diff --git a/usr.sbin/ospf6ctl/ospf6ctl.8 b/usr.sbin/ospf6ctl/ospf6ctl.8 index 5cf5e52d7..f07408f19 100644 --- a/usr.sbin/ospf6ctl/ospf6ctl.8 +++ b/usr.sbin/ospf6ctl/ospf6ctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ospf6ctl.8,v 1.13 2023/03/02 17:09:53 jmc Exp $ +.\" $OpenBSD: ospf6ctl.8,v 1.14 2023/06/21 09:47:03 sthen Exp $ .\" .\" Copyright (c) 2004, 2005, 2007 Esben Norby .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 2 2023 $ +.Dd $Mdocdate: June 21 2023 $ .Dt OSPF6CTL 8 .Os .Sh NAME @@ -58,6 +58,9 @@ Remove the learned routes from the FIB. Decoupling the FIB from an OSPF router may create routing loops and could cause major routing issues in the complete OSPF cloud. Only routers with just one link to the OSPF cloud can safely decouple the FIB. +.It Cm fib reload +Refetches and relearns the routes in the Forwarding Information Base +a.k.a. the kernel routing table. .It Cm log brief Disable verbose debug logging. .It Cm log verbose diff --git a/usr.sbin/ospf6ctl/ospf6ctl.c b/usr.sbin/ospf6ctl/ospf6ctl.c index af034dcb9..488ac927e 100644 --- a/usr.sbin/ospf6ctl/ospf6ctl.c +++ b/usr.sbin/ospf6ctl/ospf6ctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6ctl.c,v 1.53 2022/12/27 12:11:39 claudio Exp $ */ +/* $OpenBSD: ospf6ctl.c,v 1.54 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -225,6 +225,11 @@ main(int argc, char *argv[]) printf("decouple request sent.\n"); done = 1; break; + case FIB_RELOAD: + imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0); + printf("reload request sent.\n"); + done = 1; + break; case LOG_VERBOSE: verbose = 1; /* FALLTHROUGH */ @@ -304,6 +309,7 @@ main(int argc, char *argv[]) case FIB: case FIB_COUPLE: case FIB_DECOUPLE: + case FIB_RELOAD: case LOG_VERBOSE: case LOG_BRIEF: case RELOAD: diff --git a/usr.sbin/ospf6ctl/parser.c b/usr.sbin/ospf6ctl/parser.c index a23bd44d6..5f91a6c5e 100644 --- a/usr.sbin/ospf6ctl/parser.c +++ b/usr.sbin/ospf6ctl/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.14 2019/05/26 09:27:09 remi Exp $ */ +/* $OpenBSD: parser.c,v 1.15 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -73,6 +73,7 @@ static const struct token t_main[] = { static const struct token t_fib[] = { { KEYWORD, "couple", FIB_COUPLE, NULL}, { KEYWORD, "decouple", FIB_DECOUPLE, NULL}, + { KEYWORD, "reload", FIB_RELOAD, NULL}, { ENDTOKEN, "", NONE, NULL} }; diff --git a/usr.sbin/ospf6ctl/parser.h b/usr.sbin/ospf6ctl/parser.h index b5bf97141..7fc50f8c7 100644 --- a/usr.sbin/ospf6ctl/parser.h +++ b/usr.sbin/ospf6ctl/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.9 2019/05/26 09:27:09 remi Exp $ */ +/* $OpenBSD: parser.h,v 1.10 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -29,6 +29,7 @@ enum actions { FIB, FIB_COUPLE, FIB_DECOUPLE, + FIB_RELOAD, LOG_VERBOSE, LOG_BRIEF, SHOW, diff --git a/usr.sbin/ospf6d/control.c b/usr.sbin/ospf6d/control.c index 2bb656c1d..c83a8a51f 100644 --- a/usr.sbin/ospf6d/control.c +++ b/usr.sbin/ospf6d/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.31 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: control.c,v 1.32 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -279,6 +279,7 @@ control_dispatch_imsg(int fd, short event, void *bula) case IMSG_CTL_FIB_DECOUPLE: ospfe_fib_update(imsg.hdr.type); /* FALLTHROUGH */ + case IMSG_CTL_FIB_RELOAD: case IMSG_CTL_RELOAD: c->iev.ibuf.pid = imsg.hdr.pid; ospfe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0); diff --git a/usr.sbin/ospf6d/database.c b/usr.sbin/ospf6d/database.c index 9c025b0fe..6bffb436b 100644 --- a/usr.sbin/ospf6d/database.c +++ b/usr.sbin/ospf6d/database.c @@ -1,4 +1,4 @@ -/* $OpenBSD: database.c,v 1.22 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: database.c,v 1.23 2023/06/21 07:45:47 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -51,7 +51,7 @@ send_db_description(struct nbr *nbr) goto fail; /* reserve space for database description header */ - if (ibuf_reserve(buf, sizeof(dd_hdr)) == NULL) + if (ibuf_add_zero(buf, sizeof(dd_hdr)) == -1) goto fail; switch (nbr->state) { @@ -134,8 +134,9 @@ send_db_description(struct nbr *nbr) dd_hdr.bits = bits; dd_hdr.dd_seq_num = htonl(nbr->dd_seq_num); - memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(dd_hdr)), - &dd_hdr, sizeof(dd_hdr)); + if (ibuf_set(buf, sizeof(struct ospf_hdr), &dd_hdr, + sizeof(dd_hdr)) == -1) + goto fail; /* calculate checksum */ if (upd_ospf_hdr(buf, nbr->iface)) diff --git a/usr.sbin/ospf6d/kroute.c b/usr.sbin/ospf6d/kroute.c index a7d2491a9..28ca7fac8 100644 --- a/usr.sbin/ospf6d/kroute.c +++ b/usr.sbin/ospf6d/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.67 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: kroute.c,v 1.68 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -45,16 +45,23 @@ struct { u_int32_t rtseq; pid_t pid; int fib_sync; + int fib_serial; u_int8_t fib_prio; int fd; struct event ev; + struct event reload; u_int rdomain; +#define KR_RELOAD_IDLE 0 +#define KR_RELOAD_FETCH 1 +#define KR_RELOAD_HOLD 2 + int reload_state; } kr_state; struct kroute_node { RB_ENTRY(kroute_node) entry; struct kroute_node *next; struct kroute r; + int serial; }; void kr_redist_remove(struct kroute_node *, struct kroute_node *); @@ -90,7 +97,10 @@ void if_announce(void *); int send_rtmsg(int, int, struct kroute *); int dispatch_rtmsg(void); int fetchtable(void); -int rtmsg_process(char *, size_t); +int refetchtable(void); +int rtmsg_process(char *, size_t); +void kr_fib_reload_timer(int, short, void *); +void kr_fib_reload_arm_timer(int); RB_HEAD(kroute_tree, kroute_node) krt; RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare) @@ -165,6 +175,9 @@ kr_init(int fs, u_int rdomain, int redis_label_or_prefix, u_int8_t fib_prio) kr_dispatch_msg, NULL); event_add(&kr_state.ev, NULL); + kr_state.reload_state = KR_RELOAD_IDLE; + evtimer_set(&kr_state.reload, kr_fib_reload_timer, NULL); + return (0); } @@ -373,6 +386,64 @@ kr_fib_decouple(void) log_info("kernel routing table decoupled"); } +void +kr_fib_reload_timer(int fd, short event, void *bula) +{ + if (kr_state.reload_state == KR_RELOAD_FETCH) { + kr_fib_reload(); + kr_state.reload_state = KR_RELOAD_HOLD; + kr_fib_reload_arm_timer(KR_RELOAD_HOLD_TIMER); + } else { + kr_state.reload_state = KR_RELOAD_IDLE; + } +} + +void +kr_fib_reload_arm_timer(int delay) +{ + struct timeval tv; + + timerclear(&tv); + tv.tv_sec = delay / 1000; + tv.tv_usec = (delay % 1000) * 1000; + + if (evtimer_add(&kr_state.reload, &tv) == -1) + fatal("add_reload_timer"); +} + +void +kr_fib_reload(void) +{ + struct kroute_node *krn, *kr, *kn; + + log_info("reloading interface list and routing table"); + + kr_state.fib_serial++; + + if (fetchifs(0) != 0 || fetchtable() != 0) + return; + + for (kr = RB_MIN(kroute_tree, &krt); kr != NULL; kr = krn) { + krn = RB_NEXT(kroute_tree, &krt, kr); + + do { + kn = kr->next; + + if (kr->serial != kr_state.fib_serial) { + + if (kr->r.priority == kr_state.fib_prio) { + kr->serial = kr_state.fib_serial; + if (send_rtmsg(kr_state.fd, + RTM_ADD, &kr->r) != 0) + break; + } else + kroute_remove(kr); + } + + } while ((kr = kn) != NULL); + } +} + void kr_fib_update_prio(u_int8_t fib_prio) { @@ -664,6 +735,8 @@ kroute_insert(struct kroute_node *kr) { struct kroute_node *krm, *krh; + kr->serial = kr_state.fib_serial; + if ((krh = RB_INSERT(kroute_tree, &krt, kr)) != NULL) { /* * Multipath route, add at end of list. @@ -1279,7 +1352,7 @@ rtmsg_process(char *buf, size_t len) int flags, mpath; unsigned int scope; u_short ifindex = 0; - int rv; + int rv, delay; size_t offset; char *next; @@ -1395,13 +1468,10 @@ rtmsg_process(char *buf, size_t len) if ((okr = kroute_find(&prefix, prefixlen, prio)) != NULL) { - /* just add new multipath routes */ - if (mpath && rtm->rtm_type == RTM_ADD) - goto add; - /* get the correct route */ kr = okr; - if (mpath && (kr = kroute_matchgw(okr, - &nexthop, scope)) == NULL) { + if ((mpath || prio == kr_state.fib_prio) && + (kr = kroute_matchgw(okr, &nexthop, scope)) == + NULL) { log_warnx("rtmsg_process: mpath route" " not found"); /* add routes we missed out earlier */ @@ -1432,7 +1502,8 @@ rtmsg_process(char *buf, size_t len) kr->r.flags |= F_DOWN; /* just readd, the RDE will care */ - kr_redistribute(okr); + kr->serial = kr_state.fib_serial; + kr_redistribute(kr); } else { add: if ((kr = calloc(1, @@ -1518,6 +1589,23 @@ add: case RTM_IFANNOUNCE: if_announce(next); break; + case RTM_DESYNC: + /* + * We lost some routing packets. Schedule a reload + * of the kernel route/interface information. + */ + if (kr_state.reload_state == KR_RELOAD_IDLE) { + delay = KR_RELOAD_TIMER; + log_info("desync; scheduling fib reload"); + } else { + delay = KR_RELOAD_HOLD_TIMER; + log_debug("desync during KR_RELOAD_%s", + kr_state.reload_state == + KR_RELOAD_FETCH ? "FETCH" : "HOLD"); + } + kr_state.reload_state = KR_RELOAD_FETCH; + kr_fib_reload_arm_timer(delay); + break; default: /* ignore for now */ break; diff --git a/usr.sbin/ospf6d/lsupdate.c b/usr.sbin/ospf6d/lsupdate.c index 0d934be76..3873771a7 100644 --- a/usr.sbin/ospf6d/lsupdate.c +++ b/usr.sbin/ospf6d/lsupdate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsupdate.c,v 1.22 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: lsupdate.c,v 1.23 2023/06/21 07:45:47 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -177,7 +177,7 @@ prepare_ls_update(struct iface *iface, int bigpkt) goto fail; /* reserve space for number of lsa field */ - if (ibuf_reserve(buf, sizeof(u_int32_t)) == NULL) + if (ibuf_add_zero(buf, sizeof(u_int32_t)) == -1) goto fail; return (buf); @@ -208,8 +208,10 @@ add_ls_update(struct ibuf *buf, struct iface *iface, void *data, u_int16_t len, age = ntohs(age); if ((age += older + iface->transmit_delay) >= MAX_AGE) age = MAX_AGE; - age = htons(age); - memcpy(ibuf_seek(buf, ageoff, sizeof(age)), &age, sizeof(age)); + if (ibuf_set_n16(buf, ageoff, age) == -1) { + log_warn("add_ls_update"); + return (0); + } return (1); } @@ -218,9 +220,8 @@ int send_ls_update(struct ibuf *buf, struct iface *iface, struct in6_addr addr, u_int32_t nlsa) { - nlsa = htonl(nlsa); - memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(nlsa)), - &nlsa, sizeof(nlsa)); + if (ibuf_set_n32(buf, sizeof(struct ospf_hdr), nlsa) == -1) + goto fail; /* calculate checksum */ if (upd_ospf_hdr(buf, iface)) goto fail; diff --git a/usr.sbin/ospf6d/ospf6.h b/usr.sbin/ospf6d/ospf6.h index 296fe1ff3..b75a64a31 100644 --- a/usr.sbin/ospf6d/ospf6.h +++ b/usr.sbin/ospf6d/ospf6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6.h,v 1.21 2013/03/25 14:29:35 markus Exp $ */ +/* $OpenBSD: ospf6.h,v 1.22 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2004, 2005, 2007 Esben Norby @@ -69,6 +69,10 @@ #define MIN_SPF_HOLDTIME 1 #define MAX_SPF_HOLDTIME 5 +/* msec */ +#define KR_RELOAD_TIMER 250 +#define KR_RELOAD_HOLD_TIMER 5000 + #define MIN_MD_ID 0 #define MAX_MD_ID 255 diff --git a/usr.sbin/ospf6d/ospf6d.c b/usr.sbin/ospf6d/ospf6d.c index a85f8771c..224d6cd5b 100644 --- a/usr.sbin/ospf6d/ospf6d.c +++ b/usr.sbin/ospf6d/ospf6d.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6d.c,v 1.53 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: ospf6d.c,v 1.54 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -372,6 +372,9 @@ main_dispatch_ospfe(int fd, short event, void *bula) case IMSG_CTL_FIB_DECOUPLE: kr_fib_decouple(); break; + case IMSG_CTL_FIB_RELOAD: + kr_fib_reload(); + break; case IMSG_CTL_KROUTE: case IMSG_CTL_KROUTE_ADDR: kr_show_route(&imsg); diff --git a/usr.sbin/ospf6d/ospf6d.h b/usr.sbin/ospf6d/ospf6d.h index e9233b648..a8f2a929e 100644 --- a/usr.sbin/ospf6d/ospf6d.h +++ b/usr.sbin/ospf6d/ospf6d.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6d.h,v 1.50 2021/01/19 09:46:51 claudio Exp $ */ +/* $OpenBSD: ospf6d.h,v 1.51 2023/06/21 09:47:03 sthen Exp $ */ /* * Copyright (c) 2004, 2007 Esben Norby @@ -93,6 +93,7 @@ enum imsg_type { IMSG_CTL_SHOW_SUM_AREA, IMSG_CTL_FIB_COUPLE, IMSG_CTL_FIB_DECOUPLE, + IMSG_CTL_FIB_RELOAD, IMSG_CTL_AREA, IMSG_CTL_IFACE, IMSG_CTL_KROUTE, @@ -546,6 +547,7 @@ int kr_delete(struct kroute *); void kr_shutdown(void); void kr_fib_couple(void); void kr_fib_decouple(void); +void kr_fib_reload(void); void kr_fib_update_prio(u_int8_t); void kr_dispatch_msg(int, short, void *); void kr_show_route(struct imsg *); diff --git a/usr.sbin/ospf6d/ospfe.c b/usr.sbin/ospf6d/ospfe.c index 0e8c79755..bb8eb975b 100644 --- a/usr.sbin/ospf6d/ospfe.c +++ b/usr.sbin/ospf6d/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.68 2023/03/08 04:43:14 guenther Exp $ */ +/* $OpenBSD: ospfe.c,v 1.69 2023/06/21 07:45:47 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -780,11 +780,11 @@ orig_rtr_lsa(struct area *area) fatal("orig_rtr_lsa"); /* reserve space for LSA header and LSA Router header */ - if (ibuf_reserve(buf, sizeof(lsa_hdr)) == NULL) - fatal("orig_rtr_lsa: ibuf_reserve failed"); + if (ibuf_add_zero(buf, sizeof(lsa_hdr)) == -1) + fatal("orig_rtr_lsa: ibuf_add_zero failed"); - if (ibuf_reserve(buf, sizeof(lsa_rtr)) == NULL) - fatal("orig_rtr_lsa: ibuf_reserve failed"); + if (ibuf_add_zero(buf, sizeof(lsa_rtr)) == -1) + fatal("orig_rtr_lsa: ibuf_add_zero failed"); /* links */ LIST_FOREACH(iface, &area->iface_list, entry) { @@ -944,8 +944,8 @@ orig_rtr_lsa(struct area *area) LSA_24_SETLO(lsa_rtr.opts, area_ospf_options(area)); LSA_24_SETHI(lsa_rtr.opts, flags); lsa_rtr.opts = htonl(lsa_rtr.opts); - memcpy(ibuf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_rtr)), - &lsa_rtr, sizeof(lsa_rtr)); + if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_rtr, sizeof(lsa_rtr)) == -1) + fatal("orig_rtr_lsa: ibuf_set failed"); /* LSA header */ lsa_hdr.age = htons(DEFAULT_AGE); @@ -956,11 +956,12 @@ orig_rtr_lsa(struct area *area) lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); lsa_hdr.len = htons(buf->wpos); lsa_hdr.ls_chksum = 0; /* updated later */ - memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); + if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1) + fatal("orig_rtr_lsa: ibuf_set failed"); - chksum = htons(iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET)); - memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), - &chksum, sizeof(chksum)); + chksum = iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET); + if (ibuf_set_n16(buf, LS_CKSUM_OFFSET, chksum) == -1) + fatal("orig_rtr_lsa: ibuf_set_n16 failed"); if (self) imsg_compose_event(iev_rde, IMSG_LS_UPD, self->peerid, 0, @@ -987,8 +988,8 @@ orig_net_lsa(struct iface *iface) fatal("orig_net_lsa"); /* reserve space for LSA header and options field */ - if (ibuf_reserve(buf, sizeof(lsa_hdr) + sizeof(lsa_net)) == NULL) - fatal("orig_net_lsa: ibuf_reserve failed"); + if (ibuf_add_zero(buf, sizeof(lsa_hdr) + sizeof(lsa_net)) == -1) + fatal("orig_net_lsa: ibuf_add_zero failed"); lsa_net.opts = 0; /* fully adjacent neighbors + self */ @@ -1019,15 +1020,16 @@ orig_net_lsa(struct iface *iface) lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); lsa_hdr.len = htons(buf->wpos); lsa_hdr.ls_chksum = 0; /* updated later */ - memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); + if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1) + fatal("orig_net_lsa: ibuf_set failed"); lsa_net.opts &= lsa_net.opts & htonl(LSA_24_MASK); - memcpy(ibuf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_net)), &lsa_net, - sizeof(lsa_net)); + if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_net, sizeof(lsa_net)) == -1) + fatal("orig_net_lsa: ibuf_set failed"); - chksum = htons(iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET)); - memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), - &chksum, sizeof(chksum)); + chksum = iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET); + if (ibuf_set_n16(buf, LS_CKSUM_OFFSET, chksum) == -1) + fatal("orig_net_lsa: ibuf_set_n16 failed"); imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0, -1, buf->buf, buf->wpos); @@ -1073,8 +1075,8 @@ orig_link_lsa(struct iface *iface) fatal("orig_link_lsa"); /* reserve space for LSA header and LSA link header */ - if (ibuf_reserve(buf, sizeof(lsa_hdr) + sizeof(lsa_link)) == NULL) - fatal("orig_link_lsa: ibuf_reserve failed"); + if (ibuf_add_zero(buf, sizeof(lsa_hdr) + sizeof(lsa_link)) == -1) + fatal("orig_link_lsa: ibuf_add_zero failed"); /* link-local address, and all prefixes configured on interface */ TAILQ_FOREACH(ia, &iface->ifa_list, entry) { @@ -1104,8 +1106,8 @@ orig_link_lsa(struct iface *iface) LSA_24_SETLO(lsa_link.opts, options); lsa_link.opts = htonl(lsa_link.opts); lsa_link.numprefix = htonl(num_prefix); - memcpy(ibuf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_link)), - &lsa_link, sizeof(lsa_link)); + if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_link, sizeof(lsa_link)) == -1) + fatal("orig_link_lsa: ibuf_set failed"); /* LSA header */ lsa_hdr.age = htons(DEFAULT_AGE); @@ -1116,11 +1118,12 @@ orig_link_lsa(struct iface *iface) lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); lsa_hdr.len = htons(buf->wpos); lsa_hdr.ls_chksum = 0; /* updated later */ - memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); + if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1) + fatal("orig_link_lsa: ibuf_set failed"); - chksum = htons(iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET)); - memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), - &chksum, sizeof(chksum)); + chksum = iso_cksum(buf->buf, buf->wpos, LS_CKSUM_OFFSET); + if (ibuf_set_n16(buf, LS_CKSUM_OFFSET, chksum) == -1) + fatal("orig_link_lsa: ibuf_set_n16 failed"); imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0, -1, buf->buf, buf->wpos); diff --git a/usr.sbin/ospf6d/packet.c b/usr.sbin/ospf6d/packet.c index eaac35c61..26a54ad4d 100644 --- a/usr.sbin/ospf6d/packet.c +++ b/usr.sbin/ospf6d/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.20 2021/01/19 16:02:06 claudio Exp $ */ +/* $OpenBSD: packet.c,v 1.21 2023/06/21 07:45:47 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -64,16 +64,16 @@ gen_ospf_hdr(struct ibuf *buf, struct iface *iface, u_int8_t type) int upd_ospf_hdr(struct ibuf *buf, struct iface *iface) { - struct ospf_hdr *ospf_hdr; - - if ((ospf_hdr = ibuf_seek(buf, 0, sizeof(*ospf_hdr))) == NULL) - fatalx("upd_ospf_hdr: buf_seek failed"); - /* update length */ - if (buf->wpos > USHRT_MAX) + if (ibuf_size(buf) > USHRT_MAX) fatalx("upd_ospf_hdr: resulting ospf packet too big"); - ospf_hdr->len = htons((u_int16_t)buf->wpos); - ospf_hdr->chksum = 0; /* calculated via IPV6_CHECKSUM */ + if (ibuf_set_n16(buf, offsetof(struct ospf_hdr, len), + ibuf_size(buf)) == -1) + fatalx("upd_ospf_hdr: ibuf_set_n16 failed"); + + /* checksum calculated via IPV6_CHECKSUM */ + if (ibuf_set_n16(buf, offsetof(struct ospf_hdr, chksum), 0) == -1) + fatalx("upd_ospf_hdr: ibuf_set_n16 failed"); return (0); } diff --git a/usr.sbin/ospfd/lsupdate.c b/usr.sbin/ospfd/lsupdate.c index 25c6b3ad3..27415eaec 100644 --- a/usr.sbin/ospfd/lsupdate.c +++ b/usr.sbin/ospfd/lsupdate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsupdate.c,v 1.52 2023/06/20 15:19:55 claudio Exp $ */ +/* $OpenBSD: lsupdate.c,v 1.53 2023/06/21 07:44:08 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -202,8 +202,6 @@ add_ls_update(struct ibuf *buf, struct iface *iface, void *data, u_int16_t len, return (1); } - - int send_ls_update(struct ibuf *buf, struct iface *iface, struct in_addr addr, u_int32_t nlsa) diff --git a/usr.sbin/relayd/check_tcp.c b/usr.sbin/relayd/check_tcp.c index 096020336..9bcb40ff9 100644 --- a/usr.sbin/relayd/check_tcp.c +++ b/usr.sbin/relayd/check_tcp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: check_tcp.c,v 1.59 2023/06/20 09:54:57 claudio Exp $ */ +/* $OpenBSD: check_tcp.c,v 1.60 2023/06/21 07:54:54 claudio Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard @@ -183,10 +183,6 @@ tcp_host_up(struct ctl_tcp_event *cte) return; } - if (cte->table->sendbuf != NULL && cte->table->sendbinbuf == NULL) { - cte->req = cte->table->sendbuf; - } else if (cte->table->sendbinbuf != NULL) - cte->req = cte->table->sendbinbuf->buf; if (cte->table->sendbuf != NULL || cte->table->sendbinbuf != NULL) { event_again(&cte->ev, cte->s, EV_TIMEOUT|EV_WRITE, tcp_send_req, &cte->tv_start, &cte->table->conf.timeout, cte); @@ -203,6 +199,7 @@ void tcp_send_req(int s, short event, void *arg) { struct ctl_tcp_event *cte = arg; + char *req; int bs; int len; @@ -214,14 +211,17 @@ tcp_send_req(int s, short event, void *arg) if (cte->table->sendbinbuf != NULL) { len = ibuf_size(cte->table->sendbinbuf); + req = ibuf_data(cte->table->sendbinbuf); log_debug("%s: table %s sending binary", __func__, cte->table->conf.name); print_hex(cte->table->sendbinbuf->buf, 0, len); - } else - len = strlen(cte->req); + } else { + len = strlen(cte->table->sendbuf); + req = cte->table->sendbuf; + } do { - bs = write(s, cte->req, len); + bs = write(s, req, len); if (bs == -1) { if (errno == EAGAIN || errno == EINTR) goto retry; @@ -230,7 +230,7 @@ tcp_send_req(int s, short event, void *arg) hce_notify_done(cte->host, HCE_TCP_WRITE_FAIL); return; } - cte->req += bs; + req += bs; len -= bs; } while (len > 0); @@ -302,20 +302,22 @@ check_send_expect(struct ctl_tcp_event *cte) u_char *b; if (cte->table->conf.check == CHECK_BINSEND_EXPECT) { + size_t exlen; + + exlen = strlen(cte->table->conf.exbuf) / 2; log_debug("%s: table %s expecting binary", __func__, cte->table->conf.name); - print_hex(cte->table->conf.exbinbuf, 0, - strlen(cte->table->conf.exbuf) / 2); + print_hex(cte->table->conf.exbinbuf, 0, exlen); - if (memcmp(cte->table->conf.exbinbuf, cte->buf->buf, - strlen(cte->table->conf.exbuf) / 2) == 0) { + if (ibuf_size(cte->buf) >= exlen && memcmp(ibuf_data(cte->buf), + cte->table->conf.exbinbuf, exlen) == 0) { cte->host->he = HCE_SEND_EXPECT_OK; cte->host->up = HOST_UP; return (0); - } else { + } else if (ibuf_size(cte->buf) >= exlen) { log_debug("%s: table %s received mismatching binary", __func__, cte->table->conf.name); - print_hex(cte->buf->buf, 0, ibuf_size(cte->buf)); + print_hex(ibuf_data(cte->buf), 0, ibuf_size(cte->buf)); } } else if (cte->table->conf.check == CHECK_SEND_EXPECT) { /* @@ -353,7 +355,7 @@ check_http_code(struct ctl_tcp_event *cte) if (ibuf_add_zero(cte->buf, 1) == -1) fatal("out of memory"); - head = cte->buf->buf; + head = ibuf_data(cte->buf); host = cte->host; host->he = HCE_HTTP_CODE_ERROR; host->code = 0; @@ -404,7 +406,7 @@ check_http_digest(struct ctl_tcp_event *cte) if (ibuf_add_zero(cte->buf, 1) == -1) fatal("out of memory"); - head = cte->buf->buf; + head = ibuf_data(cte->buf); host = cte->host; host->he = HCE_HTTP_DIGEST_ERROR; diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 35775d1b5..990cec350 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.269 2022/08/31 16:17:18 dv Exp $ */ +/* $OpenBSD: relayd.h,v 1.270 2023/06/21 07:54:54 claudio Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter @@ -176,7 +176,6 @@ struct ctl_icmp_event { struct ctl_tcp_event { int s; - char *req; struct ibuf *buf; struct host *host; struct table *table; diff --git a/usr.sbin/relayd/util.c b/usr.sbin/relayd/util.c index 8a06dc4a4..65d6660e4 100644 --- a/usr.sbin/relayd/util.c +++ b/usr.sbin/relayd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.3 2019/09/15 19:23:29 rob Exp $ */ +/* $OpenBSD: util.c,v 1.4 2023/06/21 07:49:24 claudio Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -289,44 +289,42 @@ getmonotime(struct timeval *tv) struct ibuf * string2binary(const char *string) { - unsigned long i, j, x; - unsigned char *binary = NULL; struct ibuf *ibuf = NULL; - char hex[3]; - int len; + unsigned char ch, r; + size_t i, len; - if (strlen(string) % 2 != 0) { - return NULL; - } + len = strlen(string); + if (len % 2 != 0) + goto fail; + if ((ibuf = ibuf_open(len / 2)) == NULL) + goto fail; - binary = calloc(strlen(string), sizeof(unsigned char)); - if (binary == NULL) { - return NULL; - } - - hex[2] = '\0'; - j = 0; - for (i = 0; i < strlen(string); i++) { - if (isxdigit(string[i]) == 0 || isxdigit(string[i+1]) == 0) { - free(binary); - return NULL; - } else { - hex[0] = string[i]; - hex[1] = string[i+1]; - x = strtoul(hex, NULL, 16); - binary[j++] = (unsigned char)x; - i++; + while (*string) { + r = 0; + for (i = 0; i < 2; i++) { + ch = string[i]; + if (isdigit(ch)) + ch -= '0'; + else if (islower(ch)) + ch -= ('a' - 10); + else if (isupper(ch)) + ch -= ('A' - 10); + else + goto fail; + if (ch > 0xf) + goto fail; + r = r << 4 | ch; } + if (ibuf_add_n8(ibuf, r) == -1) + goto fail; + string += 2; } - len = strlen(string) / 2; - if ((ibuf = ibuf_open(len)) == NULL || - ibuf_add(ibuf, binary, len) == -1) { - ibuf_free(ibuf); - free(binary); - return NULL; - } - free(binary); + return ibuf; + +fail: + ibuf_free(ibuf); + return NULL; } void