Re: strlcpy() or strscpy()?

2019-01-29 Thread Martijn van Duren
On 1/29/19 3:35 PM, Theo de Raadt wrote:
> Martijn van Duren  wrote:
> 
>> I think the others have given a decent explanation, but I would like to
>> elaborate a little furter.
> 
> I strongly agree with your points, but a few comments.
> 
>> OK, so strscpy won't read any more data from src than count bytes, which
>> could save you from reading from the end of the world, where strlcpy
>> does assume that src is a NUL-terminated string.
> 
> In C, a string is a NUL-terminated byte sequence.
> 
> If it isn't NUL-terminated, then it isn't a string.
> 
> The language feature "char []" does this, and the string-function subset
> of the language RELY upon this.  strlcpy follows that same pattern.
> 
> We don't need to say "C string", it is clear enough to say "string".
> 
>> src is clearly not a C-string, since it's not NUL-terminated, but
>> there's no problem, since strscpy doesn't throw us over the edge of the
>> world. Right?
> 
> Oh my god, strlen also fails.
> 
> Because the object isn't a string.
> 
> That much is clear.
> 
>> The problem is that you don't know what comes after src. It could be
>> sensitive information that's now being made available to an attacker, it
>> could introduce byte-sequences that completely blow up your terminal.
>> You just can't tell for sure. With strlcpy chances are greater that you
>> hit a page that's not mapped readable and you generate a SEGFAULT.
>> Like Joel said in his talk, it's better to crash and fix the bug.
> 
> Indeed.  Most OpenBSD security changes have focused on converting subtle
> failure conditions into quick & hard failures, rather than allowing code
> to continue running after creating the first instance of damage.
> 
>> Note that I'm not familiar enough with the kernel to make any statement
>> on whether on not things work identically there.
> 
> Same thing in the kernel.  An aggressive over-access is likely to run
> into an unmapped page of memory, and kaboom you crash, which is good because
> now you know of a bug you didn't know previously.  (1) the bug is less easily
> be exploited by an attacker since the common case crashes instead of leaving
> a damage artifact in memory, and (2) you know before the attacker, and (3)
> it is a priority for repair.
> 
>> If you want to be 100% secure you'd need to keep track of both the src
>> length (note that's the length of the string and not of the allocated
>> memory) and the destination buffer size and built a set of string
>> manipulation functions around that. But that would be a lot more tedious
>> to use and one could just as easily overlook to change the length
>> attribute upon change, which brings you back to square one.
> 
> The strlcpy paper described this as a design decision.  Easy for people
> to incorporate the overflow-protection.
> 
> Overflow-detection and handling is another problem.  strlcpy also makes
> this easy, but a glance at our whole source tree demonstrates how
> un-urgent the extended software development community takes that
> problem, meaning we seldom receive diffs to add checks.
> 
> As to strlcpy walking the whole string and determining the required
> length, that's the same behaviour as snprintf.  So strlcpy is mergely
> copying the interface of an existing function in the standard.
> 
> The enemy of the good is the perfect, and that enemy foams at the mouth
> about imperfection and then turns around and doesn't fix any software.
> 
>> I'm not certain what the author tries to say with "the implementation
>> is robust to the string changing out from underneath it", so I won't
>> comment on that part.
> 
> It must be grabbing the big string lock.
> 
I did a bit of digging for shits and giggles and found the following:
The Linux kernel does contain a version of strlcpy, but it is a bit
different from our strlcpy:
/**
 * strlcpy - Copy a C-string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @size: size of destination buffer
 *
 * Compatible with ``*BSD``: the result is always a valid
 * NUL-terminated string that fits in the buffer (unless,
 * of course, the buffer size is zero). It does not pad
 * out the result like strncpy() does.
 */
size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);

if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}

So Linux first does a whole walk over the string to find the length
and then does a full copy via memcpy.

Then we have strscpy[0], which walks src one word (long) at a time and
checks for NUL as it goes along. I can't find any locking, nor can I
ascribe any other security measure to it compared to our strlcpy.
>From this I can only guess that their statement that their strlcpy is
less secure is based around TOCTOU. But I can't see how changing your
string in the middle of any operation is going to end well.

As 

Re: strlcpy() or strscpy()?

2019-01-29 Thread Theo de Raadt
Martijn van Duren  wrote:

> I think the others have given a decent explanation, but I would like to
> elaborate a little furter.

I strongly agree with your points, but a few comments.

> OK, so strscpy won't read any more data from src than count bytes, which
> could save you from reading from the end of the world, where strlcpy
> does assume that src is a NUL-terminated string.

In C, a string is a NUL-terminated byte sequence.

If it isn't NUL-terminated, then it isn't a string.

The language feature "char []" does this, and the string-function subset
of the language RELY upon this.  strlcpy follows that same pattern.

