lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20120625121108.882a4319f8e4f66e074c46b2@canb.auug.org.au>
Date:	Mon, 25 Jun 2012 12:11:08 +1000
From:	Stephen Rothwell <sfr@...b.auug.org.au>
To:	Al Viro <viro@...IV.linux.org.uk>
Cc:	linux-next@...r.kernel.org, linux-kernel@...r.kernel.org,
	Pavel Shilovsky <pshilovsky@...ba.org>,
	Steve French <smfrench@...il.com>,
	<linux-cifs@...r.kernel.org>, Miklos Szeredi <mszeredi@...e.cz>
Subject: linux-next: manual merge of the vfs tree with the cifs tree

Hi Al,

Today's linux-next merge of the vfs tree got a conflict in fs/cifs/dir.c
between commit 76023fd85bfd ("CIFS: Rename Get/FreeXid and make them work
with unsigned int") from the cifs tree and commit 070ac6cd4b0a ("cifs:
implement i_op->atomic_open()") from the vfs tree.

I fixed it up (see below) and can carry the fix as necessary.

P.S. Steve. that cifs tree commit has a bad email address for you in your
Signed-off-by line and committer (Steven French <sfrench@...0smf.(none)>).
-- 
Cheers,
Stephen Rothwell                    sfr@...b.auug.org.au

diff --cc fs/cifs/dir.c
index 9d73354,a180265..0000000
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@@ -133,29 -133,40 +133,40 @@@ cifs_bp_rename_retry
  	return full_path;
  }
  
+ /*
+  * Don't allow the separator character in a path component.
+  * The VFS will not allow "/", but "\" is allowed by posix.
+  */
+ static int
+ check_name(struct dentry *direntry)
+ {
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
+ 	int i;
+ 
+ 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
+ 		for (i = 0; i < direntry->d_name.len; i++) {
+ 			if (direntry->d_name.name[i] == '\\') {
+ 				cFYI(1, "Invalid file name");
+ 				return -EINVAL;
+ 			}
+ 		}
+ 	}
+ 	return 0;
+ }
+ 
+ 
  /* Inode operations in similar order to how they appear in Linux file fs.h */
  
- int
- cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
- 		struct nameidata *nd)
+ static int cifs_do_create(struct inode *inode, struct dentry *direntry,
 -			  int xid, struct tcon_link *tlink, unsigned oflags,
++			  unsigned int xid, struct tcon_link *tlink, unsigned oflags,
+ 			  umode_t mode, __u32 *oplock, __u16 *fileHandle,
+ 			  int *created)
  {
  	int rc = -ENOENT;
- 	unsigned int xid;
  	int create_options = CREATE_NOT_DIR;
- 	__u32 oplock = 0;
- 	int oflags;
- 	/*
- 	 * BB below access is probably too much for mknod to request
- 	 *    but we have to do query and setpathinfo so requesting
- 	 *    less could fail (unless we want to request getatr and setatr
- 	 *    permissions (only).  At least for POSIX we do not have to
- 	 *    request so much.
- 	 */
- 	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
- 	__u16 fileHandle;
- 	struct cifs_sb_info *cifs_sb;
- 	struct tcon_link *tlink;
- 	struct cifs_tcon *tcon;
+ 	int desiredAccess;
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ 	struct cifs_tcon *tcon = tlink_tcon(tlink);
  	char *full_path = NULL;
  	FILE_ALL_INFO *buf = NULL;
  	struct inode *newinode = NULL;
@@@ -321,37 -355,136 +355,136 @@@ cifs_create_get_file_info
  	}
  
  cifs_create_set_dentry:
- 	if (rc == 0)
- 		d_instantiate(direntry, newinode);
- 	else
+ 	if (rc != 0) {
  		cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
+ 		goto out;
+ 	}
+ 	d_drop(direntry);
+ 	d_add(direntry, newinode);
  
- 	if (newinode && nd) {
- 		struct cifsFileInfo *pfile_info;
- 		struct file *filp;
+ 	/* ENOENT for create?  How weird... */
+ 	rc = -ENOENT;
+ 	if (!newinode) {
+ 		CIFSSMBClose(xid, tcon, *fileHandle);
+ 		goto out;
+ 	}
+ 	rc = 0;
  
- 		filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
- 		if (IS_ERR(filp)) {
- 			rc = PTR_ERR(filp);
- 			CIFSSMBClose(xid, tcon, fileHandle);
- 			goto cifs_create_out;
- 		}
+ out:
+ 	kfree(buf);
+ 	kfree(full_path);
+ 	return rc;
+ }
  
