linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2.6]: IPv6: strcpy -> strlcpy
@ 2003-11-27  8:14 Felipe Alfaro Solana
  2003-11-27  8:33 ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Alfaro Solana @ 2003-11-27  8:14 UTC (permalink / raw)
  To: davem; +Cc: Linux Kernel Mailinglist

[-- Attachment #1: Type: text/plain, Size: 149 bytes --]

Hi!

Attached is a patch against 2.6.0-test11 to convert all strcpy() calls
to their corresponding strlcpy() for IPv6. Compiled and tested.

Thanks!

[-- Attachment #2: strlcpy-ipv6.patch --]
[-- Type: text/x-patch, Size: 2566 bytes --]

diff -uNr linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c linux-2.6.0-test11/net/ipv6/ip6_tunnel.c
--- linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c	2003-11-26 21:42:56.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/ip6_tunnel.c	2003-11-27 00:27:09.000000000 +0100
@@ -1056,7 +1056,7 @@
 	struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
 	t->fl.proto = IPPROTO_IPV6;
 	t->dev = dev;
-	strcpy(t->parms.name, dev->name);
+	strlcpy(t->parms.name, dev->name, IFNAMSIZ);
 }
 
 /**
diff -uNr linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_queue.c linux-2.6.0-test11/net/ipv6/netfilter/ip6_queue.c
--- linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_queue.c	2003-11-26 21:43:27.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/netfilter/ip6_queue.c	2003-11-27 00:26:47.000000000 +0100
@@ -240,12 +240,12 @@
 	pmsg->hw_protocol     = entry->skb->protocol;
 	
 	if (entry->info->indev)
-		strcpy(pmsg->indev_name, entry->info->indev->name);
+		strlcpy(pmsg->indev_name, entry->info->indev->name, IFNAMSIZ);
 	else
 		pmsg->indev_name[0] = '\0';
 	
 	if (entry->info->outdev)
-		strcpy(pmsg->outdev_name, entry->info->outdev->name);
+		strlcpy(pmsg->outdev_name, entry->info->outdev->name, IFNAMSIZ);
 	else
 		pmsg->outdev_name[0] = '\0';
 	
diff -uNr linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_tables.c linux-2.6.0-test11/net/ipv6/netfilter/ip6_tables.c
--- linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_tables.c	2003-11-26 21:45:30.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/netfilter/ip6_tables.c	2003-11-27 00:24:07.000000000 +0100
@@ -1357,7 +1357,7 @@
 			       sizeof(info.underflow));
 			info.num_entries = t->private->number;
 			info.size = t->private->size;
-			strcpy(info.name, name);
+			strlcpy(info.name, name, IP6T_TABLE_MAXNAMELEN);
 
 			if (copy_to_user(user, &info, *len) != 0)
 				ret = -EFAULT;
diff -uNr linux-2.6.0-test11.orig/net/ipv6/sit.c linux-2.6.0-test11/net/ipv6/sit.c
--- linux-2.6.0-test11.orig/net/ipv6/sit.c	2003-11-26 21:45:36.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/sit.c	2003-11-27 00:27:01.000000000 +0100
@@ -747,7 +747,7 @@
 	iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
+	strlcpy(tunnel->parms.name, dev->name, IFNAMSIZ);
 
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@ -786,7 +786,7 @@
 	struct iphdr *iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
+	strlcpy(tunnel->parms.name, dev->name, IFNAMSIZ);
 
 	iph->version		= 4;
 	iph->protocol		= IPPROTO_IPV6;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27  8:14 [PATCH 2.6]: IPv6: strcpy -> strlcpy Felipe Alfaro Solana
@ 2003-11-27  8:33 ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-27 10:59   ` David S. Miller
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-27  8:33 UTC (permalink / raw)
  To: felipe_alfaro; +Cc: davem, linux-kernel, yoshfuji, netdev

In article <1069920883.2476.1.camel@teapot.felipe-alfaro.com> (at Thu, 27 Nov 2003 09:14:44 +0100), Felipe Alfaro Solana <felipe_alfaro@linuxmail.org> says:

> Attached is a patch against 2.6.0-test11 to convert all strcpy() calls
> to their corresponding strlcpy() for IPv6. Compiled and tested.

I don't like this coding style.

diff -uNr linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c linux-2.6.0-test11/net/ipv6/ip6_tunnel.c
--- linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c	2003-11-26 21:42:56.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/ip6_tunnel.c	2003-11-27 00:27:09.000000000 +0100
-	strcpy(t->parms.name, dev->name);
+	strlcpy(t->parms.name, dev->name, IFNAMSIZ);
                                          sizeof(t->parms.name)

or something like that.

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27  8:33 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-27 10:59   ` David S. Miller
  2003-11-27 12:04     ` Felipe Alfaro Solana
  0 siblings, 1 reply; 20+ messages in thread
From: David S. Miller @ 2003-11-27 10:59 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / _$B5HF#1QL@
  Cc: felipe_alfaro, linux-kernel, yoshfuji, netdev

On Thu, 27 Nov 2003 17:33:20 +0900 (JST)
YOSHIFUJI Hideaki / _$B5HF#1QL@ <yoshfuji@linux-ipv6.org> wrote:

> -	strcpy(t->parms.name, dev->name);
> +	strlcpy(t->parms.name, dev->name, IFNAMSIZ);
>                                           sizeof(t->parms.name)
> 
> or something like that.

I agree, using sizeof() is the less error prone way of
doing things like this.

Felipe could you please rewrite your patch like this?

Thank you.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 10:59   ` David S. Miller
@ 2003-11-27 12:04     ` Felipe Alfaro Solana
  2003-11-27 12:09       ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Alfaro Solana @ 2003-11-27 12:04 UTC (permalink / raw)
  To: David S. Miller
  Cc: YOSHIFUJI Hideaki / _$B5HF#1QL@, Linux Kernel Mailinglist, netdev

[-- Attachment #1: Type: text/plain, Size: 202 bytes --]

On Thu, 2003-11-27 at 11:59, David S. Miller wrote:

> I agree, using sizeof() is the less error prone way of
> doing things like this.
> 
> Felipe could you please rewrite your patch like this?

Done!

[-- Attachment #2: strlcpy-ipv6.patch --]
[-- Type: text/x-patch, Size: 2644 bytes --]

diff -uNr linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c linux-2.6.0-test11/net/ipv6/ip6_tunnel.c
--- linux-2.6.0-test11.orig/net/ipv6/ip6_tunnel.c	2003-11-26 21:42:56.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/ip6_tunnel.c	2003-11-27 00:27:09.000000000 +0100
@@ -1056,7 +1056,7 @@
 	struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
 	t->fl.proto = IPPROTO_IPV6;
 	t->dev = dev;
-	strcpy(t->parms.name, dev->name);
+	strlcpy(t->parms.name, dev->name, sizeof(t->parms.name));
 }
 
 /**
diff -uNr linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_queue.c linux-2.6.0-test11/net/ipv6/netfilter/ip6_queue.c
--- linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_queue.c	2003-11-26 21:43:27.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/netfilter/ip6_queue.c	2003-11-27 00:26:47.000000000 +0100
@@ -240,12 +240,12 @@
 	pmsg->hw_protocol     = entry->skb->protocol;
 	
 	if (entry->info->indev)
-		strcpy(pmsg->indev_name, entry->info->indev->name);
+		strlcpy(pmsg->indev_name, entry->info->indev->name, sizeof(pmsg->indev_name));
 	else
 		pmsg->indev_name[0] = '\0';
 	
 	if (entry->info->outdev)
-		strcpy(pmsg->outdev_name, entry->info->outdev->name);
+		strlcpy(pmsg->outdev_name, entry->info->outdev->name, sizeof(pmsg->outdev_name));
 	else
 		pmsg->outdev_name[0] = '\0';
 	
diff -uNr linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_tables.c linux-2.6.0-test11/net/ipv6/netfilter/ip6_tables.c
--- linux-2.6.0-test11.orig/net/ipv6/netfilter/ip6_tables.c	2003-11-26 21:45:30.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/netfilter/ip6_tables.c	2003-11-27 00:24:07.000000000 +0100
@@ -1357,7 +1357,7 @@
 			       sizeof(info.underflow));
 			info.num_entries = t->private->number;
 			info.size = t->private->size;
-			strcpy(info.name, name);
+			strlcpy(info.name, name, sizeof(info.name));
 
 			if (copy_to_user(user, &info, *len) != 0)
 				ret = -EFAULT;
diff -uNr linux-2.6.0-test11.orig/net/ipv6/sit.c linux-2.6.0-test11/net/ipv6/sit.c
--- linux-2.6.0-test11.orig/net/ipv6/sit.c	2003-11-26 21:45:36.000000000 +0100
+++ linux-2.6.0-test11/net/ipv6/sit.c	2003-11-27 00:27:01.000000000 +0100
@@ -747,7 +747,7 @@
 	iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
+	strlcpy(tunnel->parms.name, dev->name, sizeof(tunnel->parms.name));
 
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@ -786,7 +786,7 @@
 	struct iphdr *iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
+	strlcpy(tunnel->parms.name, dev->name, sizeof(tunnel->parms.name));
 
 	iph->version		= 4;
 	iph->protocol		= IPPROTO_IPV6;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 12:04     ` Felipe Alfaro Solana
@ 2003-11-27 12:09       ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-27 19:46         ` Russell King
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-27 12:09 UTC (permalink / raw)
  To: felipe_alfaro; +Cc: davem, linux-kernel, netdev, yoshfuji

In article <1069934643.2393.0.camel@teapot.felipe-alfaro.com> (at Thu, 27 Nov 2003 13:04:04 +0100), Felipe Alfaro Solana <felipe_alfaro@linuxmail.org> says:

> On Thu, 2003-11-27 at 11:59, David S. Miller wrote:
> 
> > I agree, using sizeof() is the less error prone way of
> > doing things like this.
> > 
> > Felipe could you please rewrite your patch like this?
> 
> Done!

Thanks. Ok to me.
--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 12:09       ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-27 19:46         ` Russell King
  2003-11-27 19:54           ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 20+ messages in thread
From: Russell King @ 2003-11-27 19:46 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B
  Cc: felipe_alfaro, davem, linux-kernel, netdev

On Thu, Nov 27, 2003 at 09:09:53PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B wrote:
> In article <1069934643.2393.0.camel@teapot.felipe-alfaro.com> (at Thu, 27 Nov 2003 13:04:04 +0100), Felipe Alfaro Solana <felipe_alfaro@linuxmail.org> says:
> 
> > On Thu, 2003-11-27 at 11:59, David S. Miller wrote:
> > 
> > > I agree, using sizeof() is the less error prone way of
> > > doing things like this.
> > > 
> > > Felipe could you please rewrite your patch like this?
> > 
> > Done!
> 
> Thanks. Ok to me.

I'm slightly cautious here, although I haven't read the patch yet.
Did anyone consider whether any of these structures were copied to
user space, and whether, as a result of this change, we're now
copying uninitialised data to users?

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 19:46         ` Russell King
@ 2003-11-27 19:54           ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-27 20:00             ` Russell King
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-27 19:54 UTC (permalink / raw)
  To: rmk+lkml; +Cc: felipe_alfaro, davem, linux-kernel, netdev, yoshfuji

In article <20031127194602.A25015@flint.arm.linux.org.uk> (at Thu, 27 Nov 2003 19:46:02 +0000), Russell King <rmk+lkml@arm.linux.org.uk> says:

> > > > I agree, using sizeof() is the less error prone way of
> > > > doing things like this.
> > > > 
> > > > Felipe could you please rewrite your patch like this?
> > > 
> > > Done!
> > 
> > Thanks. Ok to me.
> 
> I'm slightly cautious here, although I haven't read the patch yet.
> Did anyone consider whether any of these structures were copied to
> user space, and whether, as a result of this change, we're now
> copying uninitialised data to users?

I believe that it, to change from strcpy() to strlcpy(), just 
eliminates possibility of buffer-overrun.

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 19:54           ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-27 20:00             ` Russell King
  2003-11-27 20:47               ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-27 22:06               ` Felipe Alfaro Solana
  0 siblings, 2 replies; 20+ messages in thread
From: Russell King @ 2003-11-27 20:00 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B
  Cc: felipe_alfaro, davem, linux-kernel, netdev

On Fri, Nov 28, 2003 at 04:54:13AM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B wrote:
> In article <20031127194602.A25015@flint.arm.linux.org.uk> (at Thu, 27 Nov 2003 19:46:02 +0000), Russell King <rmk+lkml@arm.linux.org.uk> says:
> > I'm slightly cautious here, although I haven't read the patch yet.
> > Did anyone consider whether any of these structures were copied to
> > user space, and whether, as a result of this change, we're now
> > copying uninitialised data to users?
> 
> I believe that it, to change from strcpy() to strlcpy(), just 
> eliminates possibility of buffer-overrun.

While this is 100% correct, the bit which raised my attention was the
original message which didn't seem to show that the above had been
considered.

The thing that worries me is that an incorrect strlcpy() conversion
gives the impression that someone has thought about buffer underruns
as well as overruns, and, unless someone /has/ actually thought about
it, there could well still be a security problem lurking there.

I'm just overly wary of all strlcpy() conversions.

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 20:00             ` Russell King
@ 2003-11-27 20:47               ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-27 21:14                 ` Murray J. Root
  2003-11-27 22:06               ` Felipe Alfaro Solana
  1 sibling, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-27 20:47 UTC (permalink / raw)
  To: rmk+lkml; +Cc: felipe_alfaro, davem, linux-kernel, netdev, yoshfuji

In article <20031127200041.B25015@flint.arm.linux.org.uk> (at Thu, 27 Nov 2003 20:00:41 +0000), Russell King <rmk+lkml@arm.linux.org.uk> says:

> The thing that worries me is that an incorrect strlcpy() conversion
> gives the impression that someone has thought about buffer underruns
> as well as overruns, and, unless someone /has/ actually thought about
> it, there could well still be a security problem lurking there.

Hmm, what do you actually mean by "buffer underruns?"

(If I'm correct) do you suggest that we should zero-out rest of 
destination buffer?

if so, we may want to have a function, say strlcpy0(), like this:

size_t strlcpy0(char *dst, const char *src, size_t maxlen)
{
  size_t len = strlcpy(dst, src, maxlen);
  if (maxlen && len < maxlen - 1)
    memset(dst + len + 1, 0, maxlen - len - 1);
  return len;
}

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 20:47               ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-27 21:14                 ` Murray J. Root
  0 siblings, 0 replies; 20+ messages in thread
From: Murray J. Root @ 2003-11-27 21:14 UTC (permalink / raw)
  To: linux-kernel

On Fri, Nov 28, 2003 at 05:47:24AM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> In article <20031127200041.B25015@flint.arm.linux.org.uk> (at Thu, 27 Nov 2003 20:00:41 +0000), Russell King <rmk+lkml@arm.linux.org.uk> says:
> 
> > The thing that worries me is that an incorrect strlcpy() conversion
> > gives the impression that someone has thought about buffer underruns
> > as well as overruns, and, unless someone /has/ actually thought about
> > it, there could well still be a security problem lurking there.
> 
> Hmm, what do you actually mean by "buffer underruns?"
> 
> (If I'm correct) do you suggest that we should zero-out rest of 
> destination buffer?
> 
> if so, we may want to have a function, say strlcpy0(), like this:
> 
> size_t strlcpy0(char *dst, const char *src, size_t maxlen)
> {
>   size_t len = strlcpy(dst, src, maxlen);
>   if (maxlen && len < maxlen - 1)
>     memset(dst + len + 1, 0, maxlen - len - 1);
>   return len;
> }
> 

size_t strlcpy0(char *dst, const char *src, size_t maxlen)
{
  memset(dst, 0, maxlen);
  size_t len = strlcpy(dst, src, maxlen);
  return len;
}

-- 
Murray J. Root


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 20:00             ` Russell King
  2003-11-27 20:47               ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-27 22:06               ` Felipe Alfaro Solana
  2003-11-27 22:19                 ` Russell King
  1 sibling, 1 reply; 20+ messages in thread
From: Felipe Alfaro Solana @ 2003-11-27 22:06 UTC (permalink / raw)
  To: Russell King
  Cc: YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B, davem,
	Linux Kernel Mailinglist, netdev

On Thu, 2003-11-27 at 21:00, Russell King wrote:
> > 
> > I believe that it, to change from strcpy() to strlcpy(), just 
> > eliminates possibility of buffer-overrun.
> 
> While this is 100% correct, the bit which raised my attention was the
> original message which didn't seem to show that the above had been
> considered.

Well, I can't see the difference between using strcpy() and strlcpy().
Let be:

char destination[MAX];
char * source;
N = strlen(source);

We could use strlcpy(destination, source, MAX) or strcpy(destination,
source).

We have the following scenarios:

- N < MAX. In this case, both strcpy() and strlcpy() should yield the
same results. No buffer overflows. If the source strings does not
already contain uninitialised data, there's no way for strlcpy() to copy
them.

- N >= MAX. In this case, strlcpy() will copy less bytes than strcpy().
To be exact, strlcpy() will copy N-MAX+1 bytes less than strcpy().
Again, no buffer overflows. Also, it's still impossible to copy
uninitialised data since we just stop at \0 or when we fill up the
destination buffer.

So I don't see how using strlcpy() could copy uninitialised data from
kernel space to user space. If we used memcpy() we could end up copying
uninitialised data, but I can't see how using strlcpy() would do that.

In general terms, strlcpy() will copy *at most* the same number of bytes
as strcpy(), but there is no single case when strlcpy() will copy more
bytes than strcpy().

Can someone throw some light on this?


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 22:06               ` Felipe Alfaro Solana
@ 2003-11-27 22:19                 ` Russell King
  2003-11-27 22:33                   ` Russell King
  2003-11-27 23:03                   ` Felipe Alfaro Solana
  0 siblings, 2 replies; 20+ messages in thread
From: Russell King @ 2003-11-27 22:19 UTC (permalink / raw)
  To: Felipe Alfaro Solana
  Cc: YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B, davem,
	Linux Kernel Mailinglist, netdev

On Thu, Nov 27, 2003 at 11:06:10PM +0100, Felipe Alfaro Solana wrote:
> On Thu, 2003-11-27 at 21:00, Russell King wrote:
> > > 
> > > I believe that it, to change from strcpy() to strlcpy(), just 
> > > eliminates possibility of buffer-overrun.
> > 
> > While this is 100% correct, the bit which raised my attention was the
> > original message which didn't seem to show that the above had been
> > considered.
> 
> Well, I can't see the difference between using strcpy() and strlcpy().

You misunderstand me.  Consider the difference between:

	strcpy(d, s)
	strlcpy(d, s, sizeof(d));
	strncpy(d, s, sizeof(d));

strncpy zeros the remainder of d if strlen(s) < sizeof(d), but does not
zero terminate the buffer if strlen(s) == sizeof(d).  (Note: this is
how strncpy under the Linux kernel is supposed to work, and yes, the
generic strncpy version in lib/string.c is still buggy.)

strlcpy copies up to the smaller of strlen(s)-1 and sizeof(d)-1, and
ensures that the string is null terminated.  If strlen(s) < sizeof(d)-1,
bytes in d will not be written.

Note my final sentence there.  Consider the following:

	char foo[256];

	strlcpy(foo, "hello", sizeof(foo);

	copy_to_user(uptr, foo, sizeof(foo));

That ends up writing uninitialised kernel data to (unprivileged) user
space.  So would strcpy() used in that situation.

strncpy() on the other hand, will zero the rest of the buffer (on x86
at least) but you'll have to manually ensure that there is a terminator
on the end.  Or, you use strlcpy but memset the entire space you're
copying the string into beforehand, which could be wasteful.

Note: we should really fix the generic strncpy() - there are places in
the kernel source which rely on the x86 strncpy() behaviour today (eg,
binfmt_*.c core file generation.)

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 22:19                 ` Russell King
@ 2003-11-27 22:33                   ` Russell King
  2003-11-28  1:34                     ` Mitchell Blank Jr
  2003-11-27 23:03                   ` Felipe Alfaro Solana
  1 sibling, 1 reply; 20+ messages in thread
From: Russell King @ 2003-11-27 22:33 UTC (permalink / raw)
  To: Felipe Alfaro Solana, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B, davem,
	Linux Kernel Mailinglist, netdev

On Thu, Nov 27, 2003 at 10:19:28PM +0000, Russell King wrote:
> Note: we should really fix the generic strncpy() - there are places in
> the kernel source which rely on the x86 strncpy() behaviour today (eg,
> binfmt_*.c core file generation.)

Sorry, bad example.  Hmm, from a glance around, it seems that all of
the places which use strncpy() implicitly zero the buffer prior to
using strncpy().

This means that the x86 strncpy is doing unnecessary zeroing.  I do
remember Alan complaining about the last set of strlcpy() stuff
introducing information leaks - maybe those got fixed though.

Ok, I don't know where the kernel stands on this issue anymore.
Can someone definitively provide a statement of exactly what the
kernel expects of strncpy() ?

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 22:19                 ` Russell King
  2003-11-27 22:33                   ` Russell King
@ 2003-11-27 23:03                   ` Felipe Alfaro Solana
  2003-11-28  0:23                     ` YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 1 reply; 20+ messages in thread
From: Felipe Alfaro Solana @ 2003-11-27 23:03 UTC (permalink / raw)
  To: Russell King
  Cc: YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B, davem,
	Linux Kernel Mailinglist, netdev

On Thu, 2003-11-27 at 23:19, Russell King wrote:

> You misunderstand me.  Consider the difference between:

OK, it's perfectly clear now :-)

> Note my final sentence there.  Consider the following:
> 
> 	char foo[256];
> 
> 	strlcpy(foo, "hello", sizeof(foo);
> 
> 	copy_to_user(uptr, foo, sizeof(foo));
> 
> That ends up writing uninitialised kernel data to (unprivileged) user
> space.  So would strcpy() used in that situation.
> 
> strncpy() on the other hand, will zero the rest of the buffer (on x86
> at least) but you'll have to manually ensure that there is a terminator
> on the end.  Or, you use strlcpy but memset the entire space you're
> copying the string into beforehand, which could be wasteful.
> 
> Note: we should really fix the generic strncpy() - there are places in
> the kernel source which rely on the x86 strncpy() behaviour today (eg,
> binfmt_*.c core file generation.)

So, as I see:

1. We should fix strncpy()
2. I should replace strlcpy() with strncpy() in my patches.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 23:03                   ` Felipe Alfaro Solana
@ 2003-11-28  0:23                     ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-28  0:26                       ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-28  0:23 UTC (permalink / raw)
  To: felipe_alfaro; +Cc: rmk+lkml, davem, linux-kernel, netdev, yoshfuji

In article <1069974209.5349.7.camel@teapot.felipe-alfaro.com> (at Fri, 28 Nov 2003 00:03:29 +0100), Felipe Alfaro Solana <felipe_alfaro@linuxmail.org> says:

> So, as I see:
> 
> 1. We should fix strncpy()
> 2. I should replace strlcpy() with strncpy() in my patches.

I think it is NOT correct. 
It SEEMS unsafe to use strncpy() even if it terminated 
string correctly.

So, I'd suggest to replace

    strlcpy(dst, src, len);

with 

 1)   strlcpy0(dst, src, len);

where strlcpy0() is provided in my previous mail,
or with

 2)   memset(dst, 0, len);
      strncpy(dst, src, len);

(or say, strncpy0())
or, with

 3)   if (len)
         strncpy(dst, src, len - 1);
      dst[len] = 0;

(or, say, strncpy0()).

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-28  0:23                     ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-28  0:26                       ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-28  0:40                         ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-28  0:26 UTC (permalink / raw)
  To: felipe_alfaro; +Cc: rmk+lkml, davem, linux-kernel, netdev, yoshfuji

In article <20031128.092326.39861126.yoshfuji@linux-ipv6.org> (at Fri, 28 Nov 2003 09:23:26 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says:

>  2)   memset(dst, 0, len);
>       strncpy(dst, src, len);

oops, this should be

        memset(dst, 0, len);
        if (len > 0)
          strncpy(dst, src, len - 1);


>  3)   if (len)
>          strncpy(dst, src, len - 1);
>       dst[len] = 0;
> 
> (or, say, strncpy0()).

Note: in this case, we need to fix strncpy() first 
to zero-out rest of destination buffer.

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-28  0:26                       ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-28  0:40                         ` YOSHIFUJI Hideaki / 吉藤英明
  2003-11-28 11:22                           ` Jörn Engel
  0 siblings, 1 reply; 20+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-11-28  0:40 UTC (permalink / raw)
  To: felipe_alfaro; +Cc: rmk+lkml, davem, linux-kernel, netdev, yoshfuji

In article <20031128.092642.47232575.yoshfuji@linux-ipv6.org> (at Fri, 28 Nov 2003 09:26:42 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says:

> >  3)   if (len)
> >          strncpy(dst, src, len - 1);
> >       dst[len] = 0;

grr, another mistake...:

          if (len) {
             strncpy(dst, src, len - 1);
             dst[len - 1];
          }

----------------
1) use strlcpy0(dst, src, len)

size_t strlcpy0(char *dst, const char *src, size_t maxlen)
{
  size_t len = strlcpy(dst, src, maxlen);
  if (likely(maxlen != 0) && len < maxlen - 1)
    memset(dst + len + 1, 0, maxlen - len - 1);
}

2a) use strncpy0(dst, src, len)

char *strncpy0(char *dst, const char *src, size_t maxlen)
{
  memset(dst, 0, maxlen);
  if (likely(maxlen != 0))
    strncpy(dst, src, maxlen - 1);
}

2b) fix strncpy() to zero-out rest of destination buffer 
    and use strncpy0(dst, src, len)

char *strncpy0(char *dst, const char *src, size_t maxlen)
{
  if (likely(maxlen != 0)) {
    strncpy(dst, src, maxlen - 1);
    dst[maxlen - 1] = 0;
  }
}


I prefer 1 > 2b >> 2a.

--yoshfuji

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-27 22:33                   ` Russell King
@ 2003-11-28  1:34                     ` Mitchell Blank Jr
  0 siblings, 0 replies; 20+ messages in thread
From: Mitchell Blank Jr @ 2003-11-28  1:34 UTC (permalink / raw)
  To: Felipe Alfaro Solana, YOSHIFUJI Hideaki / ?$B5HF#1QL@?(B, davem,
	Linux Kernel Mailinglist, netdev

Russell King wrote:
> Sorry, bad example.  Hmm, from a glance around, it seems that all of
> the places which use strncpy() implicitly zero the buffer prior to
> using strncpy().
> 
> This means that the x86 strncpy is doing unnecessary zeroing.  I do
> remember Alan complaining about the last set of strlcpy() stuff
> introducing information leaks - maybe those got fixed though.

The problem is that most places you're filling in an array in a struct.
So even if you use strncpy() everywhere you can still get bitten if the
compiler inserts any padding for alignment on some architecture (since
even if you fully initialize each char[] array in the structure using
strncpy you might still leak info in padding bytes)

The safest thing to do in these cases is:
  1. memset() the array before you start
  2. strlcpy() for filling each char[] array (since strncpy would just
     re-zero those bytes it's wasteful)

Yes, the full memset() is a small waste, but its safe.  In 99% of these
cases we're talking about some weird ioctl() or something that's way off
the fast path anyways.

I pointed this out some months ago and someone (forgot who) replied that
there shouldn't be any padding in any struct exported from the kernel.
They added a compiler warning for structure padding in the -mm series for
a few days, but I guess it caused so many warnings that they took it right
out again, so I believe that there ARE plenty of places that user-visible
struct's get padded by the ABI of some platforms.  If there's some difinitive
evidence that padding never happens I'd like to see it.

-Mitch

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
  2003-11-28  0:40                         ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-11-28 11:22                           ` Jörn Engel
  0 siblings, 0 replies; 20+ messages in thread
From: Jörn Engel @ 2003-11-28 11:22 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / ?$B5HF#1QL@
  Cc: felipe_alfaro, rmk+lkml, davem, linux-kernel, netdev

On Fri, 28 November 2003 09:40:22 +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> In article <20031128.092642.47232575.yoshfuji@linux-ipv6.org> (at Fri, 28 Nov 2003 09:26:42 +0900 (JST)), YOSHIFUJI Hideaki / ?$B5HF#1QL@ <yoshfuji@linux-ipv6.org> says:
> 
> > >  3)   if (len)
> > >          strncpy(dst, src, len - 1);
> > >       dst[len] = 0;
> 
> grr, another mistake...:
> 
>           if (len) {
>              strncpy(dst, src, len - 1);
>              dst[len - 1];
                           ^
>           }

Did you forget ' = 0' there? ;)

Jörn

-- 
ticks = jiffies;
while (ticks == jiffies);
ticks = jiffies;
-- /usr/src/linux/init/main.c

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.6]: IPv6: strcpy -> strlcpy
       [not found]           ` <WCOd.3u0.1@gated-at.bofh.it>
@ 2003-11-28 14:04             ` Ihar 'Philips' Filipau
  0 siblings, 0 replies; 20+ messages in thread
From: Ihar 'Philips' Filipau @ 2003-11-28 14:04 UTC (permalink / raw)
  To: Russell King; +Cc: Linux Kernel Mailing List

Russell King wrote:
> 
> That ends up writing uninitialised kernel data to (unprivileged) user
> space.  So would strcpy() used in that situation.
> 

   I used to use:

    char buf[MAX];
     ...
    buf[MAX-1] = 0; /* zero terminate */
    strncpy(buf, src, MAX-1);

   This is safe regarding both 0 termination and 0 padding rest of string.

-- 
Ihar 'Philips' Filipau  / with best regards from Saarbruecken.
--                                                           _ _ _
  Because the kernel depends on it existing. "init"          |_|*|_|
  literally _is_ special from a kernel standpoint,           |_|_|*|
  because its' the "reaper of zombies" (and, may I add,      |*|*|*|
  that would be a great name for a rock band).
                                 -- Linus Torvalds


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2003-11-28 14:05 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-27  8:14 [PATCH 2.6]: IPv6: strcpy -> strlcpy Felipe Alfaro Solana
2003-11-27  8:33 ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-27 10:59   ` David S. Miller
2003-11-27 12:04     ` Felipe Alfaro Solana
2003-11-27 12:09       ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-27 19:46         ` Russell King
2003-11-27 19:54           ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-27 20:00             ` Russell King
2003-11-27 20:47               ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-27 21:14                 ` Murray J. Root
2003-11-27 22:06               ` Felipe Alfaro Solana
2003-11-27 22:19                 ` Russell King
2003-11-27 22:33                   ` Russell King
2003-11-28  1:34                     ` Mitchell Blank Jr
2003-11-27 23:03                   ` Felipe Alfaro Solana
2003-11-28  0:23                     ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-28  0:26                       ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-28  0:40                         ` YOSHIFUJI Hideaki / 吉藤英明
2003-11-28 11:22                           ` Jörn Engel
     [not found] <Wt8p.1R5.13@gated-at.bofh.it>
     [not found] ` <Wti7.2fc.19@gated-at.bofh.it>
     [not found]   ` <WAjQ.83K.37@gated-at.bofh.it>
     [not found]     ` <WAte.8iX.5@gated-at.bofh.it>
     [not found]       ` <WACW.a9.19@gated-at.bofh.it>
     [not found]         ` <WCuZ.2Tm.11@gated-at.bofh.it>
     [not found]           ` <WCOd.3u0.1@gated-at.bofh.it>
2003-11-28 14:04             ` Ihar 'Philips' Filipau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).