From 9808816c14abac3d6ef20f1435a9aad5e4cb3d1a Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Sat, 11 Jul 2009 10:36:57 +0000 Subject: [PATCH] MFS fixes: - Don't dereference NULL dir inode in advance_* (reported by Maurizio Lombardi) - Fix potential inode reference leak in fs_slink_* --- servers/mfs/open.c | 20 ++++++++++---------- servers/mfs/path.c | 13 +++++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/servers/mfs/open.c b/servers/mfs/open.c index 1317a9f3d..02bdea380 100644 --- a/servers/mfs/open.c +++ b/servers/mfs/open.c @@ -498,11 +498,6 @@ PUBLIC int fs_slink_o() caller_uid = fs_m_in.REQ_UID; caller_gid = fs_m_in.REQ_GID; - /* Temporarily open the dir. */ - if ( (ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) { - return(EINVAL); - } - /* Copy the link name's last component */ len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)); r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, @@ -510,6 +505,11 @@ PUBLIC int fs_slink_o() if (r != OK) return r; MFS_NUL(string, len, sizeof(string)); + /* Temporarily open the dir. */ + if ( (ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) { + return(EINVAL); + } + /* Create the inode for the symlink. */ sip = new_node_o(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES), (zone_t) 0); @@ -578,11 +578,6 @@ PUBLIC int fs_slink_s() fs_m_in.REQ_INODE_NR, fs_dev); #endif - /* Temporarily open the dir. */ - if ( (ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) { - return(EINVAL); - } - /* Copy the link name's last component */ len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)); r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0, @@ -590,6 +585,11 @@ PUBLIC int fs_slink_s() if (r != OK) return r; MFS_NUL(string, len, sizeof(string)); + /* Temporarily open the dir. */ + if ( (ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) { + return(EINVAL); + } + /* Create the inode for the symlink. */ sip = new_node_s(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES), (zone_t) 0); diff --git a/servers/mfs/path.c b/servers/mfs/path.c index 22bdb1b7a..d49765f50 100644 --- a/servers/mfs/path.c +++ b/servers/mfs/path.c @@ -770,12 +770,13 @@ char string[NAME_MAX]; /* component name to look for */ dirp = *pdirp; - /* If 'string' is empty, yield same inode straight away. */ - if (string[0] == '\0') { return(get_inode(dirp->i_dev, (int) dirp->i_num)); } - /* Check for NIL_INODE. */ if (dirp == NIL_INODE) { return(NIL_INODE); } + /* If 'string' is empty, yield same inode straight away. */ + /* This code won't trigger anymore with the current VFS path lookup logic. */ + if (string[0] == '\0') { return(get_inode(dirp->i_dev, (int) dirp->i_num)); } + /* If 'string' is not present in the directory, signal error. */ if ( (r = search_dir_nocheck(dirp, string, &numb, LOOK_UP)) != OK) { err_code = r; @@ -866,12 +867,12 @@ char string[NAME_MAX]; /* component name to look for */ dirp = *pdirp; - /* If 'string' is empty, yield same inode straight away. */ - if (string[0] == '\0') { return(get_inode(dirp->i_dev, (int) dirp->i_num)); } - /* Check for NIL_INODE. */ if (dirp == NIL_INODE) { return(NIL_INODE); } + /* If 'string' is empty, yield same inode straight away. */ + if (string[0] == '\0') { return(get_inode(dirp->i_dev, (int) dirp->i_num)); } + /* If 'string' is not present in the directory, signal error. */ if ( (r = search_dir(dirp, string, &numb, LOOK_UP)) != OK) { err_code = r; -- 2.44.0