We don't need to say "C string", it is clear enough to say "string".

> src is clearly not a C-string, since it's not NUL-terminated, but
> there's no problem, since strscpy doesn't throw us over the edge of the
> world. Right?

Oh my god, strlen also fails.

Because the object isn't a string.

That much is clear.

> The problem is that you don't know what comes after src. It could be
> sensitive information that's now being made available to an attacker, it
> could introduce byte-sequences that completely blow up your terminal.
> You just can't tell for sure. With strlcpy chances are greater that you
> hit a page that's not mapped readable and you generate a SEGFAULT.
> Like Joel said in his talk, it's better to crash and fix the bug.

Indeed.  Most OpenBSD security changes have focused on converting subtle
failure conditions into quick & hard failures, rather than allowing code
to continue running after creating the first instance of damage.

> Note that I'm not familiar enough with the kernel to make any statement
> on whether on not things work identically there.

Same thing in the kernel.  An aggressive over-access is likely to run
into an unmapped page of memory, and kaboom you crash, which is good because
now you know of a bug you didn't know previously.  (1) the bug is less easily
be exploited by an attacker since the common case crashes instead of leaving
a damage artifact in memory, and (2) you know before the attacker, and (3)
it is a priority for repair.

> If you want to be 100% secure you'd need to keep track of both the src
> length (note that's the length of the string and not of the allocated
> memory) and the destination buffer size and built a set of string
> manipulation functions around that. But that would be a lot more tedious
> to use and one could just as easily overlook to change the length
> attribute upon change, which brings you back to square one.

The strlcpy paper described this as a design decision.  Easy for people
to incorporate the overflow-protection.

Overflow-detection and handling is another problem.  strlcpy also makes
this easy, but a glance at our whole source tree demonstrates how
un-urgent the extended software development community takes that
problem, meaning we seldom receive diffs to add checks.

As to strlcpy walking the whole string and determining the required
length, that's the same behaviour as snprintf.  So strlcpy is mergely
copying the interface of an existing function in the standard.

The enemy of the good is the perfect, and that enemy foams at the mouth
about imperfection and then turns around and doesn't fix any software.

> I'm not certain what the author tries to say with "the implementation
> is robust to the string changing out from underneath it", so I won't
> comment on that part.

It must be grabbing the big string lock.



Re: strlcpy() or strscpy()?

2019-01-28 Thread Martijn van Duren
I think the others have given a decent explanation, but I would like to
elaborate a little furter.

The Linux documentation says the following:
Preferred to strlcpy since the API doesn't require reading memory from  
the src string beyond the specified "count" bytes, and since the return 
value is easier to error-check than strlcpy's. In addition, the 
implementation is robust to the string changing out from underneath it, 
unlike the current strlcpy implementation.

OK, so strscpy won't read any more data from src than count bytes, which
could save you from reading from the end of the world, where strlcpy
does assume that src is a NUL-terminated string. So it's not 100%
identical to the wrapper around strlcpy. But here also comes a wrong
sense of security.

Consider the following C code:
#include 
#include 

char *
crapcopy(char *src)
{
static char dst[1048576]; /* something big -> 1MB*/ 

strlcpy(dst, src, sizeof(dst));
return dst;
}

void
func(void)
{
char src[2];

src[0] = 'a';
src[1] = 'b';

printf("%s\n", crapcopy(src));
}

src is clearly not a C-string, since it's not NUL-terminated, but
there's no problem, since strscpy doesn't throw us over the edge of the
world. Right?
The problem is that you don't know what comes after src. It could be
sensitive information that's now being made available to an attacker, it
could introduce byte-sequences that completely blow up your terminal.
You just can't tell for sure. With strlcpy chances are greater that you
hit a page that's not mapped readable and you generate a SEGFAULT.
Like Joel said in his talk, it's better to crash and fix the bug.

Note that I'm not familiar enough with the kernel to make any statement
on whether on not things work identically there.

If you want to be 100% secure you'd need to keep track of both the src
length (note that's the length of the string and not of the allocated
memory) and the destination buffer size and built a set of string
manipulation functions around that. But that would be a lot more tedious
to use and one could just as easily overlook to change the length
attribute upon change, which brings you back to square one.

If documentation states that it requires a NUL-terminated string to
function just make damn sure that thing is NUL-terminated, which can
best be done by building it with functions that guarantee to NUL-
terminate their return string.

I'm not certain what the author tries to say with "the implementation
is robust to the string changing out from underneath it", so I won't
comment on that part.

martijn@

