diff --git a/mp4-LSM/mp4.c b/mp4-LSM/mp4.c
index 10e88847c319bfda832d778abbbd256140d5ca63..d9c9183529efe49c95f189822adc60480f0ff893 100755
--- a/mp4-LSM/mp4.c
+++ b/mp4-LSM/mp4.c
@@ -10,7 +10,7 @@
 #include "mp4_given.h"
 
 typedef struct mp4_security mp4_security_t;
-#define XATTR_LEN 32
+#define XATTR_LEN 64
 #define PATH_BUF 512
 /**
  * get_inode_sid - Get the inode mp4 security label id
@@ -26,7 +26,7 @@ static int get_inode_sid(struct inode *inode)
 	 * Add your code here
 	 * ...
 	 */
-	char *buf;
+	/*char *buf;
 	struct dentry *dentry;
 
 	int rc;
@@ -41,17 +41,17 @@ static int get_inode_sid(struct inode *inode)
 
 	if(!(inode->i_op->getxattr)){
 		// not impletment handler
-		if(printk_ratelimit()){
-			pr_alert("input inode structure does not impletment getxattr\n");
-		}
+		//if(printk_ratelimit()){
+			//pr_alert("input inode structure does not impletment getxattr\n");
+		//}
 		return MP4_NO_ACCESS;
 	}
 
 	dentry = d_find_alias(inode);
 	if(!dentry){
-		if(printk_ratelimit()){
-			pr_alert("cannot find dentry for inode at get_inode_sid\n");
-		}
+		//if(printk_ratelimit()){
+			//pr_alert("cannot find dentry for inode at get_inode_sid\n");
+		//}
 		return -1;
 	}
 
@@ -73,7 +73,68 @@ static int get_inode_sid(struct inode *inode)
 		xattr_cred = __cred_ctx_to_sid(buf);
 	}
 	kfree(buf);
-	return xattr_cred;
+	return xattr_cred;*/
+	char * cred_ctx;
+	struct dentry *de = d_find_alias(inode);
+	int ret, sid, len;
+
+	if (!de) {
+		pr_err("%s, NULL dentry\n", __func__);
+		return -EFAULT;
+	}
+
+	len = XATTR_LEN;
+	cred_ctx = kmalloc(len, GFP_NOFS);
+	if (!cred_ctx) {
+		dput(de);
+		pr_err("%s, could not allocate mem\n", __func__);
+		return -ENOMEM;
+	}
+	// Clean the momory 
+	memset(cred_ctx, 0, len);
+
+	if (!inode->i_op->getxattr) {
+		dput(de);
+		kfree(cred_ctx);
+		return 0;
+	}
+
+	ret = inode->i_op->getxattr(de, XATTR_NAME_MP4, cred_ctx, len);
+
+	if (ret == -ERANGE) {
+	    ret = inode->i_op->getxattr(de, XATTR_NAME_MP4, NULL, 0);
+	    if (ret < 0) {
+		dput(de);
+		pr_err("%s, query the correct size of xattr failed", __func__);
+		return ret;
+	    }
+
+	    len = ret;
+	    cred_ctx = kmalloc(len + 1, GFP_NOFS);
+	    if (!cred_ctx) {
+		dput(de);
+		return -ENOMEM;
+	    }
+	    cred_ctx[len] = 0;
+	    ret = inode->i_op->getxattr(de, XATTR_NAME_MP4, cred_ctx, len);
+	}
+
+	dput(de);
+
+	if (ret < 0) {
+	    if (ret != -ENODATA) {
+		pr_err("%s, get the xattr failed\n", __func__);
+		kfree(cred_ctx);
+		return ret;
+	    }
+
+	} else {
+	    sid = __cred_ctx_to_sid(cred_ctx);
+	    ret = sid;
+	}
+
+	kfree(cred_ctx);
+	return ret;
 }
 
 /**
@@ -292,12 +353,9 @@ static int mp4_inode_init_security(struct inode *inode, struct inode *dir,
  * returns 0 is access granter, -EACCES otherwise
  *
  */
+/*
 static int mp4_has_permission(int ssid, int osid, int mask)
 {
-	/*
-	 * Add your code here
-	 * ...
-	 */
 	int rc = -1;
 	if(osid == MP4_TARGET_SID){
 		// object file is labeled
@@ -422,7 +480,7 @@ static int mp4_has_permission(int ssid, int osid, int mask)
 		}
 	}
 	return rc;
-}
+}*/
 
 /**
  * mp4_inode_permission - Check permission for an inode being opened
@@ -435,12 +493,10 @@ static int mp4_has_permission(int ssid, int osid, int mask)
  * returns 0 if access is granted, -EACCES otherwise
  *
  */
+/*
 static int mp4_inode_permission(struct inode *inode, int mask)
 {
-	/*
-	 * Add your code here
-	 * ...
-	 */
+
 	const struct mp4_security *cur_sec;
 	struct dentry *dentry;
 	char* buf;
@@ -509,6 +565,171 @@ static int mp4_inode_permission(struct inode *inode, int mask)
 	    return -EACCES;
 	}
 
