summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2020-12-07 18:28:09 +0000
committerbluhm <bluhm@openbsd.org>2020-12-07 18:28:09 +0000
commit27f0efdaecbcaf4b5b3427367c0681b2d7380927 (patch)
tree0fc176f4c1315a3bc63596815ec03281088d2d0e
parentInitialize handled (diff)
downloadwireguard-openbsd-27f0efdaecbcaf4b5b3427367c0681b2d7380927.tar.xz
wireguard-openbsd-27f0efdaecbcaf4b5b3427367c0681b2d7380927.zip
In btrace(8) handle snprintf(3) errors correctly. If snprintf
fails, buffer is unchanged; initialize it with empty string. snprintf may return negative value or the length that would have been written; check and calculate remaining size. snprintf writes size - 1 characters; pass buffer size as length. OK mpi@
-rw-r--r--usr.sbin/btrace/btrace.c48
-rw-r--r--usr.sbin/btrace/ksyms.c15
2 files changed, 44 insertions, 19 deletions
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index 7b77ceb1366..64acf9eaef6 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.25 2020/09/14 18:45:19 jasper Exp $ */
+/* $OpenBSD: btrace.c,v 1.26 2020/12/07 18:28:09 bluhm Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -635,18 +635,31 @@ const char *
builtin_stack(struct dt_evt *dtev, int kernel)
{
struct stacktrace *st = &dtev->dtev_kstack;
- static char buf[4096];
+ static char buf[4096], *bp;
size_t i;
- int n = 0;
+ int sz;
if (!kernel || st->st_count == 0)
return "";
+ buf[0] = '\0';
+ bp = buf;
+ sz = sizeof(buf);
for (i = 0; i < st->st_count; i++) {
- n += kelf_snprintsym(buf + n, sizeof(buf) - 1 - n,
- st->st_pc[i]);
+ int l;
+
+ l = kelf_snprintsym(bp, sz - 1, st->st_pc[i]);
+ if (l < 0)
+ break;
+ if (l >= sz - 1) {
+ bp += sz - 1;
+ sz = 1;
+ break;
+ }
+ bp += l;
+ sz -= l;
}
- snprintf(buf + n, sizeof(buf) - 1 - n, "\n");
+ snprintf(bp, sz, "\n");
return buf;
}
@@ -656,7 +669,7 @@ builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
{
static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
- snprintf(buf, sizeof(buf) - 1, "%lu",
+ snprintf(buf, sizeof(buf), "%lu",
dtev->dtev_sysargs[dat - B_AT_BI_ARG0]);
return buf;
@@ -879,6 +892,7 @@ ba2hash(struct bt_arg *ba, struct dt_evt *dtev)
char *hash;
int l, len;
+ buf[0] = '\0';
l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev));
if (l < 0 || (size_t)l > sizeof(buf)) {
warn("string too long %d > %lu", l, sizeof(buf));
@@ -948,6 +962,7 @@ ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev,
*pstep = step;
}
+ buf[0] = '\0';
l = snprintf(buf, sizeof(buf), "%lu", bucket);
if (l < 0 || (size_t)l > sizeof(buf)) {
warn("string too long %d > %lu", l, sizeof(buf));
@@ -1051,12 +1066,13 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
struct bt_var *bv;
const char *str;
+ buf[0] = '\0';
switch (ba->ba_type) {
case B_AT_STR:
str = (const char *)ba->ba_value;
break;
case B_AT_LONG:
- snprintf(buf, sizeof(buf) - 1, "%ld",(long)ba->ba_value);
+ snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value);
str = buf;
break;
case B_AT_BI_KSTACK:
@@ -1069,26 +1085,26 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
str = dtev->dtev_comm;
break;
case B_AT_BI_CPU:
- snprintf(buf, sizeof(buf) - 1, "%u", dtev->dtev_cpu);
+ snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu);
str = buf;
break;
case B_AT_BI_PID:
- snprintf(buf, sizeof(buf) - 1, "%d", dtev->dtev_pid);
+ snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid);
str = buf;
break;
case B_AT_BI_TID:
- snprintf(buf, sizeof(buf) - 1, "%d", dtev->dtev_tid);
+ snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid);
str = buf;
break;
case B_AT_BI_NSECS:
- snprintf(buf, sizeof(buf) - 1, "%llu", builtin_nsecs(dtev));
+ snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev));
str = buf;
break;
case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
str = builtin_arg(dtev, ba->ba_type);
break;
case B_AT_BI_RETVAL:
- snprintf(buf, sizeof(buf) - 1, "%ld", (long)dtev->dtev_sysretval[0]);
+ snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_sysretval[0]);
str = buf;
break;
case B_AT_MAP:
@@ -1100,7 +1116,7 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
str = ba2str(ba_read(ba), dtev);
break;
case B_AT_OP_ADD ... B_AT_OP_OR:
- snprintf(buf, sizeof(buf) - 1, "%ld", ba2long(ba, dtev));
+ snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev));
str = buf;
break;
case B_AT_MF_COUNT:
@@ -1269,10 +1285,10 @@ debug_rule_name(struct bt_rule *r)
assert(r->br_type == B_RT_PROBE);
if (r->br_probe->bp_rate) {
- snprintf(buf, sizeof(buf) - 1, "%s:%s:%u", bp->bp_prov,
+ snprintf(buf, sizeof(buf), "%s:%s:%u", bp->bp_prov,
bp->bp_unit, bp->bp_rate);
} else {
- snprintf(buf, sizeof(buf) - 1, "%s:%s:%s", bp->bp_prov,
+ snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov,
bp->bp_unit, bp->bp_name);
}
diff --git a/usr.sbin/btrace/ksyms.c b/usr.sbin/btrace/ksyms.c
index ed8977bcc09..b599f6696ec 100644
--- a/usr.sbin/btrace/ksyms.c
+++ b/usr.sbin/btrace/ksyms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ksyms.c,v 1.2 2020/08/13 11:35:21 mpi Exp $ */
+/* $OpenBSD: ksyms.c,v 1.3 2020/12/07 18:28:09 bluhm Exp $ */
/*
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
@@ -121,10 +121,19 @@ kelf_snprintsym(char *str, size_t size, unsigned long pc)
cnt = snprintf(str, size, "\n%s", name);
else
cnt = snprintf(str, size, "\n0x%llx", sym.st_value);
+ if (cnt < 0)
+ return cnt;
offset = pc - sym.st_value;
- if (offset != 0)
- cnt += snprintf(str + cnt, size - cnt, "+0x%llx", offset);
+ if (offset != 0) {
+ int l;
+
+ l = snprintf(str + cnt, size > (size_t)cnt ? size - cnt : 0,
+ "+0x%llx", offset);
+ if (l < 0)
+ return l;
+ cnt += l;
+ }
return cnt;