diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 15:14:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 15:14:39 -0400 |
commit | 26b55633a891a28bf04f42882de145eb8e9cb9ad (patch) | |
tree | 997c1bbaad576a0ae4903af59a8d89b86b0f2fae /fs/ecryptfs | |
parent | b34d8915c413acb51d837a45fb8747b61f65c020 (diff) | |
parent | 21edad32205e97dc7ccb81a85234c77e760364c8 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6:
ecryptfs: dont call lookup_one_len to avoid NULL nameidata
fs/ecryptfs/file.c: introduce missing free
ecryptfs: release reference to lower mount if interpose fails
eCryptfs: Handle ioctl calls with unlocked and compat functions
ecryptfs: Fix warning in ecryptfs_process_response()
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/file.c | 60 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 94 | ||||
-rw-r--r-- | fs/ecryptfs/messaging.c | 2 |
3 files changed, 118 insertions, 38 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index e8fcf4e2ed7d..622c95140802 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -199,7 +199,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
199 | "the persistent file for the dentry with name " | 199 | "the persistent file for the dentry with name " |
200 | "[%s]; rc = [%d]\n", __func__, | 200 | "[%s]; rc = [%d]\n", __func__, |
201 | ecryptfs_dentry->d_name.name, rc); | 201 | ecryptfs_dentry->d_name.name, rc); |
202 | goto out; | 202 | goto out_free; |
203 | } | 203 | } |
204 | } | 204 | } |
205 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) | 205 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) |
@@ -207,7 +207,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
207 | rc = -EPERM; | 207 | rc = -EPERM; |
208 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | 208 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " |
209 | "file must hence be opened RO\n", __func__); | 209 | "file must hence be opened RO\n", __func__); |
210 | goto out; | 210 | goto out_free; |
211 | } | 211 | } |
212 | ecryptfs_set_file_lower( | 212 | ecryptfs_set_file_lower( |
213 | file, ecryptfs_inode_to_private(inode)->lower_file); | 213 | file, ecryptfs_inode_to_private(inode)->lower_file); |
@@ -292,12 +292,40 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag) | |||
292 | return rc; | 292 | return rc; |
293 | } | 293 | } |
294 | 294 | ||
295 | static int ecryptfs_ioctl(struct inode *inode, struct file *file, | 295 | static long |
296 | unsigned int cmd, unsigned long arg); | 296 | ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
297 | { | ||
298 | struct file *lower_file = NULL; | ||
299 | long rc = -ENOTTY; | ||
300 | |||
301 | if (ecryptfs_file_to_private(file)) | ||
302 | lower_file = ecryptfs_file_to_lower(file); | ||
303 | if (lower_file && lower_file->f_op && lower_file->f_op->unlocked_ioctl) | ||
304 | rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); | ||
305 | return rc; | ||
306 | } | ||
307 | |||
308 | #ifdef CONFIG_COMPAT | ||
309 | static long | ||
310 | ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
311 | { | ||
312 | struct file *lower_file = NULL; | ||
313 | long rc = -ENOIOCTLCMD; | ||
314 | |||
315 | if (ecryptfs_file_to_private(file)) | ||
316 | lower_file = ecryptfs_file_to_lower(file); | ||
317 | if (lower_file && lower_file->f_op && lower_file->f_op->compat_ioctl) | ||
318 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); | ||
319 | return rc; | ||
320 | } | ||
321 | #endif | ||
297 | 322 | ||
298 | const struct file_operations ecryptfs_dir_fops = { | 323 | const struct file_operations ecryptfs_dir_fops = { |
299 | .readdir = ecryptfs_readdir, | 324 | .readdir = ecryptfs_readdir, |
300 | .ioctl = ecryptfs_ioctl, | 325 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, |
326 | #ifdef CONFIG_COMPAT | ||
327 | .compat_ioctl = ecryptfs_compat_ioctl, | ||
328 | #endif | ||
301 | .open = ecryptfs_open, | 329 | .open = ecryptfs_open, |
302 | .flush = ecryptfs_flush, | 330 | .flush = ecryptfs_flush, |
303 | .release = ecryptfs_release, | 331 | .release = ecryptfs_release, |
@@ -313,7 +341,10 @@ const struct file_operations ecryptfs_main_fops = { | |||
313 | .write = do_sync_write, | 341 | .write = do_sync_write, |
314 | .aio_write = generic_file_aio_write, | 342 | .aio_write = generic_file_aio_write, |
315 | .readdir = ecryptfs_readdir, | 343 | .readdir = ecryptfs_readdir, |
316 | .ioctl = ecryptfs_ioctl, | 344 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, |
345 | #ifdef CONFIG_COMPAT | ||
346 | .compat_ioctl = ecryptfs_compat_ioctl, | ||
347 | #endif | ||
317 | .mmap = generic_file_mmap, | 348 | .mmap = generic_file_mmap, |
318 | .open = ecryptfs_open, | 349 | .open = ecryptfs_open, |
319 | .flush = ecryptfs_flush, | 350 | .flush = ecryptfs_flush, |
@@ -322,20 +353,3 @@ const struct file_operations ecryptfs_main_fops = { | |||
322 | .fasync = ecryptfs_fasync, | 353 | .fasync = ecryptfs_fasync, |
323 | .splice_read = generic_file_splice_read, | 354 | .splice_read = generic_file_splice_read, |
324 | }; | 355 | }; |
325 | |||
326 | static int | ||
327 | ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
328 | unsigned long arg) | ||
329 | { | ||
330 | int rc = 0; | ||
331 | struct file *lower_file = NULL; | ||
332 | |||
333 | if (ecryptfs_file_to_private(file)) | ||
334 | lower_file = ecryptfs_file_to_lower(file); | ||
335 | if (lower_file && lower_file->f_op && lower_file->f_op->ioctl) | ||
336 | rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode), | ||
337 | lower_file, cmd, arg); | ||
338 | else | ||
339 | rc = -ENOTTY; | ||
340 | return rc; | ||
341 | } | ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 82900b063b1e..6c55113e7222 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -264,7 +264,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
264 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 264 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
265 | "to allocate ecryptfs_dentry_info struct\n", | 265 | "to allocate ecryptfs_dentry_info struct\n", |
266 | __func__); | 266 | __func__); |
267 | goto out_dput; | 267 | goto out_put; |
268 | } | 268 | } |
269 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); | 269 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); |
270 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); | 270 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); |
@@ -339,14 +339,85 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
339 | out_free_kmem: | 339 | out_free_kmem: |
340 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 340 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
341 | goto out; | 341 | goto out; |
342 | out_dput: | 342 | out_put: |
343 | dput(lower_dentry); | 343 | dput(lower_dentry); |
344 | mntput(lower_mnt); | ||
344 | d_drop(ecryptfs_dentry); | 345 | d_drop(ecryptfs_dentry); |
345 | out: | 346 | out: |
346 | return rc; | 347 | return rc; |
347 | } | 348 | } |
348 | 349 | ||
349 | /** | 350 | /** |
351 | * ecryptfs_new_lower_dentry | ||
352 | * @ename: The name of the new dentry. | ||
353 | * @lower_dir_dentry: Parent directory of the new dentry. | ||
354 | * @nd: nameidata from last lookup. | ||
355 | * | ||
356 | * Create a new dentry or get it from lower parent dir. | ||
357 | */ | ||
358 | static struct dentry * | ||
359 | ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, | ||
360 | struct nameidata *nd) | ||
361 | { | ||
362 | struct dentry *new_dentry; | ||
363 | struct dentry *tmp; | ||
364 | struct inode *lower_dir_inode; | ||
365 | |||
366 | lower_dir_inode = lower_dir_dentry->d_inode; | ||
367 | |||
368 | tmp = d_alloc(lower_dir_dentry, name); | ||
369 | if (!tmp) | ||
370 | return ERR_PTR(-ENOMEM); | ||
371 | |||
372 | mutex_lock(&lower_dir_inode->i_mutex); | ||
373 | new_dentry = lower_dir_inode->i_op->lookup(lower_dir_inode, tmp, nd); | ||
374 | mutex_unlock(&lower_dir_inode->i_mutex); | ||
375 | |||
376 | if (!new_dentry) | ||
377 | new_dentry = tmp; | ||
378 | else | ||
379 | dput(tmp); | ||
380 | |||
381 | return new_dentry; | ||
382 | } | ||
383 | |||
384 | |||
385 | /** | ||
386 | * ecryptfs_lookup_one_lower | ||
387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | ||
388 | * @lower_dir_dentry: lower parent directory | ||
389 | * | ||
390 | * Get the lower dentry from vfs. If lower dentry does not exist yet, | ||
391 | * create it. | ||
392 | */ | ||
393 | static struct dentry * | ||
394 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, | ||
395 | struct dentry *lower_dir_dentry) | ||
396 | { | ||
397 | struct nameidata nd; | ||
398 | struct vfsmount *lower_mnt; | ||
399 | struct qstr *name; | ||
400 | int err; | ||
401 | |||
402 | name = &ecryptfs_dentry->d_name; | ||
403 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | ||
404 | ecryptfs_dentry->d_parent)); | ||
405 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); | ||
406 | mntput(lower_mnt); | ||
407 | |||
408 | if (!err) { | ||
409 | /* we dont need the mount */ | ||
410 | mntput(nd.path.mnt); | ||
411 | return nd.path.dentry; | ||
412 | } | ||
413 | if (err != -ENOENT) | ||
414 | return ERR_PTR(err); | ||
415 | |||
416 | /* create a new lower dentry */ | ||
417 | return ecryptfs_new_lower_dentry(name, lower_dir_dentry, &nd); | ||
418 | } | ||
419 | |||
420 | /** | ||
350 | * ecryptfs_lookup | 421 | * ecryptfs_lookup |
351 | * @ecryptfs_dir_inode: The eCryptfs directory inode | 422 | * @ecryptfs_dir_inode: The eCryptfs directory inode |
352 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | 423 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
@@ -373,14 +444,12 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
373 | goto out_d_drop; | 444 | goto out_d_drop; |
374 | } | 445 | } |
375 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
376 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | 447 | |
377 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, | 448 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
378 | lower_dir_dentry, | 449 | lower_dir_dentry); |
379 | ecryptfs_dentry->d_name.len); | ||
380 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
381 | if (IS_ERR(lower_dentry)) { | 450 | if (IS_ERR(lower_dentry)) { |
382 | rc = PTR_ERR(lower_dentry); | 451 | rc = PTR_ERR(lower_dentry); |
383 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 452 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
384 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 453 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
385 | encrypted_and_encoded_name); | 454 | encrypted_and_encoded_name); |
386 | goto out_d_drop; | 455 | goto out_d_drop; |
@@ -402,14 +471,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
402 | "filename; rc = [%d]\n", __func__, rc); | 471 | "filename; rc = [%d]\n", __func__, rc); |
403 | goto out_d_drop; | 472 | goto out_d_drop; |
404 | } | 473 | } |
405 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | 474 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
406 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, | 475 | lower_dir_dentry); |
407 | lower_dir_dentry, | ||
408 | encrypted_and_encoded_name_size - 1); | ||
409 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
410 | if (IS_ERR(lower_dentry)) { | 476 | if (IS_ERR(lower_dentry)) { |
411 | rc = PTR_ERR(lower_dentry); | 477 | rc = PTR_ERR(lower_dentry); |
412 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 478 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
413 | "[%d] on lower_dentry = [%s]\n", __func__, rc, | 479 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
414 | encrypted_and_encoded_name); | 480 | encrypted_and_encoded_name); |
415 | goto out_d_drop; | 481 | goto out_d_drop; |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 46c4dd8dfcc3..bcb68c0cb1f0 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -274,7 +274,7 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
274 | struct user_namespace *user_ns, struct pid *pid, | 274 | struct user_namespace *user_ns, struct pid *pid, |
275 | u32 seq) | 275 | u32 seq) |
276 | { | 276 | { |
277 | struct ecryptfs_daemon *daemon; | 277 | struct ecryptfs_daemon *uninitialized_var(daemon); |
278 | struct ecryptfs_msg_ctx *msg_ctx; | 278 | struct ecryptfs_msg_ctx *msg_ctx; |
279 | size_t msg_size; | 279 | size_t msg_size; |
280 | struct nsproxy *nsproxy; | 280 | struct nsproxy *nsproxy; |