From c5fb5a34ef9b9996fbc5d1fa3ab05779eacc6c03 Mon Sep 17 00:00:00 2001 From: krw Date: Sun, 10 Jul 2022 20:34:31 +0000 Subject: [PATCH] Add some anti-feline input protection by refusing to process input of excessive length. Make 'args' parameter to Xfuncs const char * and do the multiple argument parsing in Xswap() and Xflag() on a local copy. --- sbin/fdisk/cmd.c | 46 +++++++++++++++++++++++++++++----------------- sbin/fdisk/cmd.h | 32 ++++++++++++++++---------------- sbin/fdisk/misc.c | 12 +++++++++--- sbin/fdisk/user.c | 4 ++-- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c index 60589e04617..3ced91da012 100644 --- a/sbin/fdisk/cmd.c +++ b/sbin/fdisk/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.162 2022/07/10 17:46:03 krw Exp $ */ +/* $OpenBSD: cmd.c,v 1.163 2022/07/10 20:34:31 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -49,7 +49,7 @@ extern const unsigned char manpage[]; extern const int manpage_sz; int -Xreinit(char *args, struct mbr *mbr) +Xreinit(const char *args, struct mbr *mbr) { int dogpt; @@ -78,14 +78,20 @@ Xreinit(char *args, struct mbr *mbr) } int -Xswap(char *args, struct mbr *mbr) +Xswap(const char *args, struct mbr *mbr) { + char lbuf[LINEBUFSZ]; char *from, *to; int pf, pt; struct prt pp; struct gpt_partition gg; - to = args; + if (strlcpy(lbuf, args, sizeof(lbuf)) >= sizeof(lbuf)) { + printf("argument string too long\n"); + return CMD_CONT; + } + + to = lbuf; from = strsep(&to, WHITESPACE); pt = parsepn(to); @@ -223,7 +229,7 @@ edit(const int pn, struct mbr *mbr) } int -Xedit(char *args, struct mbr *mbr) +Xedit(const char *args, struct mbr *mbr) { struct gpt_partition oldgg; struct prt oldprt; @@ -298,7 +304,7 @@ setpid(const int pn, struct mbr *mbr) } int -Xsetpid(char *args, struct mbr *mbr) +Xsetpid(const char *args, struct mbr *mbr) { struct gpt_partition oldgg; struct prt oldprt; @@ -326,7 +332,7 @@ Xsetpid(char *args, struct mbr *mbr) } int -Xselect(char *args, struct mbr *mbr) +Xselect(const char *args, struct mbr *mbr) { static uint64_t lba_firstembr = 0; uint64_t lba_self; @@ -361,7 +367,7 @@ Xselect(char *args, struct mbr *mbr) } int -Xprint(char *args, struct mbr *mbr) +Xprint(const char *args, struct mbr *mbr) { if (gh.gh_sig == GPTSIGNATURE) GPT_print(args, VERBOSE); @@ -372,7 +378,7 @@ Xprint(char *args, struct mbr *mbr) } int -Xwrite(char *args, struct mbr *mbr) +Xwrite(const char *args, struct mbr *mbr) { int i, n; @@ -404,25 +410,25 @@ Xwrite(char *args, struct mbr *mbr) } int -Xquit(char *args, struct mbr *mbr) +Xquit(const char *args, struct mbr *mbr) { return CMD_QUIT; } int -Xabort(char *args, struct mbr *mbr) +Xabort(const char *args, struct mbr *mbr) { exit(0); } int -Xexit(char *args, struct mbr *mbr) +Xexit(const char *args, struct mbr *mbr) { return CMD_EXIT; } int -Xhelp(char *args, struct mbr *mbr) +Xhelp(const char *args, struct mbr *mbr) { USER_help(); @@ -430,7 +436,7 @@ Xhelp(char *args, struct mbr *mbr) } int -Xupdate(char *args, struct mbr *mbr) +Xupdate(const char *args, struct mbr *mbr) { memcpy(mbr->mbr_code, default_dmbr.dmbr_boot, sizeof(mbr->mbr_code)); mbr->mbr_signature = DOSMBR_SIGNATURE; @@ -439,14 +445,20 @@ Xupdate(char *args, struct mbr *mbr) } int -Xflag(char *args, struct mbr *mbr) +Xflag(const char *args, struct mbr *mbr) { + char lbuf[LINEBUFSZ]; const char *errstr; char *part, *flag; long long val = -1; int i, pn; - flag = args; + if (strlcpy(lbuf, args, sizeof(lbuf)) >= sizeof(lbuf)) { + printf("argument string too long\n"); + return CMD_CONT; + } + + flag = lbuf; part = strsep(&flag, WHITESPACE); pn = parsepn(part); @@ -490,7 +502,7 @@ Xflag(char *args, struct mbr *mbr) } int -Xmanual(char *args, struct mbr *mbr) +Xmanual(const char *args, struct mbr *mbr) { char *pager = "/usr/bin/less"; char *p; diff --git a/sbin/fdisk/cmd.h b/sbin/fdisk/cmd.h index aeda9578bff..1a6b9f98b18 100644 --- a/sbin/fdisk/cmd.h +++ b/sbin/fdisk/cmd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.h,v 1.26 2021/10/25 13:51:25 krw Exp $ */ +/* $OpenBSD: cmd.h,v 1.27 2022/07/10 20:34:31 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -22,18 +22,18 @@ #define CMD_CLEAN 0x0003 #define CMD_DIRTY 0x0004 -int Xreinit(char *, struct mbr *); -int Xdisk(char *, struct mbr *); -int Xmanual(char *, struct mbr *); -int Xedit(char *, struct mbr *); -int Xsetpid(char *, struct mbr *); -int Xselect(char *, struct mbr *); -int Xswap(char *, struct mbr *); -int Xprint(char *, struct mbr *); -int Xwrite(char *, struct mbr *); -int Xexit(char *, struct mbr *); -int Xquit(char *, struct mbr *); -int Xabort(char *, struct mbr *); -int Xhelp(char *, struct mbr *); -int Xflag(char *, struct mbr *); -int Xupdate(char *, struct mbr *); +int Xreinit(const char *, struct mbr *); +int Xdisk(const char *, struct mbr *); +int Xmanual(const char *, struct mbr *); +int Xedit(const char *, struct mbr *); +int Xsetpid(const char *, struct mbr *); +int Xselect(const char *, struct mbr *); +int Xswap(const char *, struct mbr *); +int Xprint(const char *, struct mbr *); +int Xwrite(const char *, struct mbr *); +int Xexit(const char *, struct mbr *); +int Xquit(const char *, struct mbr *); +int Xabort(const char *, struct mbr *); +int Xhelp(const char *, struct mbr *); +int Xflag(const char *, struct mbr *); +int Xupdate(const char *, struct mbr *); diff --git a/sbin/fdisk/misc.c b/sbin/fdisk/misc.c index 34019bfe9c8..72ce228e764 100644 --- a/sbin/fdisk/misc.c +++ b/sbin/fdisk/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.87 2022/04/20 15:49:56 krw Exp $ */ +/* $OpenBSD: misc.c,v 1.88 2022/07/10 20:34:31 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -67,6 +67,7 @@ string_from_line(char *buf, const size_t buflen, const int trim) static char *line; static size_t sz; ssize_t len; + size_t n; unsigned int i; len = getline(&line, &sz, stdin); @@ -76,7 +77,7 @@ string_from_line(char *buf, const size_t buflen, const int trim) switch (trim) { case UNTRIMMED: line[strcspn(line, "\n")] = '\0'; - strlcpy(buf, line, buflen); + n = strlcpy(buf, line, buflen); break; case TRIMMED: for (i = strlen(line); i > 0; i--) { @@ -84,9 +85,14 @@ string_from_line(char *buf, const size_t buflen, const int trim) break; line[i - 1] = '\0'; } - strlcpy(buf, line + strspn(line, WHITESPACE), buflen); + n = strlcpy(buf, line + strspn(line, WHITESPACE), buflen); break; } + + if (n >= buflen) { + printf("input too long\n"); + memset(buf, 0, buflen); + } } int diff --git a/sbin/fdisk/user.c b/sbin/fdisk/user.c index 69e2de49e34..777344336ae 100644 --- a/sbin/fdisk/user.c +++ b/sbin/fdisk/user.c @@ -1,4 +1,4 @@ -/* $OpenBSD: user.c,v 1.81 2022/07/10 17:46:03 krw Exp $ */ +/* $OpenBSD: user.c,v 1.82 2022/07/10 20:34:31 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -34,7 +34,7 @@ struct cmd { char *cmd_name; int cmd_gpt; - int (*cmd_fcn)(char *, struct mbr *); + int (*cmd_fcn)(const char *, struct mbr *); char *cmd_help; }; -- 2.20.1