| 
					
				 | 
			
			
				@@ -321,6 +321,12 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* DEP 3/3/17: Properly handle an unlinked directory */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (hdl->dentry->state & DENTRY_NEGATIVE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -ENOENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* we are grabbing the lock because the handle content is actually 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        updated */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     lock(hdl->lock); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -370,7 +376,9 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while (dirhdl->ptr && *dirhdl->ptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         dent = *dirhdl->ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /* DEP 3/3/17: We need to filter negative dentries */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(dent->state & DENTRY_NEGATIVE)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         put_dentry(dent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         *(dirhdl->ptr++) = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -380,6 +388,11 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = bytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * hold anything */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (bytes == 0 && ((dirhdl->ptr && *dirhdl->ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       || dirhdl->dotdot || dirhdl->dot)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     unlock(hdl->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     put_handle(hdl); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -399,6 +412,12 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* DEP 3/3/17: Properly handle an unlinked directory */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (hdl->dentry->state & DENTRY_NEGATIVE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -ENOENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     lock(hdl->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     struct shim_dir_handle * dirhdl = &hdl->info.dir; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -439,7 +458,9 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while (dirhdl->ptr && *dirhdl->ptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         dent = *dirhdl->ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /* DEP 3/3/17: We need to filter negative dentries */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(dent->state & DENTRY_NEGATIVE)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         put_dentry(dent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         *(dirhdl->ptr++) = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -449,6 +470,11 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ret = bytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * hold anything */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (bytes == 0 && ((dirhdl->ptr && *dirhdl->ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       || dirhdl->dotdot || dirhdl->dot)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     unlock(hdl->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     put_handle(hdl); 
			 |