Not every compilers understand that rb_raise does not return. When a
function does not end with a return statement, such compilers can issue
warnings. We would better tell them about reachabilities.
Allow the 'Dir.home' method to reliably locate the user's home directory when
all three of the following are true at the same time:
1. Ruby is running on a Unix-like OS
2. The $HOME environment variable is not set
3. The process is not a descendant of login(1) (or a work-alike)
The prior behavior was that the lookup could only work for login-descended
processes.
This is accomplished by looking up the user's record in the password database
by uid (getpwuid_r(3)) as a fallback to the lookup by name (getpwname_r(3))
which is still attempted first (based on the name, if any, returned by
getlogin_r(3)).
If getlogin_r(3), getpwnam_r(3), and/or getpwuid_r(3) is not available at
compile time, will fallback on using their respective non-*_r() variants:
getlogin(3), getpwnam(3), and/or getpwuid(3).
The rationale for attempting to do the lookup by name prior to doing it by uid
is to accommodate the possibility of multiple login names (each with its own
record in the password database, so each with a potentially different home
directory) being mapped to the same uid (as is explicitly allowed for by
POSIX; see getlogin(3posix)).
Preserves the existing behavior for login-descended processes, and adds the
new capability of having Dir.home being able to find the user's home directory
for non-login-descended processes.
Fixes [Bug #16787]
Related discussion:
https://bugs.ruby-lang.org/issues/16787https://github.com/ruby/ruby/pull/3034
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead. This would significantly
speed up incremental builds.
We take the following inclusion order in this changeset:
1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very
first thing among everything).
2. RUBY_EXTCONF_H if any.
3. Standard C headers, sorted alphabetically.
4. Other system headers, maybe guarded by #ifdef
5. Everything else, sorted alphabetically.
Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
We want to introduce consistency and better compatibility with unixen,
but the Windows APIs doues not have consistency fundamentally and
we can not found any logical way...
This reverts commit 61aff0cd18.
This removes the related tests, and puts the related specs behind
version guards. This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
This removes the security features added by $SAFE = 1, and warns for access
or modification of $SAFE from Ruby-level, as well as warning when calling
all public C functions related to $SAFE.
This modifies some internal functions that took a safe level argument
to no longer take the argument.
rb_require_safe now warns, rb_require_string has been added as a
version that takes a VALUE and does not warn.
One public C function that still takes a safe level argument and that
this doesn't warn for is rb_eval_cmd. We may want to consider
adding an alternative method that does not take a safe level argument,
and warn for rb_eval_cmd.
Some OS-level security features cause these methods to not return
expected results. For example fs.protected_regular sysctl on Linux,
or pledge(2)/unveil(2) on OpenBSD.
Fixes [Bug #16002]
We can check the function pointer passed to rb_define_global_function
like we do so in rb_define_method. It turns out that almost anybody
is misunderstanding the API.
The result should only be tainted if the path given to the method
was tainted.
The code to always taint the result was added in
a4934a42cb (svn revision 4892) in
2003 by matz. However, the change wasn't mentioned in the
commit message, and it may have been committed by accident.
Skip part of a readline test that uses Reline. Reline in general
would pass the test, but Reline's test mode doesn't raise a
SecurityError if passing a tainted prompt and $SAFE >= 1. This
was hidden earlier because File#path was always returning a
tainted string.
Fixes [Bug #14485]
The result should only be tainted if the path given to the method
was tainted.
The code to always taint the result was added in
a4934a42cb (svn revision 4892) in
2003 by matz. However, the change wasn't mentioned in the
commit message, and it may have been committed by accident.
Skip part of a readline test that uses Reline. Reline in general
would pass the test, but Reline's test mode doesn't raise a
SecurityError if passing a tainted prompt and $SAFE >= 1. This
was hidden earlier because File#path was always returning a
tainted string.
Fixes [Bug #14485]
CI shows it does work on Solaris 11, but does not work on Solaris
10. However, until I figure out a good way to differentiate
between Solaris 10 and 11, this should get CI passing on both.
This approach is simpler than the previous approach which tries to
emulate realpath(3). It also performs much better on both Linux and
OpenBSD on the included benchmarks.
By using realpath(3), we can better integrate with system security
features such as OpenBSD's unveil(2) system call.
This does not use realpath(3) on Windows even if it exists, as the
approach for checking for absolute paths does not work for drive
letters. This can be fixed without too much difficultly, though until
Windows defines realpath(3), there is no need to do so.
For File.realdirpath, where the last element of the path is not
required to exist, fallback to the previous approach, as realpath(3)
on most operating systems requires the whole path be valid (per POSIX),
and the operating systems where this isn't true either plan to conform
to POSIX or may change to conform to POSIX in the future.
glibc realpath(3) does not handle /path/to/file.rb/../other_file.rb
paths, returning ENOTDIR in that case. Fallback to the previous code
if realpath(3) returns ENOTDIR.
glibc doesn't like realpath(3) usage for paths like /dev/fd/5,
returning ENOENT even though the path may appear to exist in the
filesystem. If ENOENT is returned and the path exists, then fall
back to the default approach.
With the SDK of Xcode 10.2.1, `API_AVAILABLE` and so on macros are
not defined in <os/availability.h> when using a compiler other
than clang (which has `__has_feature` and `__has_attribute`), but
`__API_AVAILABLE` macro and so on are defined, which are also
defined in <Availability.h>.
I suspect this is a bug of the SDK.
This string can include elements that were not in either string
passed to File.realpath, even if one of the strings is an
absolute path, due to symlinks:
```ruby
Dir.mkdir('b') unless File.directory?('b')
File.write('b/a', '') unless File.file?('b/a')
File.symlink('b', 'c') unless File.symlink?('c')
path = File.realpath('c/a'.untaint, Dir.pwd.untaint)
path # "/home/testr/ruby/b/a"
path.tainted? # should be true, as 'b' comes from file system
```
[Bug #15803]