diff --git a/libraries/libapparmor/doc/aa_features.pod b/libraries/libapparmor/doc/aa_features.pod index ffbe113ac..16fdbe82d 100644 --- a/libraries/libapparmor/doc/aa_features.pod +++ b/libraries/libapparmor/doc/aa_features.pod @@ -136,6 +136,9 @@ I family of functions that return -1 on error. All aa_features functions described above are present in libapparmor version 2.10 and newer. +aa_features_unref() saves the value of errno when called and restores errno +before exiting in libapparmor version 2.12 and newer. + =head1 BUGS None known. If you find any, please report them at diff --git a/libraries/libapparmor/doc/aa_kernel_interface.pod b/libraries/libapparmor/doc/aa_kernel_interface.pod index 08084c12b..8616f5a8e 100644 --- a/libraries/libapparmor/doc/aa_kernel_interface.pod +++ b/libraries/libapparmor/doc/aa_kernel_interface.pod @@ -150,6 +150,9 @@ I family of functions that return -1 on error. All aa_kernel_interface functions described above are present in libapparmor version 2.10 and newer. +aa_kernel_interface_unref() saves the value of errno when called and restores +errno before exiting in libapparmor version 2.12 and newer. + =head1 BUGS None known. If you find any, please report them at diff --git a/libraries/libapparmor/doc/aa_policy_cache.pod b/libraries/libapparmor/doc/aa_policy_cache.pod index 672d616b1..91092f8b7 100644 --- a/libraries/libapparmor/doc/aa_policy_cache.pod +++ b/libraries/libapparmor/doc/aa_policy_cache.pod @@ -112,6 +112,9 @@ I family of functions that return -1 on error. All aa_policy_cache functions described above are present in libapparmor version 2.10 and newer. +aa_policy_cache_unref() saves the value of errno when called and restores errno +before exiting in libapparmor version 2.12 and newer. + =head1 BUGS None known. If you find any, please report them at diff --git a/libraries/libapparmor/src/features.c b/libraries/libapparmor/src/features.c index c656c37d1..1b8be01eb 100644 --- a/libraries/libapparmor/src/features.c +++ b/libraries/libapparmor/src/features.c @@ -404,10 +404,7 @@ int aa_features_new(aa_features **features, int dirfd, const char *path) load_features_dir(dirfd, path, f->string, STRING_SIZE) : load_features_file(dirfd, path, f->string, STRING_SIZE); if (retval == -1) { - int save = errno; - aa_features_unref(f); - errno = save; return -1; } @@ -482,8 +479,12 @@ aa_features *aa_features_ref(aa_features *features) */ void aa_features_unref(aa_features *features) { + int save = errno; + if (features && atomic_dec_and_test(&features->ref_count)) free(features); + + errno = save; } /** diff --git a/libraries/libapparmor/src/kernel_interface.c b/libraries/libapparmor/src/kernel_interface.c index 29f4833b2..5942ddd27 100644 --- a/libraries/libapparmor/src/kernel_interface.c +++ b/libraries/libapparmor/src/kernel_interface.c @@ -229,10 +229,7 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface, if (kernel_features) { aa_features_ref(kernel_features); } else if (aa_features_new_from_kernel(&kernel_features) == -1) { - int save = errno; - aa_kernel_interface_unref(ki); - errno = save; return -1; } ki->supports_setload = aa_features_supports(kernel_features, set_load); @@ -240,11 +237,8 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface, if (!apparmorfs) { if (find_iface_dir(&alloced_apparmorfs) == -1) { - int save = errno; - alloced_apparmorfs = NULL; aa_kernel_interface_unref(ki); - errno = save; return -1; } /* alloced_apparmorfs will be autofree'ed */ @@ -253,10 +247,7 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface, ki->dirfd = open(apparmorfs, O_RDONLY | O_CLOEXEC | O_DIRECTORY); if (ki->dirfd < 0) { - int save = errno; - aa_kernel_interface_unref(ki); - errno = save; return -1; } @@ -283,12 +274,16 @@ aa_kernel_interface *aa_kernel_interface_ref(aa_kernel_interface *kernel_interfa */ void aa_kernel_interface_unref(aa_kernel_interface *kernel_interface) { + int save = errno; + if (kernel_interface && atomic_dec_and_test(&kernel_interface->ref_count)) { if (kernel_interface->dirfd >= 0) close(kernel_interface->dirfd); free(kernel_interface); } + + errno = save; } /** diff --git a/libraries/libapparmor/src/policy_cache.c b/libraries/libapparmor/src/policy_cache.c index 56394f70a..ec051d780 100644 --- a/libraries/libapparmor/src/policy_cache.c +++ b/libraries/libapparmor/src/policy_cache.c @@ -159,8 +159,6 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache, open: pc->dirfd = openat(dirfd, path, O_RDONLY | O_CLOEXEC | O_DIRECTORY); if (pc->dirfd < 0) { - int save; - /* does the dir exist? */ if (create && errno == ENOENT) { if (mkdirat(dirfd, path, 0700) == 0) @@ -172,28 +170,20 @@ open: PDEBUG("Cache directory '%s' does not exist\n", path); } - save = errno; aa_policy_cache_unref(pc); - errno = save; return -1; } if (kernel_features) { aa_features_ref(kernel_features); } else if (aa_features_new_from_kernel(&kernel_features) == -1) { - int save = errno; - aa_policy_cache_unref(pc); - errno = save; return -1; } pc->kernel_features = kernel_features; if (init_cache_features(pc, kernel_features, create)) { - int save = errno; - aa_policy_cache_unref(pc); - errno = save; return -1; } @@ -220,6 +210,8 @@ aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache) */ void aa_policy_cache_unref(aa_policy_cache *policy_cache) { + int save = errno; + if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) { aa_features_unref(policy_cache->features); aa_features_unref(policy_cache->kernel_features); @@ -227,6 +219,8 @@ void aa_policy_cache_unref(aa_policy_cache *policy_cache) close(policy_cache->dirfd); free(policy_cache); } + + errno = save; } /**