linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] eCryptfs: infinite loop bug
@ 2012-01-18  7:30 Li Wang
  2012-01-18 15:26 ` Cong Wang
  0 siblings, 1 reply; 13+ messages in thread
From: Li Wang @ 2012-01-18  7:30 UTC (permalink / raw)
  To: ecryptfs, linux-fsdevel, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GBK", Size: 1813 bytes --]

Hi,
  There is an infinite loop bug in eCryptfs, to make it present,
just truncate to generate a huge file (>= 4G) on a 32-bit machine 
under the plain text foleder mounted with eCryptfs, a simple command
'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
therefore the following command 'truncate -s 4GB dummy' will not trigger this bug.
The bug comes from a data overflow, the patch below fixes it.

Cheers,
Li Wang

---

signed-off-by: Li Wang <liwang@nudt.edu.cn >
               Yunchuan Wen (wenyunchuan@kylinos.com.cn )

--- read_write.c.orig 2012-01-18 10:39:26.000000000 +0800
+++ read_write.c 2012-01-18 19:48:41.484196221 +0800
@@ -130,7 +130,7 @@ int ecryptfs_write(struct inode *ecryptf
   pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
   size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
   size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
-  size_t total_remaining_bytes = ((offset + size) - pos);
+  loff_t total_remaining_bytes = ((offset + size) - pos);
 
   if (num_bytes > total_remaining_bytes)
    num_bytes = total_remaining_bytes;



--- read_write.c.orig	2012-01-18 10:39:26.000000000 +0800
+++ read_write.c	2012-01-18 19:48:41.484196221 +0800
@@ -130,7 +130,7 @@ int ecryptfs_write(struct inode *ecryptf
 		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
 		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
 		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
-		size_t total_remaining_bytes = ((offset + size) - pos);
+		loff_t total_remaining_bytes = ((offset + size) - pos);
 
 		if (num_bytes > total_remaining_bytes)
 			num_bytes = total_remaining_bytes;

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-18  7:30 [PATCH] eCryptfs: infinite loop bug Li Wang
@ 2012-01-18 15:26 ` Cong Wang
  2012-01-18 21:40   ` Tyler Hicks
       [not found]   ` <526922120.05125@eyou.net>
  0 siblings, 2 replies; 13+ messages in thread
From: Cong Wang @ 2012-01-18 15:26 UTC (permalink / raw)
  To: Li Wang
  Cc: ecryptfs, linux-fsdevel, linux-kernel, Tyler Hicks, Dustin Kirkland

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

On 01/18/2012 03:30 PM, Li Wang wrote:
> Hi,
>    There is an infinite loop bug in eCryptfs, to make it present,
> just truncate to generate a huge file (>= 4G) on a 32-bit machine
> under the plain text foleder mounted with eCryptfs, a simple command
> 'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> therefore the following command 'truncate -s 4GB dummy' will not trigger this bug.
> The bug comes from a data overflow, the patch below fixes it.
>
>

Hi,

Your patch is not correctly generated, you need to make the diff on top 
of the source tree.

Also, after reviewing the code, I think there are more places need to 
fix. Can you try my patch below?

Thanks.

---->

Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com>



[-- Attachment #2: ecryptfs-loff_t.diff --]
[-- Type: text/x-patch, Size: 2094 bytes --]

diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index a9f29b1..9ca9c17 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -653,7 +653,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
 			 loff_t offset, size_t size);
 int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
 				      struct page *page_for_lower,
-				      size_t offset_in_page, size_t size);
+				      loff_t offset_in_page, size_t size);
 int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size);
 int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
 			struct inode *ecryptfs_inode);
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 3745f7c..93d80c4 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -72,7 +72,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
  */
 int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
 				      struct page *page_for_lower,
