From owner-freebsd-hackers Fri Jul 16 2:35:36 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from kozlik.carrier.kiev.ua (kozlik.carrier.kiev.ua [193.193.193.111]) by hub.freebsd.org (Postfix) with ESMTP id E745514BDE for ; Fri, 16 Jul 1999 02:35:29 -0700 (PDT) (envelope-from nx@nn.kiev.ua) Received: from nn.UUCP (uucp@localhost) by kozlik.carrier.kiev.ua (8.The.Best/UUCP_FOREVER) with UUCP id MAA29337 for freebsd-hackers@freebsd.org; Fri, 16 Jul 1999 12:30:15 +0300 (EEST) (envelope-from nx@nn.kiev.ua) Received: from nn.UUCP (uucp@localhost) by kozlik.carrier.kiev.ua (rmail mypid=29336 childpid=29337) with UUCP; Fri, 16 Jul 1999 09:30:15 +0000 GMT Received: by nn.kiev.ua (UUPC/@ v7.00, 29Jul97) id AA06197; Fri, 16 Jul 1999 12:24:47 +0300 (EDT) To: freebsd-hackers@freebsd.org X-Comment-To: Mike Smith References: <199907152358.QAA01894@dingo.cdrom.com> Message-ID: From: "Valentin Nechayev" Date: Fri, 16 Jul 1999 12:24:47 +0300 (EDT) X-Mailer: dMail [Demos Mail for DOS v2.06] Subject: Re: OpenBSD's strlcpy(3) and strlcat(3) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 42 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Mike Smith wrote: > pw = getpwuid(getuid()); > strlcpy(buf, pw->dir, sizeof(buf)); > strlcat(buf, "/.appname/", sizeof(buf)); > strlcat(buf, conffilename, sizeof(buf)); > if (strlen(buf) >= sizeof(buf)) > return(error); > fp = fopen(buf, "r"); > ... > > That works, as long as MAXPATHLEN is actually long enough. In this It is incorrect in two places. 1st, strlen(buf) always will be less than buffer size (it is told here yet). 2nd, if the last addition to buffer is zero-length, you cannot check the overflow using return value of last strlcat() (it was not in your code, but I have seen it in idea in your code;)) To check overflow, you can either 1) check result of _each_ strlcpy/strlcat function, 2) [this is hack, but beauty hack;))] create buffer of size {max_possible_length}+2 and test string length after all catenations; if it is more then {max_possible_length}, the overflow was there. > if (asprintf(&buf, "%s/.appname/%s", pw->dir, conffilename) == -1) > return(error); > fp = fopen(buf, "r"); > free(buf); > ... > > The latter has a few really clear advantages: > > - you can see what the string is meant to look like. > - it doesn't matter how long any of the components are. > - the constructed value is on the heap, so you can return it (just > imagine how much nicer ctime() would be if it did this). Yes, let you wrap around ctime() with asprintf() ;) -- NN To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message