The Samba-Bugzilla – Attachment 3934 Details for
Bug 5861
kernel BUG at fs/cifs/cifs_dfs_ref.c:305!
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Fix for DFS oops
0001--CIFS-Prevent-OOPs-when-mounting-with-remote-prefix(4).patch (text/x-diff), 4.22 KB, created by
Steve French
on 2009-02-10 13:19:46 UTC
(
hide
)
Description:
Fix for DFS oops
Filename:
MIME Type:
Creator:
Steve French
Created:
2009-02-10 13:19:46 UTC
Size:
4.22 KB
patch
obsolete
>From 9b8119cb1ed2bed648e0b3b0d5c856813a52781b Mon Sep 17 00:00:00 2001 >From: Igor Mammedov <niallain@gmail.com> >Date: Tue, 10 Feb 2009 14:10:26 +0300 >Subject: [PATCH] [CIFS] Prevent OOPs when mounting with remote prefixpath. > Fixes OOPs with message 'kernel BUG at fs/cifs/cifs_dfs_ref.c:274!'. > Checks if the prefixpath in an accesible while we are still in cifs_mount > and fails with reporting a error if we can't access the prefixpath > >Signed-off-by: Igor Mammedov <niallain@gmail.com> >--- > fs/cifs/cifsproto.h | 1 + > fs/cifs/connect.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ > fs/cifs/inode.c | 4 ++-- > 3 files changed, 48 insertions(+), 2 deletions(-) > >diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >index 382ba62..ec9f9c1 100644 >--- a/fs/cifs/cifsproto.h >+++ b/fs/cifs/cifsproto.h >@@ -42,6 +42,7 @@ extern void _FreeXid(unsigned int); > #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); > #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} > extern char *build_path_from_dentry(struct dentry *); >+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); > extern char *build_wildcard_path_from_dentry(struct dentry *direntry); > /* extern void renew_parental_timestamps(struct dentry *direntry);*/ > extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, >diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c >index 005df85..da0f4ff 100644 >--- a/fs/cifs/connect.c >+++ b/fs/cifs/connect.c >@@ -2180,6 +2180,33 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, > "mount option supported")); > } > >+static int >+is_path_accessible(int xid, struct cifsTconInfo *tcon, >+ struct cifs_sb_info *cifs_sb, const char *full_path) >+{ >+ int rc; >+ __u64 inode_num; >+ FILE_ALL_INFO *pfile_info; >+ >+ rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, >+ cifs_sb->local_nls, >+ cifs_sb->mnt_cifs_flags & >+ CIFS_MOUNT_MAP_SPECIAL_CHR); >+ if (rc != -EOPNOTSUPP) >+ return rc; >+ >+ pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); >+ if (pfile_info == NULL) >+ return -ENOMEM; >+ >+ rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, >+ 0 /* not legacy */, cifs_sb->local_nls, >+ cifs_sb->mnt_cifs_flags & >+ CIFS_MOUNT_MAP_SPECIAL_CHR); >+ kfree(pfile_info); >+ return rc; >+} >+ > int > cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, > char *mount_data, const char *devname) >@@ -2190,6 +2217,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, > struct cifsSesInfo *pSesInfo = NULL; > struct cifsTconInfo *tcon = NULL; > struct TCP_Server_Info *srvTcp = NULL; >+ char *full_path; > > xid = GetXid(); > >@@ -2426,6 +2454,23 @@ mount_fail_check: > cifs_sb->rsize = min(cifs_sb->rsize, > (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); > >+ if (!rc && cifs_sb->prepathlen) { >+ /* build_path_to_root works only when we have a valid tcon */ >+ full_path = cifs_build_path_to_root(cifs_sb); >+ if (full_path == NULL) { >+ rc = -ENOMEM; >+ goto mount_fail_check; >+ } >+ rc = is_path_accessible(xid, tcon, cifs_sb, full_path); >+ if (rc) { >+ cERROR(1, ("Path %s in not accessible: %d", >+ full_path, rc)); >+ kfree(full_path); >+ goto mount_fail_check; >+ } >+ kfree(full_path); >+ } >+ > /* volume_info->password is freed above when existing session found > (in which case it is not needed anymore) but when new sesion is created > the password ptr is put in the new session structure (in which case the >diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c >index bcf7b51..7342bfb 100644 >--- a/fs/cifs/inode.c >+++ b/fs/cifs/inode.c >@@ -621,7 +621,7 @@ static const struct inode_operations cifs_ipc_inode_ops = { > .lookup = cifs_lookup, > }; > >-static char *build_path_to_root(struct cifs_sb_info *cifs_sb) >+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) > { > int pplen = cifs_sb->prepathlen; > int dfsplen; >@@ -678,7 +678,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) > return inode; > > cifs_sb = CIFS_SB(inode->i_sb); >- full_path = build_path_to_root(cifs_sb); >+ full_path = cifs_build_path_to_root(cifs_sb); > if (full_path == NULL) > return ERR_PTR(-ENOMEM); > >-- >1.6.0.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 5861
: 3934