-				      size_t offset_in_page, size_t size)
+				      loff_t offset_in_page, size_t size)
 {
 	char *virt;
 	loff_t offset;
@@ -128,15 +128,15 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
 		pos = offset;
 	while (pos < (offset + size)) {
 		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
-		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
-		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
-		size_t total_remaining_bytes = ((offset + size) - pos);
+		loff_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
+		loff_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+		loff_t total_remaining_bytes = ((offset + size) - pos);
 
 		if (num_bytes > total_remaining_bytes)
 			num_bytes = total_remaining_bytes;
 		if (pos < offset) {
 			/* remaining zeros to write, up to destination offset */
-			size_t total_remaining_zeros = (offset - pos);
+			loff_t total_remaining_zeros = (offset - pos);
 
 			if (num_bytes > total_remaining_zeros)
 				num_bytes = total_remaining_zeros;

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-18 15:26 ` Cong Wang
@ 2012-01-18 21:40   ` Tyler Hicks
  2012-01-19  3:43     ` Linus Torvalds
       [not found]   ` <526922120.05125@eyou.net>
  1 sibling, 1 reply; 13+ messages in thread
From: Tyler Hicks @ 2012-01-18 21:40 UTC (permalink / raw)
  To: Cong Wang; +Cc: Li Wang, ecryptfs, linux-fsdevel, linux-kernel, Dustin Kirkland

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

On 2012-01-18 23:26:52, Cong Wang wrote:
> On 01/18/2012 03:30 PM, Li Wang wrote:
> >Hi,
> >   There is an infinite loop bug in eCryptfs, to make it present,
> >just truncate to generate a huge file (>= 4G) on a 32-bit machine
> >under the plain text foleder mounted with eCryptfs, a simple command
> >'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> >therefore the following command 'truncate -s 4GB dummy' will not trigger this bug.
> >The bug comes from a data overflow, the patch below fixes it.
> >
> >
> 
> Hi,
> 
> Your patch is not correctly generated, you need to make the diff on
> top of the source tree.
> 
> Also, after reviewing the code, I think there are more places need
> to fix. Can you try my patch below?

Thanks for the review and additional fixes. See my comments below.

> 
> Thanks.
> 
> ---->
> 
> Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com>
> 
> 

> diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
> index a9f29b1..9ca9c17 100644
> --- a/fs/ecryptfs/ecryptfs_kernel.h
> +++ b/fs/ecryptfs/ecryptfs_kernel.h
> @@ -653,7 +653,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
>  			 loff_t offset, size_t size);
>  int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
>  				      struct page *page_for_lower,
> -				      size_t offset_in_page, size_t size);
> +				      loff_t offset_in_page, size_t size);
>  int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size);
>  int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
>  			struct inode *ecryptfs_inode);
> diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
> index 3745f7c..93d80c4 100644
> --- a/fs/ecryptfs/read_write.c
> +++ b/fs/ecryptfs/read_write.c
> @@ -72,7 +72,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
>   */
>  int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
>  				      struct page *page_for_lower,
> -				      size_t offset_in_page, size_t size)
> +				      loff_t offset_in_page, size_t size)

mm/filemap.c uses unsigned long for variables used to identify an offset
into a single page. That's what I'm tempted to use for offset_in_page,
rather than loff_t.

