AppArmor policy needs to be able to be resolved based on the policy namespace a task is confined by. Add a base apparmorfs filesystem that (like nsfs) will exist as a kern mount and be accessed via jump_link through a securityfs file. Setup the base apparmorfs fns and data, but don't use it yet.
Unified · Split
| @@ -80,6 +80,8 @@ · 79 unmodified lines | |||
| 80 | #define BTRFS_TEST_MAGIC 0x73727279 | 80 | #define BTRFS_TEST_MAGIC 0x73727279 |
| 81 | #define NSFS_MAGIC 0x6e736673 | 81 | #define NSFS_MAGIC 0x6e736673 |
| 82 | #define BPF_FS_MAGIC 0xcafe4a11 | 82 | #define BPF_FS_MAGIC 0xcafe4a11 |
| 83 | #define AAFS_MAGIC 0x5a3c69f0 | ||
| 84 | |||
| 83 | /* Since UDF 2.01 is ISO 13346 based... */ | 85 | /* Since UDF 2.01 is ISO 13346 based... */ |
| 84 | #define UDF_SUPER_MAGIC 0x15013346 | 86 | #define UDF_SUPER_MAGIC 0x15013346 |
| 85 | #define BALLOON_KVM_MAGIC 0x13661366 | 87 | #define BALLOON_KVM_MAGIC 0x13661366 |
| @@ -22,8 +22,9 @@ · 21 unmodified lines | |||
| 22 | #include <linux/namei.h> | 22 | #include <linux/namei.h> |
| 23 | #include <linux/capability.h> | 23 | #include <linux/capability.h> |
| 24 | #include <linux/rcupdate.h> | 24 | #include <linux/rcupdate.h> |
| 25 | #include <uapi/linux/major.h> | ||
| 26 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 26 | #include <uapi/linux/major.h> | ||
| 27 | #include <uapi/linux/magic.h> | ||
| 27 | 28 | ||
| 28 | #include "include/apparmor.h" | 29 | #include "include/apparmor.h" |
| 29 | #include "include/apparmorfs.h" | 30 | #include "include/apparmorfs.h" |
| @@ -74,6 +75,265 @@ static int mangle_name(const char *name, char *target) · 44 unmodified lines | |||
| 74 | return t - target; | 75 | return t - target; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 78 | |||
| 79 | /* | ||
| 80 | * aafs - core fns and data for the policy tree | ||
| 81 | */ | ||
| 82 | |||
| 83 | #define AAFS_NAME "apparmorfs" | ||
| 84 | static struct vfsmount *aafs_mnt; | ||
| 85 | static int aafs_count; | ||
| 86 | |||
| 87 | |||
| 88 | static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) | ||
| 89 | { | ||
| 90 | struct inode *inode = d_inode(dentry); | ||
| 91 | |||
| 92 | seq_printf(seq, "%s:[%lu]", AAFS_NAME, inode->i_ino); | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | static void aafs_evict_inode(struct inode *inode) | ||
| 97 | { | ||
| 98 | truncate_inode_pages_final(&inode->i_data); | ||
| 99 | clear_inode(inode); | ||
| 100 | if (S_ISLNK(inode->i_mode)) | ||
| 101 | kfree(inode->i_link); | ||
| 102 | } | ||
| 103 | |||
| 104 | static const struct super_operations aafs_super_ops = { | ||
| 105 | .statfs = simple_statfs, | ||
| 106 | .evict_inode = aafs_evict_inode, | ||
| 107 | .show_path = aafs_show_path, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static int fill_super(struct super_block *sb, void *data, int silent) | ||
| 111 | { | ||
| 112 | static struct tree_descr files[] = { {""} }; | ||
| 113 | int error; | ||
| 114 | |||
| 115 | error = simple_fill_super(sb, AAFS_MAGIC, files); | ||
| 116 | if (error) | ||
| 117 | return error; | ||
| 118 | sb->s_op = &aafs_super_ops; | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | static struct dentry *aafs_mount(struct file_system_type *fs_type, | ||
| 124 | int flags, const char *dev_name, void *data) | ||
| 125 | { | ||
| 126 | return mount_single(fs_type, flags, data, fill_super); | ||
| 127 | } | ||
| 128 | |||
| 129 | static struct file_system_type aafs_ops = { | ||
| 130 | .owner = THIS_MODULE, | ||
| 131 | .name = AAFS_NAME, | ||
| 132 | .mount = aafs_mount, | ||
| 133 | .kill_sb = kill_anon_super, | ||
| 134 | }; | ||
| 135 | |||
| 136 | /** | ||
| 137 | * __aafs_setup_d_inode - basic inode setup for apparmorfs | ||
| 138 | * @dir: parent directory for the dentry | ||
| 139 | * @dentry: dentry we are seting the inode up for | ||
| 140 | * @mode: permissions the file should have | ||
| 141 | * @data: data to store on inode.i_private, available in open() | ||
| 142 | * @link: if symlink, symlink target string | ||
| 143 | * @fops: struct file_operations that should be used | ||
| 144 | * @iops: struct of inode_operations that should be used | ||
| 145 | */ | ||
| 146 | static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry, | ||
| 147 | umode_t mode, void *data, char *link, | ||
| 148 | const struct file_operations *fops, | ||
| 149 | const struct inode_operations *iops) | ||
| 150 | { | ||
| 151 | struct inode *inode = new_inode(dir->i_sb); | ||
| 152 | |||
| 153 | AA_BUG(!dir); | ||
| 154 | AA_BUG(!dentry); | ||
| 155 | |||
| 156 | if (!inode) | ||
| 157 | return -ENOMEM; | ||
| 158 | |||
| 159 | inode->i_ino = get_next_ino(); | ||
| 160 | inode->i_mode = mode; | ||
| 161 | inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); | ||
| 162 | inode->i_private = data; | ||
| 163 | if (S_ISDIR(mode)) { | ||
| 164 | inode->i_op = iops ? iops : &simple_dir_inode_operations; | ||
| 165 | inode->i_fop = &simple_dir_operations; | ||
| 166 | inc_nlink(inode); | ||
| 167 | inc_nlink(dir); | ||
| 168 | } else if (S_ISLNK(mode)) { | ||
| 169 | inode->i_op = iops ? iops : &simple_symlink_inode_operations; | ||
| 170 | inode->i_link = link; | ||
| 171 | } else { | ||
| 172 | inode->i_fop = fops; | ||
| 173 | } | ||
| 174 | d_instantiate(dentry, inode); | ||
| 175 | dget(dentry); | ||
| 176 | |||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 180 | /** | ||
| 181 | * aafs_create - create a dentry in the apparmorfs filesystem | ||
| 182 | * | ||
| 183 | * @name: name of dentry to create | ||
| 184 | * @mode: permissions the file should have | ||
| 185 | * @parent: parent directory for this dentry | ||
| 186 | * @data: data to store on inode.i_private, available in open() | ||
| 187 | * @link: if symlink, symlink target string | ||
| 188 | * @fops: struct file_operations that should be used for | ||
| 189 | * @iops: struct of inode_operations that should be used | ||
| 190 | * | ||
| 191 | * This is the basic "create a xxx" function for apparmorfs. | ||
| 192 | * | ||
| 193 | * Returns a pointer to a dentry if it succeeds, that must be free with | ||
| 194 | * aafs_remove(). Will return ERR_PTR on failure. | ||
| 195 | */ | ||
| 196 | static struct dentry *aafs_create(const char *name, umode_t mode, | ||
| 197 | struct dentry *parent, void *data, void *link, | ||
| 198 | const struct file_operations *fops, | ||
| 199 | const struct inode_operations *iops) | ||
| 200 | { | ||
| 201 | struct dentry *dentry; | ||
| 202 | struct inode *dir; | ||
| 203 | int error; | ||
| 204 | |||
| 205 | AA_BUG(!name); | ||
| 206 | AA_BUG(!parent); | ||
| 207 | |||
| 208 | if (!(mode & S_IFMT)) | ||
| 209 | mode = (mode & S_IALLUGO) | S_IFREG; | ||
| 210 | |||
| 211 | error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count); | ||
| 212 | if (error) | ||
| 213 | return ERR_PTR(error); | ||
| 214 | |||
| 215 | dir = d_inode(parent); | ||
| 216 | |||
| 217 | inode_lock(dir); | ||
| 218 | dentry = lookup_one_len(name, parent, strlen(name)); | ||
| 219 | if (IS_ERR(dentry)) | ||
| 220 | goto fail_lock; | ||
| 221 | |||
| 222 | if (d_really_is_positive(dentry)) { | ||
| 223 | error = -EEXIST; | ||
| 224 | goto fail_dentry; | ||
| 225 | } | ||
| 226 | |||
| 227 | error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops); | ||
| 228 | if (error) | ||
| 229 | goto fail_dentry; | ||
| 230 | inode_unlock(dir); | ||
| 231 | |||
| 232 | return dentry; | ||
| 233 | |||
| 234 | fail_dentry: | ||
| 235 | dput(dentry); | ||
| 236 | |||
| 237 | fail_lock: | ||
| 238 | inode_unlock(dir); | ||
| 239 | simple_release_fs(&aafs_mnt, &aafs_count); | ||
| 240 | |||
| 241 | return ERR_PTR(error); | ||
| 242 | } | ||
| 243 | |||
| 244 | /** | ||
| 245 | * aafs_create_file - create a file in the apparmorfs filesystem | ||
| 246 | * | ||
| 247 | * @name: name of dentry to create | ||
| 248 | * @mode: permissions the file should have | ||
| 249 | * @parent: parent directory for this dentry | ||
| 250 | * @data: data to store on inode.i_private, available in open() | ||
| 251 | * @fops: struct file_operations that should be used for | ||
| 252 | * | ||
| 253 | * see aafs_create | ||
| 254 | */ | ||
| 255 | static struct dentry *aafs_create_file(const char *name, umode_t mode, | ||
| 256 | struct dentry *parent, void *data, | ||
| 257 | const struct file_operations *fops) | ||
| 258 | { | ||
| 259 | return aafs_create(name, mode, parent, data, NULL, fops, NULL); | ||
| 260 | } | ||
| 261 | |||
| 262 | /** | ||
| 263 | * aafs_create_dir - create a directory in the apparmorfs filesystem | ||
| 264 | * | ||
| 265 | * @name: name of dentry to create | ||
| 266 | * @parent: parent directory for this dentry | ||
| 267 | * | ||
| 268 | * see aafs_create | ||
| 269 | */ | ||
| 270 | static struct dentry *aafs_create_dir(const char *name, struct dentry *parent) | ||
| 271 | { | ||
| 272 | return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL, | ||
| 273 | NULL); | ||
| 274 | } | ||
| 275 | |||
| 276 | /** | ||
| 277 | * aafs_create_symlink - create a symlink in the apparmorfs filesystem | ||
| 278 | * @name: name of dentry to create | ||
| 279 | * @parent: parent directory for this dentry | ||
| 280 | * @target: if symlink, symlink target string | ||
| 281 | * @iops: struct of inode_operations that should be used | ||
| 282 | * | ||
| 283 | * If @target parameter is %NULL, then the @iops parameter needs to be | ||
| 284 | * setup to handle .readlink and .get_link inode_operations. | ||
| 285 | */ | ||
| 286 | static struct dentry *aafs_create_symlink(const char *name, | ||
| 287 | struct dentry *parent, | ||
| 288 | const char *target, | ||
| 289 | const struct inode_operations *iops) | ||
| 290 | { | ||
| 291 | struct dentry *dent; | ||
| 292 | char *link = NULL; | ||
| 293 | |||
| 294 | if (target) { | ||
| 295 | link = kstrdup(target, GFP_KERNEL); | ||
| 296 | if (!link) | ||
| 297 | return ERR_PTR(-ENOMEM); | ||
| 298 | } | ||
| 299 | dent = aafs_create(name, S_IFLNK | 0444, parent, NULL, link, NULL, | ||
| 300 | iops); | ||
| 301 | if (IS_ERR(dent)) | ||
| 302 | kfree(link); | ||
| 303 | |||
| 304 | return dent; | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * aafs_remove - removes a file or directory from the apparmorfs filesystem | ||
| 309 | * | ||
| 310 | * @dentry: dentry of the file/directory/symlink to removed. | ||
| 311 | */ | ||
| 312 | static void aafs_remove(struct dentry *dentry) | ||
| 313 | { | ||
| 314 | struct inode *dir; | ||
| 315 | |||
| 316 | if (!dentry || IS_ERR(dentry)) | ||
| 317 | return; | ||
| 318 | |||
| 319 | dir = d_inode(dentry->d_parent); | ||
| 320 | inode_lock(dir); | ||
| 321 | if (simple_positive(dentry)) { | ||
| 322 | if (d_is_dir(dentry)) | ||
| 323 | simple_rmdir(dir, dentry); | ||
| 324 | else | ||
| 325 | simple_unlink(dir, dentry); | ||
| 326 | dput(dentry); | ||
| 327 | } | ||
| 328 | inode_unlock(dir); | ||
| 329 | simple_release_fs(&aafs_mnt, &aafs_count); | ||
| 330 | } | ||
| 331 | |||
| 332 | |||
| 333 | /* | ||
| 334 | * aa_fs - policy load/replace/remove | ||
| 335 | */ | ||
| 336 | |||
| 77 | /** | 337 | /** |
| 78 | * aa_simple_write_to_buffer - common routine for getting policy from user | 338 | * aa_simple_write_to_buffer - common routine for getting policy from user |
| 79 | * @userbuf: user buffer to copy data from (NOT NULL) | 339 | * @userbuf: user buffer to copy data from (NOT NULL) |
| @@ -1369,14 +1629,14 @@ static struct aa_fs_entry aa_fs_entry = · 1289 unmodified lines | |||
| 1369 | AA_FS_DIR("apparmor", aa_fs_entry_apparmor); | 1629 | AA_FS_DIR("apparmor", aa_fs_entry_apparmor); |
| 1370 | 1630 | ||
| 1371 | /** | 1631 | /** |
| 1372 | * aafs_create_file - create a file entry in the apparmor securityfs | 1632 | * entry_create_file - create a file entry in the apparmor securityfs |
| 1373 | * @fs_file: aa_fs_entry to build an entry for (NOT NULL) | 1633 | * @fs_file: aa_fs_entry to build an entry for (NOT NULL) |
| 1374 | * @parent: the parent dentry in the securityfs | 1634 | * @parent: the parent dentry in the securityfs |
| 1375 | * | 1635 | * |
| 1376 | * Use aafs_remove_file to remove entries created with this fn. | 1636 | * Use entry_remove_file to remove entries created with this fn. |
| 1377 | */ | 1637 | */ |
| 1378 | static int __init aafs_create_file(struct aa_fs_entry *fs_file, | 1638 | static int __init entry_create_file(struct aa_fs_entry *fs_file, |
| 1379 | struct dentry *parent) | 1639 | struct dentry *parent) |
| 1380 | { | 1640 | { |
| 1381 | int error = 0; | 1641 | int error = 0; |
| 1382 | 1642 | ||
| @@ -1391,15 +1651,15 @@ static int __init aafs_create_file(struct aa_fs_entry *fs_file, · 8 unmodified lines | |||
| 1391 | return error; | 1651 | return error; |
| 1392 | } | 1652 | } |
| 1393 | 1653 | ||
| 1394 | static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir); | 1654 | static void __init entry_remove_dir(struct aa_fs_entry *fs_dir); |
| 1395 | /** | 1655 | /** |
| 1396 | * aafs_create_dir - recursively create a directory entry in the securityfs | 1656 | * entry_create_dir - recursively create a directory entry in the securityfs |
| 1397 | * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL) | 1657 | * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL) |
| 1398 | * @parent: the parent dentry in the securityfs | 1658 | * @parent: the parent dentry in the securityfs |
| 1399 | * | 1659 | * |
| 1400 | * Use aafs_remove_dir to remove entries created with this fn. | 1660 | * Use entry_remove_dir to remove entries created with this fn. |
| 1401 | */ | 1661 | */ |
| 1402 | static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, | 1662 | static int __init entry_create_dir(struct aa_fs_entry *fs_dir, |
| 1403 | struct dentry *parent) | 1663 | struct dentry *parent) |
| 1404 | { | 1664 | { |
| 1405 | struct aa_fs_entry *fs_file; | 1665 | struct aa_fs_entry *fs_file; |
| @@ -1413,9 +1673,9 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, · 7 unmodified lines | |||
| 1413 | 1673 | ||
| 1414 | for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { | 1674 | for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { |
| 1415 | if (fs_file->v_type == AA_FS_TYPE_DIR) | 1675 | if (fs_file->v_type == AA_FS_TYPE_DIR) |
| 1416 | error = aafs_create_dir(fs_file, fs_dir->dentry); | 1676 | error = entry_create_dir(fs_file, fs_dir->dentry); |
| 1417 | else | 1677 | else |
| 1418 | error = aafs_create_file(fs_file, fs_dir->dentry); | 1678 | error = entry_create_file(fs_file, fs_dir->dentry); |
| 1419 | if (error) | 1679 | if (error) |
| 1420 | goto failed; | 1680 | goto failed; |
| 1421 | } | 1681 | } |
| @@ -1423,7 +1683,7 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, · 1 unmodified line | |||
| 1423 | return 0; | 1683 | return 0; |
| 1424 | 1684 | ||
| 1425 | failed: | 1685 | failed: |
| 1426 | aafs_remove_dir(fs_dir); | 1686 | entry_remove_dir(fs_dir); |
| 1427 | 1687 | ||
| 1428 | return error; | 1688 | return error; |
| 1429 | } | 1689 | } |
| @@ -1442,16 +1702,16 @@ static void __init aafs_remove_file(struct aa_fs_entry *fs_file) · 12 unmodified lines | |||
| 1442 | } | 1702 | } |
| 1443 | 1703 | ||
| 1444 | /** | 1704 | /** |
| 1445 | * aafs_remove_dir - recursively drop a directory entry from the securityfs | 1705 | * entry_remove_dir - recursively drop a directory entry from the securityfs |
| 1446 | * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL) | 1706 | * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL) |
| 1447 | */ | 1707 | */ |
| 1448 | static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir) | 1708 | static void __init entry_remove_dir(struct aa_fs_entry *fs_dir) |
| 1449 | { | 1709 | { |
| 1450 | struct aa_fs_entry *fs_file; | 1710 | struct aa_fs_entry *fs_file; |
| 1451 | 1711 | ||
| 1452 | for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { | 1712 | for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { |
| 1453 | if (fs_file->v_type == AA_FS_TYPE_DIR) | 1713 | if (fs_file->v_type == AA_FS_TYPE_DIR) |
| 1454 | aafs_remove_dir(fs_file); | 1714 | entry_remove_dir(fs_file); |
| 1455 | else | 1715 | else |
| 1456 | aafs_remove_file(fs_file); | 1716 | aafs_remove_file(fs_file); |
| 1457 | } | 1717 | } |
| @@ -1466,7 +1726,7 @@ static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir) · 8 unmodified lines | |||
| 1466 | */ | 1726 | */ |
| 1467 | void __init aa_destroy_aafs(void) | 1727 | void __init aa_destroy_aafs(void) |
| 1468 | { | 1728 | { |
| 1469 | aafs_remove_dir(&aa_fs_entry); | 1729 | entry_remove_dir(&aa_fs_entry); |
| 1470 | } | 1730 | } |
| 1471 | 1731 | ||
| 1472 | 1732 | ||
| @@ -1515,6 +1775,59 @@ out: · 42 unmodified lines | |||
| 1515 | return error; | 1775 | return error; |
| 1516 | } | 1776 | } |
| 1517 | 1777 | ||
| 1778 | |||
| 1779 | |||
| 1780 | static const char *policy_get_link(struct dentry *dentry, | ||
| 1781 | struct inode *inode, | ||
| 1782 | struct delayed_call *done) | ||
| 1783 | { | ||
| 1784 | struct aa_ns *ns; | ||
| 1785 | struct path path; | ||
| 1786 | |||
| 1787 | if (!dentry) | ||
| 1788 | return ERR_PTR(-ECHILD); | ||
| 1789 | ns = aa_get_current_ns(); | ||
| 1790 | path.mnt = mntget(aafs_mnt); | ||
| 1791 | path.dentry = dget(ns_dir(ns)); | ||
| 1792 | nd_jump_link(&path); | ||
| 1793 | aa_put_ns(ns); | ||
| 1794 | |||
| 1795 | return NULL; | ||
| 1796 | } | ||
| 1797 | |||
| 1798 | static int ns_get_name(char *buf, size_t size, struct aa_ns *ns, | ||
| 1799 | struct inode *inode) | ||
| 1800 | { | ||
| 1801 | int res = snprintf(buf, size, "%s:[%lu]", AAFS_NAME, inode->i_ino); | ||
| 1802 | |||
| 1803 | if (res < 0 || res >= size) | ||
| 1804 | res = -ENOENT; | ||
| 1805 | |||
| 1806 | return res; | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | static int policy_readlink(struct dentry *dentry, char __user *buffer, | ||
| 1810 | int buflen) | ||
| 1811 | { | ||
| 1812 | struct aa_ns *ns; | ||
| 1813 | char name[32]; | ||
| 1814 | int res; | ||
| 1815 | |||
| 1816 | ns = aa_get_current_ns(); | ||
| 1817 | res = ns_get_name(name, sizeof(name), ns, d_inode(dentry)); | ||
| 1818 | if (res >= 0) | ||
| 1819 | res = readlink_copy(buffer, buflen, name); | ||
| 1820 | aa_put_ns(ns); | ||
| 1821 | |||
| 1822 | return res; | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | static const struct inode_operations policy_link_iops = { | ||
| 1826 | .readlink = policy_readlink, | ||
| 1827 | .get_link = policy_get_link, | ||
| 1828 | }; | ||
| 1829 | |||
| 1830 | |||
| 1518 | /** | 1831 | /** |
| 1519 | * aa_create_aafs - create the apparmor security filesystem | 1832 | * aa_create_aafs - create the apparmor security filesystem |
| 1520 | * | 1833 | * |
| @@ -1535,8 +1848,14 @@ static int __init aa_create_aafs(void) · 14 unmodified lines | |||
| 1535 | return -EEXIST; | 1848 | return -EEXIST; |
| 1536 | } | 1849 | } |
| 1537 | 1850 | ||
| 1851 | /* setup apparmorfs used to virtualize policy/ */ | ||
| 1852 | aafs_mnt = kern_mount(&aafs_ops); | ||
| 1853 | if (IS_ERR(aafs_mnt)) | ||
| 1854 | panic("can't set apparmorfs up\n"); | ||
| 1855 | aafs_mnt->mnt_sb->s_flags &= ~MS_NOUSER; | ||
| 1856 | |||
| 1538 | /* Populate fs tree. */ | 1857 | /* Populate fs tree. */ |
| 1539 | error = aafs_create_dir(&aa_fs_entry, NULL); | 1858 | error = entry_create_dir(&aa_fs_entry, NULL); |
| 1540 | if (error) | 1859 | if (error) |
| 1541 | goto error; | 1860 | goto error; |
| 1542 | 1861 | ||