HDFS-10276. HDFS should not expose path info that user has no permission to see. (Yuanbo Liu via Yongjun Zhang)

(cherry picked from commit 5ea6fd85c7)
(cherry picked from commit 3e4c7906c2)
This commit is contained in:
Yongjun Zhang 2016-05-27 10:02:02 -07:00 committed by Zhe Zhang
parent 97e4b13038
commit e6c162a394
2 changed files with 26 additions and 11 deletions

View File

@ -196,9 +196,9 @@ class FSPermissionChecker implements AccessControlEnforcer {
* Check whether exception e is due to an ancestor inode's not being * Check whether exception e is due to an ancestor inode's not being
* directory. * directory.
*/ */
private void checkAncestorType(INode[] inodes, int ancestorIndex, private void checkAncestorType(INode[] inodes, int checkedAncestorIndex,
AccessControlException e) throws AccessControlException { AccessControlException e) throws AccessControlException {
for (int i = 0; i <= ancestorIndex; i++) { for (int i = 0; i <= checkedAncestorIndex; i++) {
if (inodes[i] == null) { if (inodes[i] == null) {
break; break;
} }
@ -221,11 +221,8 @@ class FSPermissionChecker implements AccessControlEnforcer {
throws AccessControlException { throws AccessControlException {
for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null; for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
ancestorIndex--); ancestorIndex--);
try {
checkTraverse(inodeAttrs, path, ancestorIndex); checkTraverse(inodeAttrs, inodes, path, ancestorIndex);
} catch (AccessControlException e) {
checkAncestorType(inodes, ancestorIndex, e);
}
final INodeAttributes last = inodeAttrs[inodeAttrs.length - 1]; final INodeAttributes last = inodeAttrs[inodeAttrs.length - 1];
if (parentAccess != null && parentAccess.implies(FsAction.WRITE) if (parentAccess != null && parentAccess.implies(FsAction.WRITE)
@ -276,10 +273,15 @@ class FSPermissionChecker implements AccessControlEnforcer {
} }
/** Guarded by {@link FSNamesystem#readLock()} */ /** Guarded by {@link FSNamesystem#readLock()} */
private void checkTraverse(INodeAttributes[] inodes, String path, int last private void checkTraverse(INodeAttributes[] inodeAttrs, INode[] inodes,
) throws AccessControlException { String path, int last) throws AccessControlException {
for(int j = 0; j <= last; j++) { int j = 0;
check(inodes[j], path, FsAction.EXECUTE); try {
for (; j <= last; j++) {
check(inodeAttrs[j], path, FsAction.EXECUTE);
}
} catch (AccessControlException e) {
checkAncestorType(inodes, j, e);
} }
} }

View File

@ -546,6 +546,19 @@ public class TestDFSPermission {
+ "a directory, when checked on /existing_file/non_existing_name", + "a directory, when checked on /existing_file/non_existing_name",
e.getMessage().contains("is not a directory")); e.getMessage().contains("is not a directory"));
} }
rootFs.setPermission(p4, new FsPermission("600"));
try {
fs.exists(nfpath);
fail("The exists call should have failed.");
} catch (AccessControlException e) {
assertTrue("Permission denied messages must carry file path",
e.getMessage().contains(fpath.getName()));
assertFalse("Permission denied messages should not specify existing_file"
+ " is not a directory, since the user does not have permission"
+ " on /p4",
e.getMessage().contains("is not a directory"));
}
} }
/* Check if namenode performs permission checking correctly /* Check if namenode performs permission checking correctly