- 		pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
- 		if (pfile_info == NULL) {
- 			fput(filp);
- 			CIFSSMBClose(xid, tcon, fileHandle);
- 			rc = -ENOMEM;
- 		}
- 	} else {
+ int
+ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ 		 struct file *file, unsigned oflags, umode_t mode,
+ 		 int *opened)
+ {
+ 	int rc;
 -	int xid;
++	unsigned int xid;
+ 	struct tcon_link *tlink;
+ 	struct cifs_tcon *tcon;
+ 	__u16 fileHandle;
+ 	__u32 oplock;
+ 	struct file *filp;
+ 	struct cifsFileInfo *pfile_info;
+ 
+ 	/* Posix open is only called (at lookup time) for file create now.  For
+ 	 * opens (rather than creates), because we do not know if it is a file
+ 	 * or directory yet, and current Samba no longer allows us to do posix
+ 	 * open on dirs, we could end up wasting an open call on what turns out
+ 	 * to be a dir. For file opens, we wait to call posix open till
+ 	 * cifs_open.  It could be added to atomic_open in the future but the
+ 	 * performance tradeoff of the extra network request when EISDIR or
+ 	 * EACCES is returned would have to be weighed against the 50% reduction
+ 	 * in network traffic in the other paths.
+ 	 */
+ 	if (!(oflags & O_CREAT)) {
+ 		struct dentry *res = cifs_lookup(inode, direntry, 0);
+ 		if (IS_ERR(res))
+ 			return PTR_ERR(res);
+ 
+ 		return finish_no_open(file, res);
+ 	}
+ 
+ 	rc = check_name(direntry);
+ 	if (rc)
+ 		return rc;
+ 
 -	xid = GetXid();
++	xid = get_xid();
+ 
+ 	cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
+ 	     inode, direntry->d_name.name, direntry);
+ 
+ 	tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
+ 	filp = ERR_CAST(tlink);
+ 	if (IS_ERR(tlink))
+ 		goto free_xid;
+ 
+ 	tcon = tlink_tcon(tlink);
+ 
+ 	rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+ 			    &oplock, &fileHandle, opened);
+ 
+ 	if (rc)
+ 		goto out;
+ 
+ 	rc = finish_open(file, direntry, generic_file_open, opened);
+ 	if (rc) {
  		CIFSSMBClose(xid, tcon, fileHandle);
+ 		goto out;
  	}
  
- cifs_create_out:
- 	kfree(buf);
- 	kfree(full_path);
+ 	pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
+ 	if (pfile_info == NULL) {
+ 		CIFSSMBClose(xid, tcon, fileHandle);
+ 		fput(filp);
+ 		rc = -ENOMEM;
+ 	}
+ 
+ out:
+ 	cifs_put_tlink(tlink);
+ free_xid:
 -	FreeXid(xid);
++	free_xid(xid);
+ 	return rc;
+ }
+ 
+ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
+ 		bool excl)
+ {
+ 	int rc;
 -	int xid = GetXid();
++	int xid = get_xid();
+ 	/*
+ 	 * BB below access is probably too much for mknod to request
+ 	 *    but we have to do query and setpathinfo so requesting
+ 	 *    less could fail (unless we want to request getatr and setatr
+ 	 *    permissions (only).  At least for POSIX we do not have to
+ 	 *    request so much.
+ 	 */
+ 	unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
+ 	struct tcon_link *tlink;
+ 	__u16 fileHandle;
+ 	__u32 oplock;
+ 	int created = FILE_CREATED;
+ 
+ 	cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p",
+ 	     inode, direntry->d_name.name, direntry);
+ 
+ 	tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
+ 	rc = PTR_ERR(tlink);
+ 	if (IS_ERR(tlink))
+ 		goto free_xid;
+ 
+ 	rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+ 			    &oplock, &fileHandle, &created);
+ 	if (!rc)
+ 		CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
+ 
  	cifs_put_tlink(tlink);
+ free_xid:
 -	FreeXid(xid);
 +	free_xid(xid);
+ 
  	return rc;
  }
  
@@@ -488,22 -621,17 +621,17 @@@ mknod_out
  
  struct dentry *
  cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
- 	    struct nameidata *nd)
+ 	    unsigned int flags)
  {
 -	int xid;
 +	unsigned int xid;
  	int rc = 0; /* to get around spurious gcc warning, set to zero here */
  	struct cifs_sb_info *cifs_sb;
  	struct tcon_link *tlink;
  	struct cifs_tcon *pTcon;
- 	struct cifsFileInfo *cfile;
  	struct inode *newInode = NULL;
  	char *full_path = NULL;
- 	struct file *filp;
  
 -	xid = GetXid();
 +	xid = get_xid();
  
  	cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
  	      parent_dir_inode, direntry->d_name.name, direntry);

Content of type "application/pgp-signature" skipped

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