| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
Export the function xappendword() from make. Use it in drop and
watch.
Saves 8-80 bytes, an unusually large disparity.
|
|
|
|
|
|
|
| |
Rewrite the test for the reduced-privilege token: check whether
the BUILTIN\Administrators group is enabled. This seems more
directly relevant than the previous check for restrictions on
the token.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add cdrop and pdrop applets as aliases for drop. If a command
isn't specified these use cmd.exe and PowerShell instead of the
BusyBox shell.
This makes it possible to choose the default shell used for SSH
connections even in older versions of OpenSSH that don't support
the DefaultShellArguments registry key.
Note that to get cmd.exe to run a command rather than an interactive
shell it's necessary to set the DefaultShellCommandOption registry
key to '/c'.
Costs 248-272 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove the runuser applet, leaving only drop. Move drop from
util-linux to miscutils.
A command of the form 'drop -c command' causes the BusyBox shell
to be used, just like 'drop' without any arguments. A simple
OpenSSH configuration with 'drop.exe' as DefaultShell and no
DefaultShellArguments now works both for interactive login and
to run a command. This is useful for older versions of OpenSSH
which don't support DefaultShellArguments.
Saves 208-232 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The 'drop' alias for 'runuser' relaxes a number of constraints
that were introduced for compatibility:
- It works even if the current process doesn't have elevated
privileges.
- It isn't necessary to specify the name of the user.
- Any command can be invoked, not just the BusyBox shell.
- If the command doesn't specify a path 'drop' will first look for
a BusyBox applet then search PATH.
Adds 320-336 when built along with runuser.
(GitHub issue #240)
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a function, file_is_win32_exe(), to detect if a path refers
to an executable. It tries adding extensions if necessary.
Use this in a number of places to replace common code of the form
path = alloc_ext_space(cmd);
if (add_win32_extension(path) || file_is_executable(path))
Saves 32-48 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a cut down, Windows-specific implementation of `runuser` from
util-linux.
This allows elevated privileges to be dropped when running in an
SSH session. It also works when using `su` or starting busybox-w32
'as administrator'.
There are complications:
- The method used to drop privileges leaves the access token in the
TokenIsElevated state. Detecting this is likely to be fragile.
- The unprivileged shell is started by CreateProcessAsUserA(). In
older versions of Windows this has to be loaded dynamically.
Adds about 900 bytes.
(GitHub issue #240)
|
|
|
|
|
|
|
|
|
|
| |
Commit 88965fe20 (win32: use ACL check to clarify write permission)
added code to check if a file had write permission due to an ACL
entry.
When running with elevated privileges this check is unnecessary as
"user" permissions will be sufficient. This also prevents write
permission for "other" being set without respecting umask.
|
|
|
|
|
|
|
| |
Fix remove_cr() so it only removes CRs which are part of a CRLF
pair, not every CR.
Add a test case for the shell.
|
|
|
|
|
|
|
|
| |
Use FILE_SHARE_READ when opening a file to check if it's an
executable. Without that other processes running in parallel
might be unable to access the file.
(GitHub issue #284)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 7fb95a2a5 (win32: try to get link count for directories)
allowed stat(2) to report accurate values of st_nlink for
directories.
There are only a couple of places in busybox-w32 where these values
are required. Disable counting of subdirectories by default and
only enable it when necessary.
Microsoft kindly provide directories to test edge cases like this:
C:/Windows/WinSxS (contains many subdirectories)
C:/Windows/WinSxS/Manifests (contains many files)
Adds 84-112 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function get_proc_addr() facilitates dynamic loading of functions
from DLLs. In the event of failure it set errno to ENOSYS.
This is sometimes useful, such as in the implementations of link(2),
symlink(2) and realpath(3). However, many other uses of lazy loading
can recover from failure or simply don't care. In these cases setting
errno is unnecessary and may be counterproductive.
(GitHub issue #283)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous commit incorrectly stated that preventing the access
time of a file from being updated only required it to be opened
with GENERIC_READ access. In fact, even though we don't want to
update the access time, SetFileTime() also requires the file to
have been opened with FILE_WRITE_ATTRIBUTES access.
There's no need to explicitly avoid device files when checking
for execute mode: since device files are now 'character special'
they are excluded by the test that the file is 'regular'.
Device files should be excluded when trying to obtain extra file
data using GetFileInformationByHandle(). It shouldn't be possible
for CreateFile() to open then, so there's no point in trying.
|
|
|
|
|
|
|
|
|
|
|
| |
Commit b11352dcb (win32: prevent stat(2) from updating access times)
requested GENERIC_ALL access when opening files. It appears that
GENERIC_READ is sufficient and also faster.
The code to find the actual size of compressed or sparse files only
needs to be invoked for regular files. Avoiding unnecessary calls
to GetCompressedFileSize() makes stat(2) slightly faster and gives
a more accurate number of blocks for symbolic links.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On Microsoft Windows a user's home directory doesn't belong to
them: it actually belongs to the 'system' user. stat(2) was
only using ownership to determine write permissions, so it seemed
that the user was unable to write to their own home directory.
Use a call to AccessCheck() to determine if files can be accessed
due to an entry in their ACL. User home directories and a few other
files (e.g. C:/Users/Public) now have the correct write permission.
This feature is enabled by FEATURE_EXTRA_FILE_DATA.
Costs 220-256 bytes.
(GitHub issue #280)
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 15fcbd19c8 (win32: special case for devices files in stat(2))
caused write permissions on directories to respect the read-only
attribute. This is incorrect: the read-only attribute doesn't
apply to directories in the same way as to normal files.
Give directories write permission unconditionally, as before, though
respecting umask.
(GitHub issue #280)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The WIN32 implementation of stat(2) reads the contents of some files
to see if they're executable. This may update the file access time.
Avoid this by a special call to SetFileTime() after opening the file.
For details see:
https://devblogs.microsoft.com/oldnewthing/20111010-00/?p=9433
https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime
File access times aren't updated by default in recent versions of
Windows. This commit is only necessary if updating of file access
times is explicitly enabled:
fsutil behavior set DisableLastAccess 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 605972390 (win32: handle Unix-style absolute paths for
executables) added special treatment of paths for executables
starting with a slash. Such paths are absolute on Unix but are
relative to the current drive on Windows. On reflection this
commit did more than necessary. Later commits provided special
treatment only for paths starting with locations traditionally
used to contain binaries on Unix. This is probably sufficient.
Problems introduced by commit 605972390 include:
- If the current drive isn't the system drive tab completion of a
command starting with a slash confusingly references the system
drive.
- Building busybox-w32 with w64devkit fails on drives other than
the system drive.
Revert the changes introduced by commit 605972390.
This saves 192 bytes.
(GitHub issue #239)
|
|
|
|
|
|
|
|
| |
Commit 31467ddfc (win32: changes to stat(2) implementation) followed
symlinks manually. Unfortunately the implementation was incorrect.
Use xmalloc_follow_symlinks() instead.
Saves 32-48 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Scoop uses PowerShell's New-Item to create junctions. However,
these junctions lack a PrintName. This is a known issue which
has caused problems even for Windows' File Explorer:
https://github.com/PowerShell/PowerShell/issues/12923
Revert commit 32de287bb (win32: code shrink readlink(2)) to that
readlink(2) uses SubstituteName instead.
(GitHub issue #261)
|
|
|
|
|
|
|
|
|
|
|
| |
- Use repeated calls to readlink(2) rather than xmalloc_realpath()
when asked to follow symlinks.
- Drop the non-standard feature that caused readlink(2) to return
only the target string length.
This improves compatibility with BusyBox on Linux at a cost of
16-32 bytes.
|
|
|
|
| |
Reduce duplicated code. Saves 16-48 bytes.
|
|
|
|
|
|
| |
Previously stat(2) set st_size to the length of the canonicalised
symlink target. Call readlink(2) to get the actual length of the
target string.
|
|
|
|
|
|
|
| |
Use PrintName rather than SubstituteName from the reparse data
buffer. This avoids the need to normalise the name.
Saves 240 bytes.
|
|
|
|
|
|
|
|
|
|
| |
Add a function to check if a file is a directory and use it in
various places.
Replace some uses of S_ISDIR() with a test of the Windows file
attributes.
Saves 32-48 bytes.
|
|
|
|
|
|
|
|
| |
If a file is a junction or symlink return its tag in the st_tag
member of struct stat.
get_symlink_data() and is_symlink() also return the tag or zero,
as appropriate.
|
|
|
|
|
|
|
| |
Junctions created by 'jn' contained incorrect data: the length
of the target name was off-by-one.
(GitHub issue #251)
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a Windows-specific applet to create a directory junction.
Usage: jn DIR JUNC
where DIR must be an existing directory on a local drive and JUNC
must not currently exist.
There isn't a simple WIN32 API to create directory junctions.
The implementation of mklink in ReactOS provided useful inspiration.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On Unix the link count of a directory reflects the number of
subdirectories it contains. Enhance readdir(3) to return file
types and use this to count subdirectories when stat(2) is called
for a directory.
As with other features that might slow down stat(2) this is
controlled by the build-time setting FEATURE_EXTRA_FILE_DATA.
(Commit d82db8e9a 'win32: make stat(2) fetch additional metadata').
(GitHub issue #254)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Directory junctions were always followed to their target so they
appeared to *be* directories. This resulted in counter-intuitive
behaviour:
- a directory junction could be removed with rmdir even though
the directory wasn't empty;
- 'rm -rf' on a directory junction deleted it but also deleted
the contents of the linked directory.
A better approximation is to treat directory junctions as
symbolic links.
(GitHub issue #254)
|
|
|
|
|
|
|
|
|
|
|
| |
The environment variables BB_OVERRIDE_APPLETS, BB_SKIP_ANSI_EMULATION
and BB_SYSTEMROOT affect of the behaviour of the shell itself.
Setting them as shell variables is insufficient for them to affect
the current shell.
When these three variables are exported from the shell they are
now placed in the environment immediately. Conversely, when
they're unset or unexported they're removed from the environment.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 69d328022 (win32: track current directory of mapped drives)
replaced a call to xmalloc_realpath() with one to xmalloc_readlink().
This was incorrect. Although the argument is now guaranteed to
be a symlink it's still necessary to resolve it to an absolute path.
Otherwise the fix in commit 585d17d26 (win32: canonicalize path in
chdir(2)) doesn't work for symlinks with a relative path as their
target.
(GitHub issue #147)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 41ef232fc5 (win32: use built-in applets for non-existent
binaries with Unix-style paths) alters what happens when trying
to find an executable. If all of the following apply:
- the pathname starts with one of the standard directories for Unix
executables (/bin, /usr/bin, /sbin, /usr/sbin);
- the file isn't found relative to the system root;
- the basename matches an applet
then the applet is run.
Further extend the procedure so that if the first two conditions are
met and either:
- the PREFER_APPLETS and SH_STANDALONE features are enabled and the
basename *doesn't* match an applet
or
- the PREFER_APPLETS and SH_STANDALONE features are disabled
then PATH is searched for the basename.
This affects:
- how interpreters and binaries are spawned by mingw_spawn_interpreter()
and mingw_spawnvp();
- how 'which' and the shell search for binaries.
Special steps need to be taken in the shell to avoid treating shell
built-ins and functions as applets.
As a consequence of this change:
- An executable that isn't an applet, say curl.exe, can be run as
/usr/bin/curl so long as it's in a directory in PATH. It doesn't
have to be in C:/usr/bin.
- If the PREFER_APPLETS and SH_STANDALONE features are disabled binaries
can be run using paths referring to standard Unix directories even if
they're installed elsewhere in PATH.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change how 'which' detects if it was run from a standalone shell:
the shell passes the undocumented '-s' option. This is stricter
and more reliable than the previous method of checking the name
of the binary.
Add a function to determine the binary associated with a given
applet name. This makes it possible for 'which' and 'command -v'
to list the correct binary even for applets other than 'busybox'.
For example, when the binary is called 'sh.exe' 'which sh' will
report its path.
In standalone shell mode 'command -V' and 'type' now report "xxx
is a builtin applet" rather than "xxx is xxx", which is true but
not very illuminating.
(GitHub issue #248)
|
| |
|
|
|
|
|
|
|
|
|
| |
Provide a WIN32 implementation of clock_gettime(2), though only
with support for CLOCK_REALTIME. This makes it possible to enable
FEATURE_DATE_NANO which adds support for the %N date format.
MinGW-w64 has clock_gettime(2) but it's in the winpthreads library
and we don't want to bother with that.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mask the file permission bits in mingw_umask(), not when it's
called from run_applet_no_and_exit().
Rather than hardcode write permissions for group and other in
file_attr_to_st_mode() and mingw_fstat() make them respect the
current umask setting.
In mingw_fstat() there's no need to check the mode using S_ISDIR():
the hardcoded mode doesn't set S_IFDIR. The compiler had already
figured this out so there's no reduction in bloat.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
busybox-w32 tries to display the ownership of files by comparing
the security identifier (SID) of the current user with that of the
file on disk. For filesystems that don't support SIDs this resulted
in files being listed as owned by root.
It appears that filesystems without support for file ownership
return a null SID. In such cases pretend the file belongs to the
current user.
GitHub issue #241.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 35e32c2a71 (readlink(): do `NUL`-terminate the result) changed
how our implementation of readlink(2) handles the case where the link
is too long for the buffer. This broke xmalloc_readlink() which
expects readlink(2) to behave as documented. As a results symbolic
links with 80 or more characters didn't work properly.
Revert the commit.
(GitHub issue #237)
|
|
|
|
|
|
|
|
| |
On Linux rmdir(2) refuses to delete a symlink to a directory on
the obvious grounds that a symlink isn't a directory. Windows'
rmdir() is less discriminating.
Make our implementation of rmdir(2) behave more like Linux.
|
|
|
|
|
|
|
|
|
| |
There are a few places in mingw.c where we want to determine if a
file is a symbolic link. Previously these called mingw_lstat()
which collects far more information than is actually needed.
Create a new is_symlink() function which does the minimum work
necessary.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Upstream commit 94eb1c4dc (libbb: better coreutils compatibility
for realpath) made some changes to xmalloc_realpath_coreutils().
This now needs to be updated to handle Windows paths.
- Expose the macro is_unc_path() and part of the recent change to
bb_get_last_path_component_nostrip() as a separate funtion,
get_last_slash();
- Convert a couple of errors relating to network filesystems to
ENOENT;
- Adjust xmalloc_realpath_coreutils() to handle Windows directory
separators, relative paths and UNC paths.
|
|
|
|
|
|
|
|
| |
Symlinks containing '.' or '..' (such as '../target', './target' or
'dir/./target') were successfully created but couldn't be accessed.
It turns out Windows requires paths of that form to use backslashes
rather than forward slashes.
|
|
|
|
|
| |
As the comment pointed out is_absolute_path() was misnamed. Rename
it to is_relative_path() and change the sense of all tests.
|
|
|
|
|
| |
The is_dir_sep() macro, which has been around since the start of
busybox-w32, can be used instead of is_path_sep().
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow waitpid() to detect SIGTERM/SIGKILL by checking the (Windows)
status returned by GetExitCodeProcess() and updating the Unix
status to suit. This allows ash to detect when a process has been
'signalled'.
Provide our own implementation of strsignal(3) which returns
expanded text for SIGTERM/SIGKILL.
Costs 192 bytes.
|
|
|
|
|
|
|
|
| |
Turn off the 'if-conversion' optimisation for err_win_to_posix().
My tests actually have this being slightly faster than with the
optimisation enabled, though within the variation of the measurement.
Saves 288 bytes.
|
|
|
|
| |
Saves 176 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a new function, getsysdir(), to fetch and cache the system
directory. This avoids the non-intuitive use of getpwuid() in
get_system_drive().
The call to GetSystemDirectory() in get_proc_addr() can't be
replaced because getsysdir() calls realpath() which requires a
call to get_proc_addr().
No change in the size of the binary.
|
|
|
|
|
|
|
|
|
| |
There doesn't seem to be any need to call OpenThreadToken() in
file_owner(): OpenProcessToken() should suffice.
Also, tidy up gethomedir() without any change in functionality.
Saves 56 bytes.
|