]> arthur.barton.de Git - netatalk.git/commitdiff
Use ostat in the dircache
authorRalph Boehme <sloowfranklin@gmail.com>
Tue, 26 Mar 2013 05:58:44 +0000 (06:58 +0100)
committerRalph Boehme <sloowfranklin@gmail.com>
Wed, 10 Apr 2013 13:41:27 +0000 (15:41 +0200)
Fixes a possible crash in cname() where cname_mtouname calls
dirlookup() where the curdir is freed because the dircache
detected a dev/inode cache difference and evicted the object
from the cache.

Fixes bug #498.

NEWS
etc/afpd/dircache.c
etc/afpd/directory.c

diff --git a/NEWS b/NEWS
index a1c3cedf5d7b73d5066872aad4ad72459138c69a..deb2bc84e194a150f63da82c4bf5454d88ac850d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,11 @@ Changes in 3.0.4
                 true/yes setting. This is the default.
        mode   = map ACLs to Finder UARights and UNIX mode
        From FR #73.
-    
+* FIX: Fix a possible crash in cname() where cname_mtouname calls
+       dirlookup() where the curdir is freed because the dircache
+       detected a dev/inode cache difference and evicted the object
+       from the cache. Fixes bug #498.
+
 Changes in 3.0.3
 ================
 * UPD: afpd: Increase default DSI server quantum to 1 MB
index 37af45fa71ce9bf5fbc9d60e77da9033e4d464fa..c145616b314887ea15bcdc7b0327ae9d3b7e1cb7 100644 (file)
@@ -324,7 +324,7 @@ struct dir *dircache_search_by_did(const struct vol *vol, cnid_t cnid)
             return NULL;        /* (1b) */
 
         }
-        if (lstat(cfrombstr(cdir->d_fullpath), &st) != 0) {
+        if (ostat(cfrombstr(cdir->d_fullpath), &st, vol_syml_opt(vol)) != 0) {
             LOG(log_debug, logtype_afpd, "dircache(cnid:%u): {missing:\"%s\"}",
                 ntohl(cnid), cfrombstr(cdir->d_fullpath));
             (void)dir_remove(vol, cdir);
@@ -394,7 +394,7 @@ struct dir *dircache_search_by_name(const struct vol *vol,
     }
 
     if (cdir) {
-        if (lstat(cfrombstr(cdir->d_fullpath), &st) != 0) {
+        if (ostat(cfrombstr(cdir->d_fullpath), &st, vol_syml_opt(vol)) != 0) {
             LOG(log_debug, logtype_afpd, "dircache(did:%u,\"%s\"): {missing:\"%s\"}",
                 ntohl(dir->d_did), name, cfrombstr(cdir->d_fullpath));
             (void)dir_remove(vol, cdir);
index d58023e2ac6e9b40408f1b869363206738dcbcbd..122dfdf59a3fd096001d68182b908e08b7925bbc 100644 (file)
@@ -301,7 +301,7 @@ static int set_dir_errors(struct path *path, const char *where, int err)
  *
  * @note If the passed ret->m_name is mangled, we'll demangle it
  */
-static int cname_mtouname(const struct vol *vol, const struct dir *dir, struct path *ret, int toUTF8)
+static int cname_mtouname(const struct vol *vol, struct dir *dir, struct path *ret, int toUTF8)
 {
     static char temp[ MAXPATHLEN + 1];
     char *t;
@@ -331,6 +331,12 @@ static int cname_mtouname(const struct vol *vol, const struct dir *dir, struct p
 
         /* check for OS X mangled filename :( */
         t = demangle_osx(vol, ret->m_name, dir->d_did, &fileid);
+
+        if (curdir == NULL) {
+            /* demangle_osx() calls dirlookup() which might have clobbered curdir */
+            movecwd(vol, dir);
+        }
+
         LOG(log_maxdebug, logtype_afpd, "cname_mtouname('%s',did:%u) {demangled:'%s', fileid:%u}",
             ret->m_name, ntohl(dir->d_did), t, ntohl(fileid));