From 3528765df42e785f7d45ea9093c82008ddaa0d65 Mon Sep 17 00:00:00 2001 From: 0x1eef <0x1eef@protonmail.com> Date: Wed, 20 Mar 2024 16:25:20 -0300 Subject: [PATCH] Reimplement on top of libhbsdcontrol v2 --- .clang-format | 11 ++ Rakefile.rb | 6 +- ext/hbsdctl.rb/context.c | 68 +++++++++++ ext/hbsdctl.rb/context.h | 10 ++ ext/hbsdctl.rb/feature.c | 87 +++++++++----- ext/hbsdctl.rb/feature.h | 3 + ext/hbsdctl.rb/ffi.c | 133 ---------------------- ext/hbsdctl.rb/glue.c | 34 ++++++ ext/hbsdctl.rb/glue.h | 7 ++ ext/hbsdctl.rb/hbsdctl.c | 30 ++--- ext/hbsdctl.rb/include/feature.h | 2 - ext/hbsdctl.rb/include/ffi.h | 5 - lib/bsd/control.rb | 12 +- lib/bsd/control/context.rb | 7 ++ lib/bsd/control/feature.rb | 8 +- test/superuser/disable_feature_test.rb | 4 +- test/superuser/enable_feature_test.rb | 12 +- test/superuser/feature_status_test.rb | 16 +-- test/unprivileged/disable_feature_test.rb | 4 +- test/unprivileged/enable_feature_test.rb | 2 +- test/unprivileged/feature_test.rb | 4 +- test/unprivileged/sysdef_test.rb | 2 +- 22 files changed, 256 insertions(+), 211 deletions(-) create mode 100644 .clang-format create mode 100644 ext/hbsdctl.rb/context.c create mode 100644 ext/hbsdctl.rb/context.h create mode 100644 ext/hbsdctl.rb/feature.h delete mode 100644 ext/hbsdctl.rb/ffi.c create mode 100644 ext/hbsdctl.rb/glue.c create mode 100644 ext/hbsdctl.rb/glue.h delete mode 100644 ext/hbsdctl.rb/include/feature.h delete mode 100644 ext/hbsdctl.rb/include/ffi.h create mode 100644 lib/bsd/control/context.rb diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..dcdbcaf --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: LLVM +IndentWidth: 2 +SortIncludes: false +UseTab: Never +BreakBeforeBraces: Allman +AllowShortFunctionsOnASingleLine: Inline +AlwaysBreakAfterDefinitionReturnType: TopLevel +BreakBeforeBinaryOperators: All +BinPackArguments: false +AlignConsecutiveAssignments: true +AlwaysBreakAfterReturnType: None diff --git a/Rakefile.rb b/Rakefile.rb index 5fa30e7..15ceb81 100644 --- a/Rakefile.rb +++ b/Rakefile.rb @@ -4,8 +4,10 @@ Rake::ExtensionTask.new("hbsdctl.rb") task default: %w[clobber compile test] desc "Run C linter" -task :styleguide do - sh "uncrustify -c .styleguide.cfg --no-backup ext/hbsdctl.rb/*.c" +namespace :clang do + task :format do + sh "clang-format -style=file:.clang-format -i ext/hbsdctl.rb/*.c" + end end namespace :test do diff --git a/ext/hbsdctl.rb/context.c b/ext/hbsdctl.rb/context.c new file mode 100644 index 0000000..54cdb03 --- /dev/null +++ b/ext/hbsdctl.rb/context.c @@ -0,0 +1,68 @@ +#include +#include +#include "context.h" +#include "glue.h" + +static int FLAGS = HBSDCTRL_FEATURE_STATE_FLAG_NONE; +static const char *NAMESPACE = LIBHBSDCONTROL_DEFAULT_NAMESPACE; +static void bsdcontrol_context_free(struct bsdcontrol_ctx_t *); + +VALUE +bsdcontrol_context_alloc(VALUE klass) +{ + hbsdctrl_ctx_t *ctx; + struct bsdcontrol_ctx_t *rbctx; + ctx = hbsdctrl_ctx_new(FLAGS, NAMESPACE); + rbctx = calloc(1, sizeof(struct bsdcontrol_ctx_t)); + if (ctx == NULL || rbctx == NULL) + { + rb_raise(rb_eRuntimeError, "..."); + } + rbctx->ctx = ctx; + return Data_Wrap_Struct(klass, NULL, bsdcontrol_context_free, rbctx); +} + +static void +bsdcontrol_context_free(struct bsdcontrol_ctx_t *rbctx) +{ + hbsdctrl_ctx_free(&rbctx->ctx); + free(rbctx); +} + +/* + * BSD::Control::Context#available_features + * BSD::Control.available_features + * BSD::Control::Feature.available + */ +VALUE +bsdcontrol_context_available_features(VALUE self) +{ + VALUE rb_mBSD = rb_const_get(rb_cObject, rb_intern("BSD")), + rb_mControl = rb_const_get(rb_mBSD, rb_intern("Control")), + rb_cFeature = rb_const_get(rb_mControl, rb_intern("Feature")), + feature = 0, features = rb_ary_new(); + hbsdctrl_ctx_t *ctx; + char **name; + ctx = bsdcontrol_unwrap(self); + name = hbsdctrl_ctx_all_feature_names(ctx); + while (*name != NULL) + { + feature = rb_funcall( + rb_cFeature, rb_intern("new"), 2, rb_str_new2(*name), self); + rb_ary_push(features, feature); + name++; + } + return features; +} + +/* + * BSD::Control::Context#library_version + * BSD::Control.library_version + */ +VALUE +bsdcontrol_context_library_version(VALUE self) +{ + hbsdctrl_ctx_t *ctx; + ctx = bsdcontrol_unwrap(self); + return ULONG2NUM(ctx->hc_version); +} diff --git a/ext/hbsdctl.rb/context.h b/ext/hbsdctl.rb/context.h new file mode 100644 index 0000000..e262313 --- /dev/null +++ b/ext/hbsdctl.rb/context.h @@ -0,0 +1,10 @@ +#include +#include + +struct bsdcontrol_ctx_t { + hbsdctrl_ctx_t *ctx; +}; + +VALUE bsdcontrol_context_alloc(VALUE klass); +VALUE bsdcontrol_context_library_version(VALUE self); +VALUE bsdcontrol_context_available_features(VALUE self); diff --git a/ext/hbsdctl.rb/feature.c b/ext/hbsdctl.rb/feature.c index 1295da9..b32c723 100644 --- a/ext/hbsdctl.rb/feature.c +++ b/ext/hbsdctl.rb/feature.c @@ -1,34 +1,67 @@ +#include #include +#include +#include "feature.h" +#include "context.h" +#include "glue.h" #include -#include "include/feature.h" -static VALUE __set(VALUE, VALUE, VALUE); -/** - * BSD::Control::Feature#set! - **/ +/* + * BSD::Control::Feature#status + */ VALUE -feature_set(VALUE self, VALUE rb_path, VALUE rb_state) +bsdcontrol_feature_status(VALUE self, VALUE path) { - Check_Type(rb_path, T_STRING); - Check_Type(rb_state, T_FIXNUM); - VALUE rb_feature = rb_funcall(self, rb_intern("name"), 0); - Check_Type(rb_feature, T_STRING); - return (__set(rb_path, rb_feature, rb_state)); -} - - -static VALUE -__set(VALUE rb_path, VALUE rb_feature, VALUE rb_state) -{ - errno = 0; - int result = hbsdcontrol_set_feature_state( - RSTRING_PTR(rb_path), - RSTRING_PTR(rb_feature), - NUM2INT(rb_state) - ); - if (result == 0) { - return (Qtrue); - } else { - rb_syserr_fail(errno, "hbsdcontrol_set_feature_state"); + int fd; + VALUE rbcontext; + hbsdctrl_feature_t *feature; + hbsdctrl_feature_state_t state; + hbsdctrl_ctx_t *ctx; + rbcontext = rb_funcall(self, rb_intern("context"), 0); + fd = bsdcontrol_open(path); + ctx = bsdcontrol_unwrap(rbcontext); + feature = bsdcontrol_find_feature(ctx, self); + errno = 0; + if (feature->hf_get(ctx, feature, &fd, &state) == RES_FAIL) + { + close(fd); + errno == 0 ? rb_raise(rb_eRuntimeError, "hf_get") + : rb_syserr_fail(errno, "hf_get"); + } + else + { + const char *str; + close(fd); + str = hbsdctrl_feature_state_to_string(&state); + return ID2SYM(rb_intern(str)); + } +} + +/* + * BSD::Control::Feature#set! + */ +VALUE +bsdcontrol_feature_set(VALUE self, VALUE path, VALUE rbstate) +{ + int fd; + VALUE rbcontext; + hbsdctrl_feature_t *feature; + hbsdctrl_ctx_t *ctx; + int state; + rbcontext = rb_funcall(self, rb_intern("context"), 0); + fd = bsdcontrol_open(path); + ctx = bsdcontrol_unwrap(rbcontext); + feature = bsdcontrol_find_feature(ctx, self); + state = NUM2INT(rbstate); + errno = 0; + if (feature->hf_apply(ctx, feature, &fd, &state) == RES_FAIL) + { + close(fd); + errno == 0 ? rb_raise(rb_eRuntimeError, "hf_apply") + : rb_syserr_fail(errno, "hf_apply"); + } + else + { + return Qtrue; } } diff --git a/ext/hbsdctl.rb/feature.h b/ext/hbsdctl.rb/feature.h new file mode 100644 index 0000000..e01534d --- /dev/null +++ b/ext/hbsdctl.rb/feature.h @@ -0,0 +1,3 @@ +#include +VALUE bsdcontrol_feature_status(VALUE, VALUE); +VALUE bsdcontrol_feature_set(VALUE,VALUE,VALUE); diff --git a/ext/hbsdctl.rb/ffi.c b/ext/hbsdctl.rb/ffi.c deleted file mode 100644 index 8645af3..0000000 --- a/ext/hbsdctl.rb/ffi.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include -#include -#include "include/ffi.h" - -static struct Options __options_init(VALUE, VALUE); - -struct Options { - char *path; - char *enable_flag; - char *disable_flag; -}; - -/** - * BSD::Control::FFI.available_features - **/ -VALUE -ffi_available_features(VALUE self) -{ - const struct pax_feature_entry *entry = &pax_features[0]; - VALUE rb_mBSD = rb_const_get(rb_cObject, rb_intern("BSD")), - rb_mControl = rb_const_get(rb_mBSD, rb_intern("Control")), - rb_cFeature = rb_const_get(rb_mControl, rb_intern("Feature")), - features = rb_ary_new(), - feature = 0; - - while (entry->feature != NULL) - { - feature = rb_funcall( - rb_cFeature, - rb_intern("new"), - 3, - rb_str_new2(entry->feature), - rb_str_new2(entry->extattr[1]), - rb_str_new2(entry->extattr[0]) - ); - rb_ary_push(features, feature); - entry++; - } - return (features); -} - - -/** - * BSD::Control::FFI.sysdef! - **/ -VALUE -ffi_sysdef(VALUE self, VALUE rb_feature, VALUE rb_path) -{ - struct Options options; - int result; - errno = 0; - options = __options_init(rb_feature, rb_path); - result = hbsdcontrol_extattr_rm_attr(options.path, options.disable_flag) == 0 && - hbsdcontrol_extattr_rm_attr(options.path, options.enable_flag) == 0; - if (result) { - return (Qtrue); - } else { - rb_syserr_fail(errno, "hbsdcontrol_extattr_rm_attr"); - } -} - - -/** - * BSD::Control::FFI.status - **/ -VALUE -ffi_status(VALUE self, VALUE rb_feature, VALUE rb_path) -{ - struct Options options; - char enable_data[2], disable_data[2]; - int ns; - - errno = 0; - options = __options_init(rb_feature, rb_path); - if (extattr_string_to_namespace("system", &ns) == -1) { - rb_syserr_fail(errno, "extattr_string_to_namespace"); - } - if ( - extattr_get_file( - options.path, ns, - options.enable_flag, &enable_data, - 2) == -1) { - rb_syserr_fail(errno, "extattr_get_file"); - } - if ( - extattr_get_file( - options.path, ns, - options.disable_flag, &disable_data, - 2) == -1) { - rb_syserr_fail(errno, "extattr_get_file"); - } - if (strncmp(enable_data, disable_data, 1) == 0) { - return (ID2SYM(rb_intern("conflict"))); - } else if (strncmp(enable_data, "1", 1) == 0) { - return (ID2SYM(rb_intern("enabled"))); - } else { - return (ID2SYM(rb_intern("disabled"))); - } -} - - -/** - * BSD::Control::FFI.library_version - **/ -VALUE -ffi_library_version(VALUE self) -{ - const char *ver; - ver = hbsdcontrol_get_version(); - return (rb_str_new2(ver)); -} - - -static -struct Options -__options_init(VALUE rb_feature, VALUE rb_path) -{ - VALUE rb_enable_flag, rb_disable_flag; - struct Options options; - - rb_enable_flag = rb_funcall(rb_feature, rb_intern("enable"), 0); - rb_disable_flag = rb_funcall(rb_feature, rb_intern("disable"), 0); - Check_Type(rb_enable_flag, T_STRING); - Check_Type(rb_disable_flag, T_STRING); - Check_Type(rb_path, T_STRING); - options.path = RSTRING_PTR(rb_path); - options.enable_flag = RSTRING_PTR(rb_enable_flag); - options.disable_flag = RSTRING_PTR(rb_disable_flag); - return (options); -} diff --git a/ext/hbsdctl.rb/glue.c b/ext/hbsdctl.rb/glue.c new file mode 100644 index 0000000..7a367b3 --- /dev/null +++ b/ext/hbsdctl.rb/glue.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include "glue.h" +#include "context.h" + +int +bsdcontrol_open(VALUE path) +{ + int fd; + fd = open(RSTRING_PTR(path), O_PATH); + if (fd == -1) + { + rb_syserr_fail(errno, "open"); + } + return fd; +} + +hbsdctrl_ctx_t * +bsdcontrol_unwrap(VALUE rbcontext) +{ + struct bsdcontrol_ctx_t *rbctx; + Data_Get_Struct(rbcontext, struct bsdcontrol_ctx_t, rbctx); + return rbctx->ctx; +} + +hbsdctrl_feature_t * +bsdcontrol_find_feature(hbsdctrl_ctx_t *ctx, VALUE rbfeature) +{ + VALUE name; + name = rb_funcall(rbfeature, rb_intern("name"), 0); + Check_Type(name, T_STRING); + return hbsdctrl_ctx_find_feature_by_name(ctx, RSTRING_PTR(name)); +} diff --git a/ext/hbsdctl.rb/glue.h b/ext/hbsdctl.rb/glue.h new file mode 100644 index 0000000..19cc7c6 --- /dev/null +++ b/ext/hbsdctl.rb/glue.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +int bsdcontrol_open(VALUE); +hbsdctrl_ctx_t* bsdcontrol_unwrap(VALUE); +hbsdctrl_feature_t* bsdcontrol_find_feature(hbsdctrl_ctx_t*, VALUE); diff --git a/ext/hbsdctl.rb/hbsdctl.c b/ext/hbsdctl.rb/hbsdctl.c index 9fd715a..252003a 100644 --- a/ext/hbsdctl.rb/hbsdctl.c +++ b/ext/hbsdctl.rb/hbsdctl.c @@ -1,20 +1,22 @@ #include -#include "include/ffi.h" -#include "include/feature.h" +#include +#include "context.h" +#include "feature.h" void Init_hbsdctl(void) { - VALUE rb_mBSD = rb_const_get(rb_cObject, rb_intern("BSD")), - rb_mControl = rb_const_get(rb_mBSD, rb_intern("Control")), - rb_cFeature = rb_const_get(rb_mControl, rb_intern("Feature")), - rb_mFFI = rb_const_get(rb_mControl, rb_intern("FFI")); - - rb_define_const(rb_mControl, "Disable", INT2NUM(0)); - rb_define_const(rb_mControl, "Enable", INT2NUM(1)); - rb_define_singleton_method(rb_mFFI, "available_features", ffi_available_features, 0); - rb_define_singleton_method(rb_mFFI, "library_version", ffi_library_version, 0); - rb_define_singleton_method(rb_mFFI, "sysdef!", ffi_sysdef, 2); - rb_define_singleton_method(rb_mFFI, "status", ffi_status, 2); - rb_define_private_method(rb_cFeature, "set!", feature_set, 2); + VALUE rb_mBSD = rb_const_get(rb_cObject, rb_intern("BSD")), + rb_mControl = rb_const_get(rb_mBSD, rb_intern("Control")), + rb_cFeature = rb_const_get(rb_mControl, rb_intern("Feature")), + rb_cContext = rb_const_get(rb_mControl, rb_intern("Context")); + rb_define_alloc_func(rb_cContext, bsdcontrol_context_alloc); + rb_define_method( + rb_cContext, "library_version", bsdcontrol_context_library_version, 0); + rb_define_method(rb_cContext, + "available_features", + bsdcontrol_context_available_features, + 0); + rb_define_method(rb_cFeature, "status", bsdcontrol_feature_status, 1); + rb_define_private_method(rb_cFeature, "set!", bsdcontrol_feature_set, 2); } diff --git a/ext/hbsdctl.rb/include/feature.h b/ext/hbsdctl.rb/include/feature.h deleted file mode 100644 index ae07457..0000000 --- a/ext/hbsdctl.rb/include/feature.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -VALUE feature_set(VALUE, VALUE, VALUE); diff --git a/ext/hbsdctl.rb/include/ffi.h b/ext/hbsdctl.rb/include/ffi.h deleted file mode 100644 index 8111711..0000000 --- a/ext/hbsdctl.rb/include/ffi.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -VALUE ffi_library_version(VALUE); -VALUE ffi_available_features(VALUE); -VALUE ffi_status(VALUE, VALUE, VALUE); -VALUE ffi_sysdef(VALUE, VALUE, VALUE); diff --git a/lib/bsd/control.rb b/lib/bsd/control.rb index f24f2a4..623cc1e 100644 --- a/lib/bsd/control.rb +++ b/lib/bsd/control.rb @@ -1,19 +1,27 @@ module BSD::Control + require_relative "control/context" require_relative "control/feature" Error = Class.new(RuntimeError) + ## + # @return [BSD::Control::Context] + # Returns an instance of {BSD::Control::Context BSD::Control::Context}. + def self.context + @context ||= BSD::Control::Context.new + end + ## # @return [String] # Returns the version of libhbsdcontrol. def self.library_version - FFI.library_version + context.library_version end ## # @return [Array] # Returns an array of available features. def self.available_features - Feature.available + context.available_features end ## diff --git a/lib/bsd/control/context.rb b/lib/bsd/control/context.rb new file mode 100644 index 0000000..982cbb4 --- /dev/null +++ b/lib/bsd/control/context.rb @@ -0,0 +1,7 @@ +module BSD::Control + ## + # The {BSD::Control::Context BSD::Control::Context} class encapsulates + # and persists a clang data structure (hbsdctrl_ctx_t). + class Context + end +end diff --git a/lib/bsd/control/feature.rb b/lib/bsd/control/feature.rb index 46b2f65..49c9679 100644 --- a/lib/bsd/control/feature.rb +++ b/lib/bsd/control/feature.rb @@ -1,10 +1,10 @@ module BSD::Control - class Feature < Struct.new(:name, :enable, :disable) + class Feature < Struct.new(:name, :context) ## # @return [Array] # Returns an array of available features. def self.available - BSD::Control::FFI.available_features + BSD::Control.available_features end ## @@ -22,7 +22,7 @@ module BSD::Control # @return [Boolean] # Returns true on success. def enable!(path) - set!(path, BSD::Control::Enable) + set!(path, 1) end ## @@ -37,7 +37,7 @@ module BSD::Control # @return [Boolean] # Returns true on success. def disable!(path) - set!(path, BSD::Control::Disable) + set!(path, 0) end ## diff --git a/test/superuser/disable_feature_test.rb b/test/superuser/disable_feature_test.rb index 11468f0..71f04ec 100644 --- a/test/superuser/disable_feature_test.rb +++ b/test/superuser/disable_feature_test.rb @@ -4,9 +4,9 @@ module BSD::Control require 'fileutils' include FileUtils - def test_disable_mprotect_nonexistent_file + def test_disable_pageexec_nonexistent_file assert_raises(Errno::ENOENT) do - BSD::Control.feature(:mprotect).disable!(file) + BSD::Control.feature(:pageexec).disable!(file) end end diff --git a/test/superuser/enable_feature_test.rb b/test/superuser/enable_feature_test.rb index c420fe9..16a2618 100644 --- a/test/superuser/enable_feature_test.rb +++ b/test/superuser/enable_feature_test.rb @@ -4,26 +4,26 @@ module BSD::Control require 'fileutils' include FileUtils - def test_enable_mprotect + def test_enable_pageexec touch(file) - assert BSD::Control.feature(:mprotect).enable!(file), + assert BSD::Control.feature(:pageexec).enable!(file), "The enable! method should have returned true" ensure rm(file) end - def test_enable_mprotect_zero_permissions + def test_enable_pageexec_zero_permissions touch(file) chmod(0, file) - assert BSD::Control.feature(:mprotect).enable!(file), + assert BSD::Control.feature(:pageexec).enable!(file), "The enable! method should have returned true" ensure rm(file) end - def test_enable_mprotect_nonexistent_file + def test_enable_pageexec_nonexistent_file assert_raises(Errno::ENOENT) do - BSD::Control.feature(:mprotect).enable!(file) + BSD::Control.feature(:pageexec).enable!(file) end end diff --git a/test/superuser/feature_status_test.rb b/test/superuser/feature_status_test.rb index 63ab751..11b870b 100644 --- a/test/superuser/feature_status_test.rb +++ b/test/superuser/feature_status_test.rb @@ -4,29 +4,29 @@ module BSD::Control require 'fileutils' include FileUtils - def test_mprotect_sysdef_status + def test_pageexec_sysdef_status touch(file) assert_equal :sysdef, - BSD::Control.feature(:mprotect).status(file) + BSD::Control.feature(:pageexec).status(file) ensure rm(file) end - def test_mprotect_enabled_status + def test_pageexec_enabled_status touch(file) - BSD::Control.feature(:mprotect).enable!(file) + BSD::Control.feature(:pageexec).enable!(file) assert_equal :enabled, - BSD::Control.feature(:mprotect).status(file) + BSD::Control.feature(:pageexec).status(file) ensure rm(file) end - def test_mprotect_disabled_status + def test_pageexec_disabled_status touch(file) - BSD::Control.feature(:mprotect).disable!(file) + BSD::Control.feature(:pageexec).disable!(file) assert_equal :disabled, - BSD::Control.feature(:mprotect).status(file) + BSD::Control.feature(:pageexec).status(file) ensure rm(file) end diff --git a/test/unprivileged/disable_feature_test.rb b/test/unprivileged/disable_feature_test.rb index 11468f0..71f04ec 100644 --- a/test/unprivileged/disable_feature_test.rb +++ b/test/unprivileged/disable_feature_test.rb @@ -4,9 +4,9 @@ module BSD::Control require 'fileutils' include FileUtils - def test_disable_mprotect_nonexistent_file + def test_disable_pageexec_nonexistent_file assert_raises(Errno::ENOENT) do - BSD::Control.feature(:mprotect).disable!(file) + BSD::Control.feature(:pageexec).disable!(file) end end diff --git a/test/unprivileged/enable_feature_test.rb b/test/unprivileged/enable_feature_test.rb index f1f6e08..e48ddb5 100644 --- a/test/unprivileged/enable_feature_test.rb +++ b/test/unprivileged/enable_feature_test.rb @@ -7,7 +7,7 @@ module BSD::Control def test_enable_feature_lacks_privileges touch(file) assert_raises(Errno::EPERM) do - BSD::Control.feature(:mprotect).enable!(file) + BSD::Control.feature(:pageexec).enable!(file) end ensure rm(file) diff --git a/test/unprivileged/feature_test.rb b/test/unprivileged/feature_test.rb index 26c6e80..566171b 100644 --- a/test/unprivileged/feature_test.rb +++ b/test/unprivileged/feature_test.rb @@ -1,9 +1,9 @@ require_relative "../setup" module BSD::Control class FeatureTest < Test::Unit::TestCase - def test_mprotect_feature + def test_pageexec_feature assert_instance_of BSD::Control::Feature, - BSD::Control.feature(:mprotect) + BSD::Control.feature(:pageexec) end def test_nonexistent_feature diff --git a/test/unprivileged/sysdef_test.rb b/test/unprivileged/sysdef_test.rb index ef11f77..734edc2 100644 --- a/test/unprivileged/sysdef_test.rb +++ b/test/unprivileged/sysdef_test.rb @@ -7,7 +7,7 @@ module BSD::Control def test_sysdef!_lacks_privileges touch(file) assert_raises(Errno::EPERM) do - BSD::Control.feature(:mprotect).sysdef!(file) + BSD::Control.feature(:pageexec).sysdef!(file) end ensure rm(file)