diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/auditsc.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 132dbcdef6ec..4f521964ccaa 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -1846,6 +1846,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
| 1846 | /* The struct filename _must_ have a populated ->name */ | 1846 | /* The struct filename _must_ have a populated ->name */ |
| 1847 | BUG_ON(!name->name); | 1847 | BUG_ON(!name->name); |
| 1848 | #endif | 1848 | #endif |
| 1849 | |||
| 1849 | /* | 1850 | /* |
| 1850 | * If we have a pointer to an audit_names entry already, then we can | 1851 | * If we have a pointer to an audit_names entry already, then we can |
| 1851 | * just use it directly if the type is correct. | 1852 | * just use it directly if the type is correct. |
| @@ -1863,7 +1864,17 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
| 1863 | } | 1864 | } |
| 1864 | 1865 | ||
| 1865 | list_for_each_entry_reverse(n, &context->names_list, list) { | 1866 | list_for_each_entry_reverse(n, &context->names_list, list) { |
| 1866 | if (!n->name || strcmp(n->name->name, name->name)) | 1867 | if (n->ino) { |
| 1868 | /* valid inode number, use that for the comparison */ | ||
| 1869 | if (n->ino != inode->i_ino || | ||
| 1870 | n->dev != inode->i_sb->s_dev) | ||
| 1871 | continue; | ||
| 1872 | } else if (n->name) { | ||
| 1873 | /* inode number has not been set, check the name */ | ||
| 1874 | if (strcmp(n->name->name, name->name)) | ||
| 1875 | continue; | ||
| 1876 | } else | ||
| 1877 | /* no inode and no name (?!) ... this is odd ... */ | ||
| 1867 | continue; | 1878 | continue; |
| 1868 | 1879 | ||
| 1869 | /* match the correct record type */ | 1880 | /* match the correct record type */ |
| @@ -1936,11 +1947,16 @@ void __audit_inode_child(const struct inode *parent, | |||
| 1936 | 1947 | ||
| 1937 | /* look for a parent entry first */ | 1948 | /* look for a parent entry first */ |
| 1938 | list_for_each_entry(n, &context->names_list, list) { | 1949 | list_for_each_entry(n, &context->names_list, list) { |
| 1939 | if (!n->name || n->type != AUDIT_TYPE_PARENT) | 1950 | if (!n->name || |
| 1951 | (n->type != AUDIT_TYPE_PARENT && | ||
| 1952 | n->type != AUDIT_TYPE_UNKNOWN)) | ||
| 1940 | continue; | 1953 | continue; |
| 1941 | 1954 | ||
| 1942 | if (n->ino == parent->i_ino && | 1955 | if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev && |
| 1943 | !audit_compare_dname_path(dname, n->name->name, n->name_len)) { | 1956 | !audit_compare_dname_path(dname, |
| 1957 | n->name->name, n->name_len)) { | ||
| 1958 | if (n->type == AUDIT_TYPE_UNKNOWN) | ||
| 1959 | n->type = AUDIT_TYPE_PARENT; | ||
| 1944 | found_parent = n; | 1960 | found_parent = n; |
| 1945 | break; | 1961 | break; |
| 1946 | } | 1962 | } |
| @@ -1949,11 +1965,8 @@ void __audit_inode_child(const struct inode *parent, | |||
| 1949 | /* is there a matching child entry? */ | 1965 | /* is there a matching child entry? */ |
| 1950 | list_for_each_entry(n, &context->names_list, list) { | 1966 | list_for_each_entry(n, &context->names_list, list) { |
| 1951 | /* can only match entries that have a name */ | 1967 | /* can only match entries that have a name */ |
| 1952 | if (!n->name || n->type != type) | 1968 | if (!n->name || |
| 1953 | continue; | 1969 | (n->type != type && n->type != AUDIT_TYPE_UNKNOWN)) |
| 1954 | |||
| 1955 | /* if we found a parent, make sure this one is a child of it */ | ||
| 1956 | if (found_parent && (n->name != found_parent->name)) | ||
| 1957 | continue; | 1970 | continue; |
| 1958 | 1971 | ||
| 1959 | if (!strcmp(dname, n->name->name) || | 1972 | if (!strcmp(dname, n->name->name) || |
| @@ -1961,6 +1974,8 @@ void __audit_inode_child(const struct inode *parent, | |||
| 1961 | found_parent ? | 1974 | found_parent ? |
| 1962 | found_parent->name_len : | 1975 | found_parent->name_len : |
| 1963 | AUDIT_NAME_FULL)) { | 1976 | AUDIT_NAME_FULL)) { |
| 1977 | if (n->type == AUDIT_TYPE_UNKNOWN) | ||
| 1978 | n->type = type; | ||
| 1964 | found_child = n; | 1979 | found_child = n; |
| 1965 | break; | 1980 | break; |
| 1966 | } | 1981 | } |
| @@ -1989,6 +2004,7 @@ void __audit_inode_child(const struct inode *parent, | |||
| 1989 | found_child->name_put = false; | 2004 | found_child->name_put = false; |
| 1990 | } | 2005 | } |
| 1991 | } | 2006 | } |
| 2007 | |||
| 1992 | if (inode) | 2008 | if (inode) |
| 1993 | audit_copy_inode(found_child, dentry, inode); | 2009 | audit_copy_inode(found_child, dentry, inode); |
| 1994 | else | 2010 | else |
