*     audit_rule_init.
  *     @rule contains the allocated rule
  *
+ * @inode_invalidate_secctx:
+ *     Notify the security module that it must revalidate the security context
+ *     of an inode.
+ *
  * @inode_notifysecctx:
  *     Notify the security module of what the security context of an inode
  *     should be.  Initializes the incore security context managed by the
        int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid);
        void (*release_secctx)(char *secdata, u32 seclen);
 
+       void (*inode_invalidate_secctx)(struct inode *inode);
        int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
        int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
        int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
        struct list_head secid_to_secctx;
        struct list_head secctx_to_secid;
        struct list_head release_secctx;
+       struct list_head inode_invalidate_secctx;
        struct list_head inode_notifysecctx;
        struct list_head inode_setsecctx;
        struct list_head inode_getsecctx;
 
 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 
+void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 {
 }
 
+static inline void security_inode_invalidate_secctx(struct inode *inode)
+{
+}
+
 static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
 {
        return -EOPNOTSUPP;
 
 }
 EXPORT_SYMBOL(security_release_secctx);
 
+void security_inode_invalidate_secctx(struct inode *inode)
+{
+       call_void_hook(inode_invalidate_secctx, inode);
+}
+EXPORT_SYMBOL(security_inode_invalidate_secctx);
+
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
 {
        return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen);
                LIST_HEAD_INIT(security_hook_heads.secctx_to_secid),
        .release_secctx =
                LIST_HEAD_INIT(security_hook_heads.release_secctx),
+       .inode_invalidate_secctx =
+               LIST_HEAD_INIT(security_hook_heads.inode_invalidate_secctx),
        .inode_notifysecctx =
                LIST_HEAD_INIT(security_hook_heads.inode_notifysecctx),
        .inode_setsecctx =
 
                        goto out;
 
                root_isec->sid = rootcontext_sid;
-               root_isec->initialized = 1;
+               root_isec->initialized = LABEL_INITIALIZED;
        }
 
        if (defcontext_sid) {
        unsigned len = 0;
        int rc = 0;
 
-       if (isec->initialized)
+       if (isec->initialized == LABEL_INITIALIZED)
                goto out;
 
        mutex_lock(&isec->lock);
-       if (isec->initialized)
+       if (isec->initialized == LABEL_INITIALIZED)
                goto out_unlock;
 
        sbsec = inode->i_sb->s_security;
                break;
        }
 
-       isec->initialized = 1;
+       isec->initialized = LABEL_INITIALIZED;
 
 out_unlock:
        mutex_unlock(&isec->lock);
                struct inode_security_struct *isec = inode->i_security;
                isec->sclass = inode_mode_to_security_class(inode->i_mode);
                isec->sid = newsid;
-               isec->initialized = 1;
+               isec->initialized = LABEL_INITIALIZED;
        }
 
        if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
 
        isec->sclass = inode_mode_to_security_class(inode->i_mode);
        isec->sid = newsid;
-       isec->initialized = 1;
+       isec->initialized = LABEL_INITIALIZED;
 
        return;
 }
 
        isec->sclass = inode_mode_to_security_class(inode->i_mode);
        isec->sid = newsid;
-       isec->initialized = 1;
+       isec->initialized = LABEL_INITIALIZED;
        return 0;
 }
 
        u32 sid = task_sid(p);
 
        isec->sid = sid;
-       isec->initialized = 1;
+       isec->initialized = LABEL_INITIALIZED;
 }
 
 /* Returns error only if unable to parse addresses */
                        return err;
        }
 
-       isec->initialized = 1;
+       isec->initialized = LABEL_INITIALIZED;
 
        if (sock->sk) {
                sksec = sock->sk->sk_security;
        isec = inode_security(SOCK_INODE(sock));
        newisec->sclass = isec->sclass;
        newisec->sid = isec->sid;
-       newisec->initialized = 1;
+       newisec->initialized = LABEL_INITIALIZED;
 
        return 0;
 }
        kfree(secdata);
 }
 
+static void selinux_inode_invalidate_secctx(struct inode *inode)
+{
+       struct inode_security_struct *isec = inode->i_security;
+
+       mutex_lock(&isec->lock);
+       isec->initialized = LABEL_INVALID;
+       mutex_unlock(&isec->lock);
+}
+
 /*
  *     called with inode->i_mutex locked
  */
        LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
        LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
        LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
+       LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
        LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
        LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
        LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
 
        u32 sockcreate_sid;     /* fscreate SID */
 };
 
+enum label_initialized {
+       LABEL_MISSING,          /* not initialized */
+       LABEL_INITIALIZED,      /* inizialized */
+       LABEL_INVALID           /* invalid */
+};
+
 struct inode_security_struct {
        struct inode *inode;    /* back pointer to inode object */
        union {