>  {
>  	char *virt;
>  	loff_t offset;
> @@ -128,15 +128,15 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
>  		pos = offset;
>  	while (pos < (offset + size)) {
>  		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
> -		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
> -		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
> -		size_t total_remaining_bytes = ((offset + size) - pos);
> +		loff_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
> +		loff_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);

unsigned long should work for start_offset_in_page and num_bytes, too.

Tyler

> +		loff_t total_remaining_bytes = ((offset + size) - pos);
>  
>  		if (num_bytes > total_remaining_bytes)
>  			num_bytes = total_remaining_bytes;
>  		if (pos < offset) {
>  			/* remaining zeros to write, up to destination offset */
> -			size_t total_remaining_zeros = (offset - pos);
> +			loff_t total_remaining_zeros = (offset - pos);
>  
>  			if (num_bytes > total_remaining_zeros)
>  				num_bytes = total_remaining_zeros;


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re:Re: [PATCH] eCryptfs: infinite loop bug
       [not found]   ` <526922120.05125@eyou.net>
@ 2012-01-19  1:44     ` Li Wang
  2012-01-19  8:48       ` Tyler Hicks
  2012-01-19  9:13       ` [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write() Tyler Hicks
  0 siblings, 2 replies; 13+ messages in thread
From: Li Wang @ 2012-01-19  1:44 UTC (permalink / raw)
  To: ecryptfs, linux-fsdevel, linux-kernel, Dustin Kirkland,
	Cong Wang, Tyler Hicks

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="GBK", Size: 2516 bytes --]



Hi,
  Thanks Cong Wang for the kind reminding regarding the patch format.
  We did notice that the total_remaining_zeroes need be revised as well, 
and the start_offset_in_page, num_bytes need not be revised (always smaller 
than PAGE_CACHE_SIZE, even the huge page size is supported, 
the 4G page size is not present in the current world?)
but we forget to include the revision for total_remaining_zeroes, so here comes the patch.

Cheers,
Li Wang

Signed-off-by: Li Wang <liwang@nudt.edu.cn>
               Yunchuan Wen <wenyunchuan@kylinos.com.cn>

---

--- a/fs/ecryptfs/read_write.c	2012-01-19 17:34:54.666940824 +0800
+++ b/fs/ecryptfs/read_write.c	2012-01-19 17:35:16.257940840 +0800
@@ -130,13 +130,13 @@ int ecryptfs_write(struct inode *ecryptf
 		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
 		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
 		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
-		size_t total_remaining_bytes = ((offset + size) - pos);
+		loff_t total_remaining_bytes = ((offset + size) - pos);
 
 		if (num_bytes > total_remaining_bytes)
 			num_bytes = total_remaining_bytes;
 		if (pos < offset) {
 			/* remaining zeros to write, up to destination offset */
-			size_t total_remaining_zeros = (offset - pos);
+			loff_t total_remaining_zeros = (offset - pos);
 
 			if (num_bytes > total_remaining_zeros)
 				num_bytes = total_remaining_zeros;





---------- Origin message ----------
>From£º"Tyler Hicks" <tyhicks@canonical.com>
>To£º"Cong Wang" <xiyou.wangcong@gmail.com>
>Subject£ºRe: [PATCH] eCryptfs: infinite loop bug
>Date£º2012-01-19 05:40:51

On 2012-01-18 23:26:52, Cong Wang wrote:
> On 01/18/2012 03:30 PM, Li Wang wrote:
> >Hi,
> > There is an infinite loop bug in eCryptfs, to make it present,
> >just truncate to generate a huge file (>= 4G) on a 32-bit machine
> >under the plain text foleder mounted with eCryptfs, a simple command
> >'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> >therefore the following command 'truncate -s 4GB dummy' will not trigger this bug.
> >The bug comes from a data overflow, the patch below fixes it.
> >
> >
>
> Hi,
>
> Your patch is not correctly generated, you need to make the diff on
> top of the source tree.
>
> Also, after reviewing the code, I think there are more places need
> to fix. Can you try my patch below?
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-18 21:40   ` Tyler Hicks
@ 2012-01-19  3:43     ` Linus Torvalds
  0 siblings, 0 replies; 13+ messages in thread
From: Linus Torvalds @ 2012-01-19  3:43 UTC (permalink / raw)
  To: Tyler Hicks
  Cc: Cong Wang, Li Wang, ecryptfs, linux-fsdevel, linux-kernel,
	Dustin Kirkland

On Wed, Jan 18, 2012 at 1:40 PM, Tyler Hicks <tyhicks@canonical.com> wrote:
>
> mm/filemap.c uses unsigned long for variables used to identify an offset
> into a single page. That's what I'm tempted to use for offset_in_page,
> rather than loff_t.

Indeed. The offset within a page will fit fine even in an "unsigned
int", and "loff_t" is crazy overkill - and usually generates horrible
code on 32-bit architectures.

                      Linus

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-19  1:44     ` Li Wang
@ 2012-01-19  8:48       ` Tyler Hicks
  2012-01-19 14:03         ` Dustin Kirkland
  2012-01-19  9:13       ` [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write() Tyler Hicks
  1 sibling, 1 reply; 13+ messages in thread
From: Tyler Hicks @ 2012-01-19  8:48 UTC (permalink / raw)
  To: Li Wang; +Cc: ecryptfs, linux-fsdevel, linux-kernel, Cong Wang

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

On 2012-01-19 09:44:36, Li Wang wrote:
> 
> 
> Hi,
>   Thanks Cong Wang for the kind reminding regarding the patch format.

The commit message still needs some work. But there's no need to drag
out the process for a fix like this, so I'll rewrite the commit message
and reply to this email with the cleaned up version. Let me know if you
have any problems with that. You'll still be credited as the author.

For future kernel patches, please see "15) The canonical patch format"
of Documentation/SubmittingPatches and "5.4: PATCH FORMATTING AND
CHANGELOGS" of Documentation/development-process/5.Posting for more
information on how the commit message should be written.

Also, your email came across in base64 encoding. I'm not sure of the
reason for that or how to fix it.

>   We did notice that the total_remaining_zeroes need be revised as well, 
> and the start_offset_in_page, num_bytes need not be revised (always smaller 

Yes, size_t will work fine, as Linus confirmed.

> than PAGE_CACHE_SIZE, even the huge page size is supported, 
> the 4G page size is not present in the current world?)
> but we forget to include the revision for total_remaining_zeroes, so here comes the patch.

I really appreciate the patch - thanks!

Tyler

> 
> Cheers,
> Li Wang
> 
> Signed-off-by: Li Wang <liwang@nudt.edu.cn>
>                Yunchuan Wen <wenyunchuan@kylinos.com.cn>
> 
> ---
> 
> --- a/fs/ecryptfs/read_write.c	2012-01-19 17:34:54.666940824 +0800
> +++ b/fs/ecryptfs/read_write.c	2012-01-19 17:35:16.257940840 +0800
> @@ -130,13 +130,13 @@ int ecryptfs_write(struct inode *ecryptf
>  		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
>  		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
>  		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
> -		size_t total_remaining_bytes = ((offset + size) - pos);
> +		loff_t total_remaining_bytes = ((offset + size) - pos);
>  
>  		if (num_bytes > total_remaining_bytes)
>  			num_bytes = total_remaining_bytes;
>  		if (pos < offset) {
>  			/* remaining zeros to write, up to destination offset */
> -			size_t total_remaining_zeros = (offset - pos);
> +			loff_t total_remaining_zeros = (offset - pos);
>  
>  			if (num_bytes > total_remaining_zeros)
>  				num_bytes = total_remaining_zeros;
> 
> 
> 
> 
> 
> ---------- Origin message ----------
> >From:"Tyler Hicks" <tyhicks@canonical.com>
> >To:"Cong Wang" <xiyou.wangcong@gmail.com>
> >Subject:Re: [PATCH] eCryptfs: infinite loop bug
> >Date:2012-01-19 05:40:51
> 
> On 2012-01-18 23:26:52, Cong Wang wrote:
> > On 01/18/2012 03:30 PM, Li Wang wrote:
> > >Hi,
> > > There is an infinite loop bug in eCryptfs, to make it present,
> > >just truncate to generate a huge file (>= 4G) on a 32-bit machine
> > >under the plain text foleder mounted with eCryptfs, a simple command
> > >'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> > >therefore the following command 'truncate -s 4GB dummy' will not trigger this bug.
> > >The bug comes from a data overflow, the patch below fixes it.
> > >
> > >
> >
> > Hi,
> >
> > Your patch is not correctly generated, you need to make the diff on
> > top of the source tree.
> >
> > Also, after reviewing the code, I think there are more places need
> > to fix. Can you try my patch below?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write()
  2012-01-19  1:44     ` Li Wang
  2012-01-19  8:48       ` Tyler Hicks
@ 2012-01-19  9:13       ` Tyler Hicks
  2012-01-19 15:09         ` Cong Wang
  1 sibling, 1 reply; 13+ messages in thread
From: Tyler Hicks @ 2012-01-19  9:13 UTC (permalink / raw)
  To: Li Wang; +Cc: ecryptfs, linux-fsdevel, linux-kernel, Cong Wang, Yunchuan Wen

From: Li Wang <liwang@nudt.edu.cn>

ecryptfs_write() can enter an infinite loop when truncating a file to a
size larger than 4G. This only happens on architectures where size_t is
represented by 32 bits.

This was caused by a size_t overflow due to it incorrectly being used to
store the result of a calculation which uses potentially large values of
type loff_t.

[tyhicks@canonical.com: rewrite subject and commit message]
Signed-off-by: Li Wang <liwang@nudt.edu.cn>
Signed-off-by: Yunchuan Wen <wenyunchuan@kylinos.com.cn>
Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
---
 fs/ecryptfs/read_write.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 3745f7c..ec3d936 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -130,13 +130,13 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
 		pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
 		size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
 		size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
-		size_t total_remaining_bytes = ((offset + size) - pos);
+		loff_t total_remaining_bytes = ((offset + size) - pos);
 
 		if (num_bytes > total_remaining_bytes)
 			num_bytes = total_remaining_bytes;
 		if (pos < offset) {
 			/* remaining zeros to write, up to destination offset */
-			size_t total_remaining_zeros = (offset - pos);
+			loff_t total_remaining_zeros = (offset - pos);
 
 			if (num_bytes > total_remaining_zeros)
 				num_bytes = total_remaining_zeros;
-- 
1.7.8.3


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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-19  8:48       ` Tyler Hicks
@ 2012-01-19 14:03         ` Dustin Kirkland
  2012-01-19 15:08           ` Tyler Hicks
  0 siblings, 1 reply; 13+ messages in thread
From: Dustin Kirkland @ 2012-01-19 14:03 UTC (permalink / raw)
  To: Tyler Hicks; +Cc: Li Wang, ecryptfs, linux-fsdevel, linux-kernel, Cong Wang

On Thu, Jan 19, 2012 at 2:48 AM, Tyler Hicks <tyhicks@canonical.com> wrote:
> On 2012-01-19 09:44:36, Li Wang wrote:
>>
>>
>> Hi,
>>   Thanks Cong Wang for the kind reminding regarding the patch format.
>
> The commit message still needs some work. But there's no need to drag
> out the process for a fix like this, so I'll rewrite the commit message
> and reply to this email with the cleaned up version. Let me know if you
> have any problems with that. You'll still be credited as the author.
>
> For future kernel patches, please see "15) The canonical patch format"
> of Documentation/SubmittingPatches and "5.4: PATCH FORMATTING AND
> CHANGELOGS" of Documentation/development-process/5.Posting for more
> information on how the commit message should be written.
>
> Also, your email came across in base64 encoding. I'm not sure of the
> reason for that or how to fix it.
>
>>   We did notice that the total_remaining_zeroes need be revised as well,
>> and the start_offset_in_page, num_bytes need not be revised (always smaller
>
> Yes, size_t will work fine, as Linus confirmed.
>
>> than PAGE_CACHE_SIZE, even the huge page size is supported,
>> the 4G page size is not present in the current world?)
>> but we forget to include the revision for total_remaining_zeroes, so here comes the patch.
>
> I really appreciate the patch - thanks!

Tyler,

Is this the problem behind our long standing
tor-download-on-ecryptfs-hangs-cpu bug?
 * https://bugs.launchpad.net/ecryptfs/+bug/431975

-- 
:-Dustin

Dustin Kirkland
Chief Architect
Gazzang, Inc.
www.gazzang.com

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-19 14:03         ` Dustin Kirkland
@ 2012-01-19 15:08           ` Tyler Hicks
  0 siblings, 0 replies; 13+ messages in thread
From: Tyler Hicks @ 2012-01-19 15:08 UTC (permalink / raw)
  To: Dustin Kirkland; +Cc: Li Wang, ecryptfs, linux-fsdevel, linux-kernel, Cong Wang

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

On 2012-01-19 08:03:57, Dustin Kirkland wrote:
> On Thu, Jan 19, 2012 at 2:48 AM, Tyler Hicks <tyhicks@canonical.com> wrote:
> > On 2012-01-19 09:44:36, Li Wang wrote:
> >>
> >>
> >> Hi,
> >>   Thanks Cong Wang for the kind reminding regarding the patch format.
> >
> > The commit message still needs some work. But there's no need to drag
> > out the process for a fix like this, so I'll rewrite the commit message
> > and reply to this email with the cleaned up version. Let me know if you
> > have any problems with that. You'll still be credited as the author.
> >
> > For future kernel patches, please see "15) The canonical patch format"
> > of Documentation/SubmittingPatches and "5.4: PATCH FORMATTING AND
> > CHANGELOGS" of Documentation/development-process/5.Posting for more
> > information on how the commit message should be written.
> >
> > Also, your email came across in base64 encoding. I'm not sure of the
> > reason for that or how to fix it.
> >
> >>   We did notice that the total_remaining_zeroes need be revised as well,
> >> and the start_offset_in_page, num_bytes need not be revised (always smaller
> >
> > Yes, size_t will work fine, as Linus confirmed.
> >
> >> than PAGE_CACHE_SIZE, even the huge page size is supported,
> >> the 4G page size is not present in the current world?)
> >> but we forget to include the revision for total_remaining_zeroes, so here comes the patch.
> >
> > I really appreciate the patch - thanks!
> 
> Tyler,
> 
> Is this the problem behind our long standing
> tor-download-on-ecryptfs-hangs-cpu bug?
>  * https://bugs.launchpad.net/ecryptfs/+bug/431975

Yes. Unfortunately, I had missed the infinite loop on i386 part, as I
was testing/developing on x86_64. 

Tyler

> 
> -- 
> :-Dustin
> 
> Dustin Kirkland
> Chief Architect
> Gazzang, Inc.
> www.gazzang.com
> --
> To unsubscribe from this list: send the line "unsubscribe ecryptfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write()
  2012-01-19  9:13       ` [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write() Tyler Hicks
@ 2012-01-19 15:09         ` Cong Wang
  0 siblings, 0 replies; 13+ messages in thread
From: Cong Wang @ 2012-01-19 15:09 UTC (permalink / raw)
  To: Tyler Hicks; +Cc: Li Wang, ecryptfs, linux-fsdevel, linux-kernel, Yunchuan Wen

On 01/19/2012 05:13 PM, Tyler Hicks wrote:
> From: Li Wang<liwang@nudt.edu.cn>
>
> ecryptfs_write() can enter an infinite loop when truncating a file to a
> size larger than 4G. This only happens on architectures where size_t is
> represented by 32 bits.
>
> This was caused by a size_t overflow due to it incorrectly being used to
> store the result of a calculation which uses potentially large values of
> type loff_t.
>
> [tyhicks@canonical.com: rewrite subject and commit message]
> Signed-off-by: Li Wang<liwang@nudt.edu.cn>
> Signed-off-by: Yunchuan Wen<wenyunchuan@kylinos.com.cn>
> Cc: Cong Wang<xiyou.wangcong@gmail.com>
> Cc:<stable@vger.kernel.org>
> Signed-off-by: Tyler Hicks<tyhicks@canonical.com>


Tyler, thanks for cleaning this up! Looks pretty good now.

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-18 20:49 ` [PATCH] eCryptfs: infinite loop bug Linus Torvalds
  2012-01-18 21:04   ` Tyler Hicks
@ 2012-01-19 16:17   ` Dustin Kirkland
  1 sibling, 0 replies; 13+ messages in thread
From: Dustin Kirkland @ 2012-01-19 16:17 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: dragonylffly, tyhicks, john.johansen, ecryptfs, linux-fsdevel,
	linux-kernel

On Wed, Jan 18, 2012 at 2:49 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> There are *two* cases where we do that "total_remaining_bytes"
> calculation. The same bug seems to exist both in ecryptfs_read() and
> ecryptfs_write().
>
> Possibly only the ecryptfs_write() one leads to an endless loop, but
> the read one looks suspicious too.
>
> Also, what protects things against this just being one nasty DoS
> attack - even if the code is fixed to not be an endless loop, it looks
> like a trivial "truncate()" can be used to generate a *practically*
> infinite write stream. At the very least, this should be KILLABLE. Or
> did I mis-read the code?
>
> Tyler, Dustin, others - comments? This looks nasty.

Definitely nasty, Linus.  This is almost certainly the source of a
long-standing bug [1] we've had with tor-downloads into eCryptfs
mounts hanging the OS.  Tor clients truncate a file at the start of
the download large enough to handle the eventual result.

Glad to see this finally triaged and a fix in the works, Li Wang and
Yunchuan Wen.  Thanks for that.

[1] https://bugs.launchpad.net/ecryptfs/+bug/431975

-- 
:-Dustin

Dustin Kirkland
Chief Architect
Gazzang, Inc.
www.gazzang.com

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

* Re: [PATCH] eCryptfs: infinite loop bug
  2012-01-18 20:49 ` [PATCH] eCryptfs: infinite loop bug Linus Torvalds
@ 2012-01-18 21:04   ` Tyler Hicks
  2012-01-19 16:17   ` Dustin Kirkland
  1 sibling, 0 replies; 13+ messages in thread
From: Tyler Hicks @ 2012-01-18 21:04 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: dragonylffly, john.johansen, dustin.kirkland, ecryptfs,
	linux-fsdevel, linux-kernel

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

On 2012-01-18 12:49:17, Linus Torvalds wrote:
> Hmm.
> 
> There are *two* cases where we do that "total_remaining_bytes"
> calculation. The same bug seems to exist both in ecryptfs_read() and
> ecryptfs_write().

ecryptfs_read() is ifdef'ed out, and has been for years, so I'll just go
ahead and kill that function for good.

> 
> Possibly only the ecryptfs_write() one leads to an endless loop, but
> the read one looks suspicious too.
> 
> Also, what protects things against this just being one nasty DoS
> attack - even if the code is fixed to not be an endless loop, it looks
> like a trivial "truncate()" can be used to generate a *practically*
> infinite write stream. At the very least, this should be KILLABLE. Or
> did I mis-read the code?

I think you're right. I'll start off with making it killable and then
see if there is anything else we can do.

Tyler

> 
> Tyler, Dustin, others - comments? This looks nasty.
> 
>                      Linus.
> 
> 2012/1/17 dragonylffly <dragonylffly@163.com>:
> > Hi,
> >   There is an infinite loop bug in eCryptfs, to make it present,
> > just truncate to generate a huge file (>= 4G) on a 32-bit machine under
> > the plain text foleder mounted with eCryptfs, a simple command
> > 'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> > therefore the following command 'truncate -s 4GB dummy' will not
> > trigger this bug. The bug comes from a data overflow, the patch below fixes
> > it.
> >
> > Cheers,
> > Li Wang
> >
> > ---
> >
> > signed-off-by: Li Wang <liwang@nudt.edu.cn>
> >                Yunchuan Wen (wenyunchuan@kylinos.com.cn)
> >
> > --- read_write.c.orig 2012-01-18 10:39:26.000000000 +0800
> > +++ read_write.c 2012-01-18 19:48:41.484196221 +0800
> > @@ -130,7 +130,7 @@
> >    pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
> >    size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
> >    size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
> > -  size_t total_remaining_bytes = ((offset + size) - pos);
> > +  loff_t total_remaining_bytes = ((offset + size) - pos);
> >
> >    if (num_bytes > total_remaining_bytes)
> >     num_bytes = total_remaining_bytes;
> >
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe ecryptfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH] eCryptfs: infinite loop bug
       [not found] <7f1e961d.f528.134efaf8348.Coremail.dragonylffly@163.com>
@ 2012-01-18 20:49 ` Linus Torvalds
  2012-01-18 21:04   ` Tyler Hicks
  2012-01-19 16:17   ` Dustin Kirkland
  0 siblings, 2 replies; 13+ messages in thread
From: Linus Torvalds @ 2012-01-18 20:49 UTC (permalink / raw)
  To: dragonylffly
  Cc: tyhicks, john.johansen, dustin.kirkland, ecryptfs, linux-fsdevel,
	linux-kernel

Hmm.

There are *two* cases where we do that "total_remaining_bytes"
calculation. The same bug seems to exist both in ecryptfs_read() and
ecryptfs_write().

Possibly only the ecryptfs_write() one leads to an endless loop, but
the read one looks suspicious too.

Also, what protects things against this just being one nasty DoS
attack - even if the code is fixed to not be an endless loop, it looks
like a trivial "truncate()" can be used to generate a *practically*
infinite write stream. At the very least, this should be KILLABLE. Or
did I mis-read the code?

Tyler, Dustin, others - comments? This looks nasty.

                     Linus.

2012/1/17 dragonylffly <dragonylffly@163.com>:
> Hi,
>   There is an infinite loop bug in eCryptfs, to make it present,
> just truncate to generate a huge file (>= 4G) on a 32-bit machine under
> the plain text foleder mounted with eCryptfs, a simple command
> 'truncate -s 4G dummy' is enough. Note: 4GB is smaller than 4G,
> therefore the following command 'truncate -s 4GB dummy' will not
> trigger this bug. The bug comes from a data overflow, the patch below fixes
> it.
>
> Cheers,
> Li Wang
>
> ---
>
> signed-off-by: Li Wang <liwang@nudt.edu.cn>
>                Yunchuan Wen (wenyunchuan@kylinos.com.cn)
>
> --- read_write.c.orig 2012-01-18 10:39:26.000000000 +0800
> +++ read_write.c 2012-01-18 19:48:41.484196221 +0800
> @@ -130,7 +130,7 @@
>    pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
>    size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
>    size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
> -  size_t total_remaining_bytes = ((offset + size) - pos);
> +  loff_t total_remaining_bytes = ((offset + size) - pos);
>
>    if (num_bytes > total_remaining_bytes)
>     num_bytes = total_remaining_bytes;
>
>
>

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

end of thread, other threads:[~2012-01-19 16:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-18  7:30 [PATCH] eCryptfs: infinite loop bug Li Wang
2012-01-18 15:26 ` Cong Wang
2012-01-18 21:40   ` Tyler Hicks
2012-01-19  3:43     ` Linus Torvalds
     [not found]   ` <526922120.05125@eyou.net>
2012-01-19  1:44     ` Li Wang
2012-01-19  8:48       ` Tyler Hicks
2012-01-19 14:03         ` Dustin Kirkland
2012-01-19 15:08           ` Tyler Hicks
2012-01-19  9:13       ` [PATCH] eCryptfs: infinite loop due to overflow in ecryptfs_write() Tyler Hicks
2012-01-19 15:09         ` Cong Wang
     [not found] <7f1e961d.f528.134efaf8348.Coremail.dragonylffly@163.com>
2012-01-18 20:49 ` [PATCH] eCryptfs: infinite loop bug Linus Torvalds
2012-01-18 21:04   ` Tyler Hicks
2012-01-19 16:17   ` Dustin Kirkland

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).