envameleon 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +49 -7
- data/ext/envameleon/envameleon.c +17 -15
- data/ext/envameleon/extconf.rb +20 -0
- data/lib/envameleon.rb +27 -4
- metadata +65 -6
- data/assets/envameleon.png +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7597e5b1a9244904d1e811799087794525411e88ce6e00fccbdfb2e07a7bc36
|
|
4
|
+
data.tar.gz: d479fbcf8616eec177bfea1619003c164a262ed04e230620985ded862db78543
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e6c69a2cdd21f92abde6d1b34298020f3b8052152c3a89e2c99d25ef1591a6f52d19f35469a415bedd69f00e9141e9edc1dc8ef282fb0063532ec5088161a24
|
|
7
|
+
data.tar.gz: 5e5084c3dc7700201f8da011b1d9c41882481b3446a4c21ca65c8fc2fee7d1b2e8e60d4b1dda4f3af10aa5fd2531722a9f1a64f94168b84e04b0befb2c001b58
|
data/README.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
- [About](#about)
|
|
21
21
|
- [Getting Started](#getting-started)
|
|
22
|
+
- [Native Gems](#native-gems)
|
|
22
23
|
- [Usage](#usage)
|
|
23
24
|
- [How It Works](#how-it-works)
|
|
24
25
|
- [Process Inheritance](#process-inheritance)
|
|
@@ -56,7 +57,7 @@ app chooses when to call one of its three methods.
|
|
|
56
57
|
- Linux for changes to `/proc/self/environ`
|
|
57
58
|
- The Linux `CAP_SYS_RESOURCE` right only for `ENV.drop_proc_data`
|
|
58
59
|
|
|
59
|
-
On
|
|
60
|
+
On macOS and Windows, all three methods are safe no-ops.
|
|
60
61
|
|
|
61
62
|
### Installation
|
|
62
63
|
|
|
@@ -80,6 +81,35 @@ require "envameleon"
|
|
|
80
81
|
|
|
81
82
|
[Back to top](#readme-top).
|
|
82
83
|
|
|
84
|
+
## Native Gems
|
|
85
|
+
|
|
86
|
+
ENVameleon publishes precompiled native gems for its supported CRuby minors on:
|
|
87
|
+
|
|
88
|
+
- GNU/Linux and musl Linux on x86-64 and AArch64
|
|
89
|
+
|
|
90
|
+
The macOS and Windows gems contain the documented pure-Ruby no-ops. There is no
|
|
91
|
+
native code to compile on those systems. Linux is split into `-linux-gnu` and
|
|
92
|
+
`-linux-musl` gems so a glibc binary is never mistaken for a musl binary. These
|
|
93
|
+
native gems require RubyGems 3.3.22 or newer; musl users should use Bundler
|
|
94
|
+
2.5.6 or newer.
|
|
95
|
+
|
|
96
|
+
Each precompiled Linux gem contains a separate binary for every supported Ruby
|
|
97
|
+
minor and has no extension build hook. When Linux runs a newer Ruby API,
|
|
98
|
+
RubyGems or Bundler selects the generic source gem instead. That gem runs
|
|
99
|
+
`extconf.rb` and requires a C compiler, Make, and the Ruby headers. macOS and
|
|
100
|
+
Windows continue to select their compiler-free no-op gems. If neither a native
|
|
101
|
+
nor source fallback applies on Linux, `require "envameleon"` fails closed
|
|
102
|
+
instead of silently exposing the process environment.
|
|
103
|
+
|
|
104
|
+
Every GitHub release includes the gems and `SHA256SUMS`. Release gems also have
|
|
105
|
+
GitHub build-provenance attestations, which can be checked with:
|
|
106
|
+
|
|
107
|
+
```console
|
|
108
|
+
gh attestation verify envameleon-0.2.0-x86_64-linux-gnu.gem --repo kpumuk/envameleon
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
[Back to top](#readme-top).
|
|
112
|
+
|
|
83
113
|
## Usage
|
|
84
114
|
|
|
85
115
|
```ruby
|
|
@@ -213,21 +243,33 @@ overwrites the old proc range, but a secret may still exist elsewhere.
|
|
|
213
243
|
|
|
214
244
|
## Development
|
|
215
245
|
|
|
216
|
-
|
|
246
|
+
Install the checksum-locked development bundle and run the `test/unit` suite.
|
|
247
|
+
The test task compiles the extension on Linux and exercises the pure-Ruby no-ops
|
|
248
|
+
elsewhere:
|
|
217
249
|
|
|
218
250
|
```console
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
ruby -Ilib -Iext test/test_envameleon.rb
|
|
251
|
+
bundle install
|
|
252
|
+
bundle exec rake test
|
|
222
253
|
```
|
|
223
254
|
|
|
224
255
|
On Linux, the drop test runs when `CAP_SYS_RESOURCE` is available. Otherwise,
|
|
225
256
|
that one test is omitted.
|
|
226
257
|
|
|
227
|
-
Build the
|
|
258
|
+
Build the macOS and Windows no-op gems and the Linux source fallback with:
|
|
259
|
+
|
|
260
|
+
```console
|
|
261
|
+
bundle exec rake gem
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Native builds run inside the versioned image selected by the
|
|
265
|
+
checksum-locked `rake-compiler-dock` gem. The image installs the exact Bundler
|
|
266
|
+
version recorded in `Gemfile.lock`; Bundler then validates its own locked
|
|
267
|
+
checksum and installs every other dependency from the prepared local cache:
|
|
228
268
|
|
|
229
269
|
```console
|
|
230
|
-
|
|
270
|
+
bundle cache --all-platforms
|
|
271
|
+
bundle exec rake gem:x86_64-linux-gnu
|
|
272
|
+
ruby .github/scripts/verify_native_gem.rb pkg/envameleon-0.2.0-x86_64-linux-gnu.gem x86_64-linux-gnu
|
|
231
273
|
```
|
|
232
274
|
|
|
233
275
|
## License
|
data/ext/envameleon/envameleon.c
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
#include <stdlib.h>
|
|
8
8
|
#include <string.h>
|
|
9
9
|
#include <sys/prctl.h>
|
|
10
|
-
#include <linux/prctl.h>
|
|
11
10
|
|
|
12
11
|
static void
|
|
13
12
|
read_env_range(unsigned long *env_start, unsigned long *env_end)
|
|
@@ -16,22 +15,26 @@ read_env_range(unsigned long *env_start, unsigned long *env_end)
|
|
|
16
15
|
char *field;
|
|
17
16
|
char *end;
|
|
18
17
|
FILE *file = fopen("/proc/self/stat", "r");
|
|
18
|
+
int error = 0;
|
|
19
19
|
int number;
|
|
20
|
+
size_t length;
|
|
20
21
|
|
|
21
22
|
if (file == NULL)
|
|
22
23
|
rb_sys_fail("fopen(/proc/self/stat)");
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (error != 0) {
|
|
28
|
-
errno = error;
|
|
29
|
-
rb_sys_fail("fgets(/proc/self/stat)");
|
|
30
|
-
}
|
|
31
|
-
rb_raise(rb_eRuntimeError, "empty /proc/self/stat");
|
|
32
|
-
}
|
|
25
|
+
length = fread(stat, 1, sizeof(stat), file);
|
|
26
|
+
if (ferror(file))
|
|
27
|
+
error = errno == 0 ? EIO : errno;
|
|
33
28
|
fclose(file);
|
|
34
29
|
|
|
30
|
+
if (error != 0)
|
|
31
|
+
rb_syserr_fail(error, "fread(/proc/self/stat)");
|
|
32
|
+
if (length == sizeof(stat))
|
|
33
|
+
rb_raise(rb_eRuntimeError, "/proc/self/stat is too large");
|
|
34
|
+
if (length == 0)
|
|
35
|
+
rb_raise(rb_eRuntimeError, "empty /proc/self/stat");
|
|
36
|
+
stat[length] = '\0';
|
|
37
|
+
|
|
35
38
|
field = strrchr(stat, ')');
|
|
36
39
|
if (field == NULL || field[1] != ' ')
|
|
37
40
|
rb_raise(rb_eRuntimeError, "invalid /proc/self/stat");
|
|
@@ -98,16 +101,15 @@ mask_proc_data(VALUE environment)
|
|
|
98
101
|
size_t remaining = (char *)env_end - entry;
|
|
99
102
|
char *terminator = memchr(entry, '\0', remaining);
|
|
100
103
|
char *equals;
|
|
101
|
-
char *value;
|
|
102
|
-
size_t value_length;
|
|
103
104
|
|
|
104
105
|
if (terminator == NULL)
|
|
105
106
|
rb_raise(rb_eRuntimeError, "invalid environment data");
|
|
106
107
|
|
|
107
108
|
equals = memchr(entry, '=', terminator - entry);
|
|
108
109
|
if (equals != NULL) {
|
|
109
|
-
value = equals + 1;
|
|
110
|
-
value_length = terminator - value;
|
|
110
|
+
char *value = equals + 1;
|
|
111
|
+
size_t value_length = terminator - value;
|
|
112
|
+
|
|
111
113
|
if (value_length > 2)
|
|
112
114
|
memset(value + 1, '*', value_length - 2);
|
|
113
115
|
}
|
|
@@ -154,7 +156,7 @@ drop_proc_data(VALUE environment)
|
|
|
154
156
|
}
|
|
155
157
|
#endif
|
|
156
158
|
|
|
157
|
-
void
|
|
159
|
+
RUBY_FUNC_EXPORTED void
|
|
158
160
|
Init_envameleon(void)
|
|
159
161
|
{
|
|
160
162
|
ID environment_id = rb_intern2("ENV", 3);
|
data/ext/envameleon/extconf.rb
CHANGED
|
@@ -2,4 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
require "mkmf"
|
|
4
4
|
|
|
5
|
+
append_cflags %w[
|
|
6
|
+
-Wall
|
|
7
|
+
-Wextra
|
|
8
|
+
-Wformat=2
|
|
9
|
+
-Werror=format-security
|
|
10
|
+
-Werror=implicit-function-declaration
|
|
11
|
+
-fstack-protector-strong
|
|
12
|
+
-fvisibility=hidden
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
if RUBY_PLATFORM.include?("linux")
|
|
16
|
+
append_cflags "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3"
|
|
17
|
+
|
|
18
|
+
append_ldflags %w[
|
|
19
|
+
-Wl,-z,noexecstack
|
|
20
|
+
-Wl,-z,now
|
|
21
|
+
-Wl,-z,relro
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
|
|
5
25
|
create_makefile("envameleon/envameleon")
|
data/lib/envameleon.rb
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
require "rbconfig"
|
|
4
|
+
|
|
5
|
+
ruby_api_version = RUBY_VERSION[/\A\d+\.\d+/]
|
|
6
|
+
native_extension = File.expand_path(
|
|
7
|
+
"envameleon/#{ruby_api_version}/envameleon.#{RbConfig::CONFIG.fetch("DLEXT")}",
|
|
8
|
+
__dir__
|
|
9
|
+
)
|
|
10
|
+
development_extension = File.expand_path(
|
|
11
|
+
"envameleon/envameleon.#{RbConfig::CONFIG.fetch("DLEXT")}",
|
|
12
|
+
__dir__
|
|
13
|
+
)
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
if RbConfig::CONFIG.fetch("host_os").include?("linux")
|
|
16
|
+
extension = [native_extension, development_extension].find { |path| File.file?(path) }
|
|
17
|
+
if extension
|
|
18
|
+
require extension
|
|
19
|
+
else
|
|
20
|
+
begin
|
|
21
|
+
require "envameleon/envameleon"
|
|
22
|
+
rescue LoadError => error
|
|
23
|
+
raise unless error.path == "envameleon/envameleon"
|
|
24
|
+
|
|
25
|
+
raise LoadError, "ENVameleon has no native extension for Ruby #{ruby_api_version} on #{RUBY_PLATFORM}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
require_relative "envameleon/noop"
|
|
30
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,70 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: envameleon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmytro Shteflyuk
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rake
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '13.2'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '13.2'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rake-compiler
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.3.1
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.3.1
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake-compiler-dock
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.12'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.12'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: test-unit
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '3.7'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.7'
|
|
12
68
|
description: Scrub, mask, or drop Linux's /proc/self/environ view without changing
|
|
13
69
|
Ruby's ENV.
|
|
14
70
|
executables: []
|
|
@@ -18,13 +74,16 @@ extra_rdoc_files: []
|
|
|
18
74
|
files:
|
|
19
75
|
- LICENSE.txt
|
|
20
76
|
- README.md
|
|
21
|
-
- assets/envameleon.png
|
|
22
77
|
- ext/envameleon/envameleon.c
|
|
23
78
|
- ext/envameleon/extconf.rb
|
|
24
79
|
- lib/envameleon.rb
|
|
80
|
+
homepage: https://github.com/kpumuk/envameleon
|
|
25
81
|
licenses:
|
|
26
82
|
- MIT
|
|
27
|
-
metadata:
|
|
83
|
+
metadata:
|
|
84
|
+
bug_tracker_uri: https://github.com/kpumuk/envameleon/issues
|
|
85
|
+
rubygems_mfa_required: 'true'
|
|
86
|
+
source_code_uri: https://github.com/kpumuk/envameleon
|
|
28
87
|
rdoc_options: []
|
|
29
88
|
require_paths:
|
|
30
89
|
- lib
|
|
@@ -32,14 +91,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
32
91
|
requirements:
|
|
33
92
|
- - ">="
|
|
34
93
|
- !ruby/object:Gem::Version
|
|
35
|
-
version:
|
|
94
|
+
version: 4.1.0.dev
|
|
36
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
96
|
requirements:
|
|
38
97
|
- - ">="
|
|
39
98
|
- !ruby/object:Gem::Version
|
|
40
99
|
version: '0'
|
|
41
100
|
requirements: []
|
|
42
|
-
rubygems_version:
|
|
101
|
+
rubygems_version: 4.0.16
|
|
43
102
|
specification_version: 4
|
|
44
103
|
summary: Leave no ENVidence.
|
|
45
104
|
test_files: []
|
data/assets/envameleon.png
DELETED
|
Binary file
|