diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-03-08 16:31:29 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-03-08 16:31:29 +0000 |
commit | bb693858431cd9899acd538fd6f41f570340b660 (patch) | |
tree | 9288d2187f4547235d06ebd7902f28ff6113bbdc /sys/kern | |
parent | 32931f304a0112122036aa12b02a554e8e9bf687 (diff) | |
download | FreeBSD-src-bb693858431cd9899acd538fd6f41f570340b660.zip FreeBSD-src-bb693858431cd9899acd538fd6f41f570340b660.tar.gz |
Use sbuf routines to construct core dump filenames rather than custom
string buffer handling, making the code both easier to read and more
robust against string-handling bugs.
MFC after: 1 week
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sig.c | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 2f61001..5be17ea 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include <sys/posix4.h> #include <sys/pioctl.h> #include <sys/resourcevar.h> +#include <sys/sbuf.h> #include <sys/sleepqueue.h> #include <sys/smp.h> #include <sys/stat.h> @@ -2973,65 +2974,59 @@ SYSCTL_STRING(_kern, OID_AUTO, corefile, CTLFLAG_RW, corefilename, * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P". * This is controlled by the sysctl variable kern.corefile (see above). */ - static char * expand_name(name, uid, pid) const char *name; uid_t uid; pid_t pid; { - const char *format, *appendstr; + struct sbuf sb; + const char *format; char *temp; - char buf[11]; /* Buffer for pid/uid -- max 4B */ - size_t i, l, n; + size_t i; format = corefilename; temp = malloc(MAXPATHLEN, M_TEMP, M_NOWAIT | M_ZERO); if (temp == NULL) return (NULL); - for (i = 0, n = 0; n < MAXPATHLEN && format[i]; i++) { + (void)sbuf_new(&sb, temp, MAXPATHLEN, SBUF_FIXEDLEN); + for (i = 0; format[i]; i++) { switch (format[i]) { case '%': /* Format character */ i++; switch (format[i]) { case '%': - appendstr = "%"; + sbuf_putc(&sb, '%'); break; case 'N': /* process name */ - appendstr = name; + sbuf_printf(&sb, "%s", name); break; case 'P': /* process id */ - sprintf(buf, "%u", pid); - appendstr = buf; + sbuf_printf(&sb, "%u", pid); break; case 'U': /* user id */ - sprintf(buf, "%u", uid); - appendstr = buf; + sbuf_printf(&sb, "%u", uid); break; default: - appendstr = ""; log(LOG_ERR, - "Unknown format character %c in `%s'\n", - format[i], format); + "Unknown format character %c in " + "corename `%s'\n", format[i], format); } - l = strlen(appendstr); - if ((n + l) >= MAXPATHLEN) - goto toolong; - memcpy(temp + n, appendstr, l); - n += l; break; default: - temp[n++] = format[i]; + sbuf_putc(&sb, format[i]); } } - if (format[i] != '\0') - goto toolong; + if (sbuf_overflowed(&sb)) { + sbuf_delete(&sb); + log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too " + "long\n", (long)pid, name, (u_long)uid); + free(temp, M_TEMP); + return (NULL); + } + sbuf_finish(&sb); + sbuf_delete(&sb); return (temp); -toolong: - log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too long\n", - (long)pid, name, (u_long)uid); - free(temp, M_TEMP); - return (NULL); } /* |