On 1/27/19 7:07 AM, 0sjfoij...@firemail.cc wrote:
> Recently on LCA2019, Joel Sing made a presentation about "Security 
> Vulnerability Mitigations"[1]
> (very good, btw). He suggests function strlcpy(3) as a secure API.
> In the same conference, though, Kees Cook ("Making C Less Dangerous in the 
> Linux kernel"[2]),
> recommends strscpy() as more secure. So, my question is: what's the best to 
> use?
> 
> Thanks in advance.
> 
> 
> [1] https://youtube.com/watch?v=9-uNC4-RbQM
> [2] https://youtube.com/watch?v=FY9SbqTO5GQ
> 



Re: strlcpy() or strscpy()?

2019-01-27 Thread Marc Espie
On Sun, Jan 27, 2019 at 01:07:05AM -0500, 0sjfoij...@firemail.cc wrote:
> Recently on LCA2019, Joel Sing made a presentation about "Security
> Vulnerability Mitigations"[1]
> (very good, btw). He suggests function strlcpy(3) as a secure API.
> In the same conference, though, Kees Cook ("Making C Less Dangerous in the
> Linux kernel"[2]),
> recommends strscpy() as more secure. So, my question is: what's the best to
> use?
> 
If anything, strscpy() made things more INsecure, by adding another 
confusing variation on a well-defined API that has proven itself.

strscpy reeks of "Not Invented Here", "Misplaced Hubris" and "Design by
committee" syndrome, which happens so very often in Linux-land.

Their only saving grace is darwinian: there are so many lemmings over there
that ludicrous ideas tend to get replaced by better ideas over time.



Re: strlcpy() or strscpy()?

2019-01-27 Thread Gilles Chehade
On Sun, Jan 27, 2019 at 01:07:05AM -0500, 0sjfoij...@firemail.cc wrote:
> Recently on LCA2019, Joel Sing made a presentation about "Security
> Vulnerability Mitigations"[1]
> (very good, btw). He suggests function strlcpy(3) as a secure API.
> In the same conference, though, Kees Cook ("Making C Less Dangerous in the
> Linux kernel"[2]),
> recommends strscpy() as more secure. So, my question is: what's the best to
> use?
> 

if i understand correctly, strscpy() works just like strlcpy():

   size_t
   strlcpy(char *dst, const char *src, size_t dstsize);

   ssize_t
   strscpy(char *dest, const char *src, size_t count);


with the only difference being that strlcpy() returns an unsigned size_t
which would be the size it would have written, then strscpy() returns an
ssize_t which returns the size or -E2BIG in case of an overflow.

quite frankly, i think the claim that strscpy() is safer, easier or that
it makes overflow easier to detect is bullshit for lack of a better word
given that they both work very similar:

   if (strlcpy(dest, src, sizeof dest) >= sizeof dest) {
  // overflow
   }

   if (strscpy(dest, src, sizeof dest) == -E2BIG) {
  // overflow
   }


and that strscpy() is essentially strlcpy() in NIH disguise:

   ssize_t
   strscpy(char *dest, const char *src, size_t count)
   {
ssize_t ret;

if ((ret = strlcpy(dest, src, count)) >= count)
   return -E2BIG;

return ret;
   }


just my opinion

-- 
Gilles Chehade @poolpOrg

https://www.poolp.org tip me: https://paypal.me/poolpOrg



Re: strlcpy() or strscpy()?

2019-01-27 Thread Theo de Raadt
0sjfoij...@firemail.cc wrote:

> Recently on LCA2019, Joel Sing made a presentation about "Security
> Vulnerability Mitigations"[1]
> (very good, btw). He suggests function strlcpy(3) as a secure API.
> In the same conference, though, Kees Cook ("Making C Less Dangerous in
> the Linux kernel"[2]),
> recommends strscpy() as more secure. So, my question is: what's the
> best to use?
> 
> Thanks in advance.
> 
> 
> [1] https://youtube.com/watch?v=9-uNC4-RbQM
> [2] https://youtube.com/watch?v=FY9SbqTO5GQ

Take note:

The return value is the number of characters copied (without the
trailing NUL byte) - unless the string would not fit into dest, in which
case the return value is -E2BIG.

1) It is a linux kernel API only, it does not show up anywhere in userland

2) As it is, it will never go into the standard C library, because that
   return-value scheme is outside of scope, in particular for a string function

strlcpy has significant deployment, and noone is worried about it being
being "insecure".

The NIH is obviously very strong in linux land.




strlcpy() or strscpy()?

2019-01-27 Thread 0sjfoijhfq
Recently on LCA2019, Joel Sing made a presentation about "Security 
Vulnerability Mitigations"[1]

(very good, btw). He suggests function strlcpy(3) as a secure API.
In the same conference, though, Kees Cook ("Making C Less Dangerous in 
the Linux kernel"[2]),
recommends strscpy() as more secure. So, my question is: what's the best 
to use?


Thanks in advance.


[1] https://youtube.com/watch?v=9-uNC4-RbQM
[2] https://youtube.com/watch?v=FY9SbqTO5GQ