Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > strlcpy and strlcat

Reply
Thread Tools

strlcpy and strlcat

 
 
dj3vande@csclub.uwaterloo.ca.invalid
Guest
Posts: n/a
 
      12-10-2007
In article <(E-Mail Removed)>,
CBFalconer <(E-Mail Removed)> wrote:
>(E-Mail Removed) wrote:


>> If the dest argument to strlcat does not in fact point to a correctly
>> terminated string, the BSD implementation will stop looking for a '\0'
>> after maxlen bytes. This avoids walking through large amounts of
>> memory (only to read - it wouldn't be written in any case) when it's
>> given bad input.

>
>I would argue that my technique is better. It will normally cause
>an immediate fault during the call, which should leave traces as to
>the cause, and be repairable.


Only if it hits unreadable memory and causes a read trap before it
finds a zero byte. I'd expect it to find a zero byte and give
completely bogus results more often than it would cause a trap.

I don't think either is obviously better in general. If you're using
them to make it easier to write safe code (the original motivation for
adding them in OpenBSD, if I'm not mistaken) it makes sense to give
slightly wrong results for incorrect inputs in return for the added
safety, but if you're just treating them as string operations that do
what strncpy and strncat look like they should do, getting the
"expected" result from strlcat when the destination string is longer
than the maxlen argument is probably worth the cost of getting
completely wrong results or maybe a memory protection trap when the
destination string isn't properly terminated.


dave

 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      12-10-2007
http://www.velocityreviews.com/forums/(E-Mail Removed)lid wrote:
> CBFalconer <(E-Mail Removed)> wrote:
>> (E-Mail Removed)lid wrote:

>
>>> If the dest argument to strlcat does not in fact point to a
>>> correctly terminated string, the BSD implementation will stop
>>> looking for a '\0' after maxlen bytes. This avoids walking
>>> through large amounts of memory (only to read - it wouldn't be
>>> written in any case) when it's given bad input.

>>
>> I would argue that my technique is better. It will normally
>> cause an immediate fault during the call, which should leave
>> traces as to the cause, and be repairable.

>
> Only if it hits unreadable memory and causes a read trap before
> it finds a zero byte. I'd expect it to find a zero byte and give
> completely bogus results more often than it would cause a trap.


True. The 'read onward' has at least a chance of blowing on a bad
call. However, the 'stop after maxlen' just gives the 'destination
too small' response, and no sign of a basic error. The natural
reaction is to increase the destination size, and try again. Still
fails (maybe). At any rate, C programmers should be used to having
dire things happen when failing to pass strings to things expecting
strings.

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
 
 
 
Tor Rustad
Guest
Posts: n/a
 
      12-10-2007
(E-Mail Removed)lid wrote:
> In article <(E-Mail Removed)>,
> Tor Rustad <(E-Mail Removed)> wrote:
>> (E-Mail Removed)lid wrote:
>>
>> [...]
>>
>>> (Over 24 hours and only one response? I need to get my sigmonster set
>>> up on this account, then at least Richard H will read my posts.)

>> I have seen your request, the main reason for not checking this deeper,
>> has been primary that those strl* interfaces has IMO a design weakness,
>> which I eliminated in my own implementation.

>
> Out of curiousity, what is that design weakness, and how did you fix
> it?


Many will not check the return value for truncation. There are cases
where this is not a bug, but most of the cases it will be, and strl* may
hurt matters by hiding it.

In the (rare) cases where truncation is ok, I prefer

n = sprintf(dst, "%.*s", max, src);

or

n = snprintf(dst, max, "%s", src);

while my

m = strlcpy(dst, src, max);

will trap via assert on truncation. I also consider it a bug, to
silently reallocate the 'dst' buffer without having some max limit on
it. So recovery code, will get somewhat complex. The strl* functions are
not really designed for dynamic buffer management anyway, so why return
recovery info, if none are done?

As I see it, on truncation, either (1) there is a bug in the code, or
(2) we are under attack (e.g. DOS).

In case (1), I want this to be fixed during development, hence place an
assert() close to the problem. If the bug isn't fixed, I want the code
to enter fail safe mode.

How to handle (2), is rather hard.. to really address the issue, you
typically need to analyze the system/architecture at higher level. The
best thing one can do at low-level, is entering fail safe mode.

I also prefer that the return value of strl* functions, is the length of
the destination buffer after completion. In case dynamic memory handling
is of interest, I consider it better using a different set of functions.

Finally, the size parameter should have been placed in the middle (like
snprintf has). So, IMO a better API design would be

len_dst = my_strlcpy(dst, max_dst, src);
/* where len_dst < max_dst */


>> I would remove PARANOID, using assert() isn't paranoid.

>
> I'm used to using PARANOID to control consistency checks that can get
> expensive. (I try to remember to build with them turned on when I
> write them to make sure they're correct, but otherwise they don't get
> activated unless I'm trying to debug something.)
> In this case using it to turn off the asserts is probably overdoing it;
> an assert isn't nearly as expensive as, say, walking through a binary
> tree to make sure it's ordered the way I expect it to be.


PARANOID looked redundant, since with NDEBUG defined, those checks will
not be done, so can't you simply do e.g.

1. gcc <CFLAGS> -g ...
2. gcc <CFLAGS> -g -DNDEBUG ...

and finally

3. gcc <CFLAGS> ...

instead?

--
Tor <(E-Mail Removed) | tr i-za-h a-z>
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      12-10-2007
Tor Rustad wrote:
> (E-Mail Removed)lid wrote:
>

.... snip ...
>>
>> Out of curiousity, what is that design weakness, and how did you
>> fix it?

>
> Many will not check the return value for truncation. There are
> cases where this is not a bug, but most of the cases it will be,
> and strl* may hurt matters by hiding it.


I gather you consider failing to check the return value is OK and
that writing on unowned (or nonexistant) memory is prefereable to
truncation?

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Tor Rustad
Guest
Posts: n/a
 
      12-11-2007
CBFalconer wrote:
> Tor Rustad wrote:
>> (E-Mail Removed)lid wrote:
>>

> .... snip ...
>>> Out of curiousity, what is that design weakness, and how did you
>>> fix it?

>> Many will not check the return value for truncation. There are
>> cases where this is not a bug, but most of the cases it will be,
>> and strl* may hurt matters by hiding it.

>
> I gather you consider failing to check the return value is OK and
> that writing on unowned (or nonexistant) memory is prefereable to
> truncation?


Very odd conclusion, what did you think *fail safe* meant?

--
Tor <(E-Mail Removed) | tr i-za-h a-z>
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      12-11-2007
Tor Rustad wrote:
> CBFalconer wrote:
>> Tor Rustad wrote:
>>> (E-Mail Removed)lid wrote:
>>>

>> .... snip ...
>>
>>>> Out of curiousity, what is that design weakness, and how did you
>>>> fix it?
>>>
>>> Many will not check the return value for truncation. There are
>>> cases where this is not a bug, but most of the cases it will be,
>>> and strl* may hurt matters by hiding it.

>>
>> I gather you consider failing to check the return value is OK and
>> that writing on unowned (or nonexistant) memory is prefereable to
>> truncation?

>
> Very odd conclusion, what did you think *fail safe* meant?


I came to this conclusion when you recommend not checking the
returned value, which means you cannot detect an undersized
buffer. Either you are using strlcpy and the result is truncated,
or you are using strcpy (or equivalent) and the result is
overwriting. I am not forgiving failure to check the returned
value.

If I am way off please elucidate. Of course strlcpy can't
auto-expand the destination, since it has to operate into arbitrary
buffers.

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Help: undefined symbol: strlcpy Amy Lee Perl Misc 2 01-17-2008 03:15 PM
if and and vs if and,and titi VHDL 4 03-11-2007 05:23 AM
Do you like my strlcpy strlcat etc? RoSsIaCrIiLoIA C Programming 13 02-06-2005 03:18 PM
return value of strlcat Aleksandar Milivojevic C Programming 5 05-05-2004 03:35 PM



Advertisments