linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Li Wang <liwang@nudt.edu.cn>
Cc: Tyler Hicks <tyhicks@canonical.com>,
	ecryptfs@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jan Kara <jack@suse.cz>, Yong Peng <pengyong@kylinos.com.cn>
Subject: Re: [PATCH] eCryptfs: Quota check incorrectly ignored
Date: Fri, 10 Feb 2012 11:31:30 +0100	[thread overview]
Message-ID: <20120210103130.GD10509@quack.suse.cz> (raw)
In-Reply-To: <1328787572-2030-1-git-send-email-liwang@nudt.edu.cn>

On Thu 09-02-12 19:39:32, Li Wang wrote:
> eCryptfs recently modified the write path to perform encryption
> and write down in ecryptfs_writepage(). This function invokes vfs_write()
> to write down the encrypted data to lower page cache. vfs_write() will
> first make sure this write will not exceed the quota limit for the owner
> of the file being written into, if quota is supported by 
> the underlying file system, and it is turned on. Normally, it accomplishs
> this job by calling check_idq()/check_bdq() (fs/quota/dquot.c). When system
> dirty ratio is not high, ecryptfs_writepage() is normally invoked by the 
> write back kernel thread, who has the capability CAP_SYS_RESOURCE, 
> this priority will let check_idq()/check_bdq() directly bypass the quota
> check. This sometimes makes data safely written into the disk in spite of
> exceeding the quota limit.
> 
> This patch temporarily removes the CAP_SYS_RESOURCE capability from the kernel
> thread before invoking vfs_write_lower(), to let it undergo quota check by
> the lower file system, if necessary. After that, reassign the capability.
  Hmm, but then the error will just be thrown away by the flusher thread
and the application never learns about it? That doesn't sound like a good
solution.

								Honza


> 
> Signed-off-by: Li Wang <liwang@nudt.edu.cn>
> Singed-off-by: Yong Peng <pengyong@kylinos.com.cn>
> ---
> 
> To repeat this bug, 
> 	mount -o usrquota /dev/sda3 /tmp
> 	cd /tmp
> 	edquota -u foo // set the disk quota limit for user foo be m1 bytes
> 	quotaon -a
> 	mount -t ecryptfs cipher plain
> 
> 	login the system as user foo
> 	cd /tmp/plain
> 	execute the following simple program
> 	
> 	int main()
> 	{
> 		char buf[m2]; // m2>m1
> 		FILE *f = fopen("dummy", "w");
> 		fwrite(buf, 1, m2, f);
> 		sleep(60); // let the kernel thread do the write back job
> 		fclose(f);
> 		return 0;
> 	}
> 	
> 	This program can write as much of data as it wants, provided sleep enough long time before closing the file.
> 
>  fs/ecryptfs/crypto.c |   27 +++++++++++++++++++++++++++
>  1 files changed, 27 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
> index 63ab245..2c1da29 100644
> --- a/fs/ecryptfs/crypto.c
> +++ b/fs/ecryptfs/crypto.c
> @@ -457,6 +457,7 @@ int ecryptfs_encrypt_page(struct page *page)
>  	struct page *enc_extent_page = NULL;
>  	loff_t extent_offset;
>  	int rc = 0;
> +	struct cred *cred;
>  
>  	ecryptfs_inode = page->mapping->host;
>  	crypt_stat =
> @@ -487,8 +488,34 @@ int ecryptfs_encrypt_page(struct page *page)
>  				   * (PAGE_CACHE_SIZE
>  				      / crypt_stat->extent_size))
>  				  + extent_offset), crypt_stat);
> +		if (current->flags & PF_KTHREAD) {
> +			/*
> +                         * Temporarily remove the CAP_SYS_RESOURCE capability
> +                         * from the write back kernel thread to let it undergo
> +                         * quota check by the lower file system
> +                         */
> +			cred = prepare_creds();
> +			if (unlikely(!cred)) {
> +				rc = -ENOMEM;
> +				goto out;
> +			}
> +			cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
> +			commit_creds(cred);
> +		}
>  		rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
>  					  offset, crypt_stat->extent_size);
> +		if (current->flags & PF_KTHREAD) {
> +			/*
> +                         * Reassign the CAP_SYS_RESOURCE capability
> +                         */
> +			cred = prepare_creds();
> +			if (unlikely(!cred)) {
> +				rc = -ENOMEM;
> +				goto out;
> +			}
> +			cap_raise(cred->cap_effective, CAP_SYS_RESOURCE);
> +			commit_creds(cred);
> +		}
>  		if (rc < 0) {
>  			ecryptfs_printk(KERN_ERR, "Error attempting "
>  					"to write lower page; rc = [%d]"
> -- 
> 1.7.6.5
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

  parent reply	other threads:[~2012-02-10 10:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1328787572-2030-1-git-send-email-liwang@nudt.edu.cn>
2012-02-09 11:39 ` [PATCH] eCryptfs: Quota check incorrectly ignored Li Wang
2012-02-10 10:31 ` Jan Kara [this message]
     [not found] ` <528868922.02520@eyou.net>
     [not found]   ` <000001cce802$709bf770$51d3e650$@edu.cn>
2012-02-10 14:44     ` Li Wang
2012-02-10 19:31     ` 'Tyler Hicks'
2012-02-10 19:41       ` 'Tyler Hicks'
2012-02-10 22:58         ` Fwd: " Tyler Hicks
     [not found]         ` <528913714.17261@eyou.net>
     [not found]           ` <003e01ccea31$6e381cd0$4aa85670$@edu.cn>
2012-02-13  9:25             ` Li Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120210103130.GD10509@quack.suse.cz \
    --to=jack@suse.cz \
    --cc=ecryptfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liwang@nudt.edu.cn \
    --cc=pengyong@kylinos.com.cn \
    --cc=tyhicks@canonical.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).