+	return 0;
+}*/
+
+static int mp4_has_permission(int ssid, int osid, int mask)
+{
+	/*
+	 * Add your code here
+	 * ...
+	 */
+    	
+    	// If there are no masks about the MAY_READ/MAY_WRITE/MAY_ACCESS/MAY_EXEC
+	// pass the permission control to the Linux default access control
+	mask &= (MAY_READ|MAY_WRITE|MAY_APPEND|MAY_ACCESS|MAY_EXEC);
+	if (!mask)
+            goto PERMIT;
+    	
+    	switch(osid) {
+	    // May not be accessed by target, but may be any others
+	    // So if the ssid is target, just deny
+	    case MP4_NO_ACCESS:
+		if (ssid == MP4_TARGET_SID)
+		    goto DENY;
+		else 
+		    goto PERMIT;
+	    // May only be read by anyone
+	    case MP4_READ_OBJ:
+		if ((mask & (MAY_READ)) == mask)
+		    goto PERMIT;
+		else 
+		    goto DENY;
+	    // May be read/write/append by target 
+	    // and read by others
+	    case MP4_READ_WRITE:
+		if (ssid == MP4_TARGET_SID)
+		    if ((mask & (MAY_READ | MAY_WRITE | MAY_APPEND)) == mask)
+			goto PERMIT;
+		    else
+			goto DENY;
+		else 
+		    if ((mask & (MAY_READ)) == mask)
+			goto PERMIT;
+		    else 
+			goto DENY;
+	    // May be written/appended by target
+	    // and only read by others
+	    case MP4_WRITE_OBJ:
+		if (ssid == MP4_TARGET_SID)
+		    if ((mask & (MAY_WRITE | MAY_APPEND)) == mask)
+			goto PERMIT;
+		    else 
+			goto DENY;
+		else
+		    if ((mask & (MAY_READ)) == mask)
+			goto PERMIT;
+		    else 
+			goto DENY;
+	    // May be read/executed by all
+	    case MP4_EXEC_OBJ:
+		if ((mask & (MAY_READ | MAY_EXEC)) == mask)
+		    goto PERMIT;
+		else
+		    goto DENY;
+	    // May be read/exec/access by all
+	    case MP4_READ_DIR:
+		if (ssid == MP4_TARGET_SID)
+		    if ((mask & (MAY_READ | MAY_EXEC | MAY_ACCESS)) == mask)
+			goto PERMIT;
+		    else 
+			goto DENY;
+		else 
+		    goto PERMIT;
+	    // May be modified by all, so just permit
+	    case MP4_RW_DIR:
+		if (ssid == MP4_TARGET_SID)
+                    goto PERMIT;
+		else 
+		    goto PERMIT;
+	}
+PERMIT:
+	return 0;
+DENY:
+	return -EACCES;
+}
+
+/**
+ * mp4_inode_permission - Check permission for an inode being opened
+ *
+ * @inode: the inode in question
+ * @mask: the access requested
+ *
+ * This is the important access check hook
+ *
+ * returns 0 if access is granted, -EACCES otherwise
+ *
+ */
+static int mp4_inode_permission(struct inode *inode, int mask)
+{
+	/*
+	 * Add your code here
+	 * ...
+	 */
+    	struct dentry *de;
+	const struct cred *cur_cred = current_cred();
+	struct mp4_security *mp4_ctx;
+	char *res, *buf;
+	int osid, ssid;
+
+    	if (!inode)
+	    return 0;
+
+	// Find the dentry from inode
+	de = d_find_alias(inode);
+	if (!de)
+	    return 0;
+
+	buf = kzalloc(255 * sizeof(char), GFP_KERNEL);
+	if (!buf) {
+	    dput(de);
+	    return 0;
+	}
+
+	// Get the dentry corresponding path
+	res = dentry_path_raw(de, buf, 255);
+	if (IS_ERR(res)) {
+	    pr_err("%s, could not find path\n", __func__);
+	    kfree(buf);
+	    dput(de);
+	    return 0;
+	}
+
+	// Skip the pathes which has the prefixes described in helper func
+	if (mp4_should_skip_path(res)) {
+	    kfree(buf);
+	    dput(de);
+	    return 0;
+	}
+
+	// Get the object sid
+	osid = get_inode_sid(inode);
+	if (osid < 0) {
+	    /*pr_err("%s, could not get osid\n", __func__);*/
+	    osid = MP4_NO_ACCESS;
+	}
+
+	kfree(buf);
+	dput(de);
+
+	// Check the current task credential
+	if (!cur_cred) 
+	    return 0;
+
+	// Get the sid of the current task
+	ssid = MP4_NO_ACCESS;
+	mp4_ctx = cur_cred->security;
+	if (mp4_ctx) 
+	    ssid = mp4_ctx->mp4_flags;
+
+	/*pr_info("%s, ssid %d, osid %d\n", res, ssid, osid);*/
+
+	// Check the permissions
+	if (mp4_has_permission(ssid, osid, mask)) {
+	    pr_info("%s, DENY: ssid %d, osid %d, mask 0x%x\n", res, ssid, osid, mask);
+	    return -EACCES;
+	}
+
 	return 0;
 }