Commit cfc7307
committed
sh_exec(): do not save/restore PWD for non-BLT_ENV builtins
The question-everything department reporting for duty once again.
Version 2005-05-22 ksh93q+ introduced code that saves the inode and
path of the present working directory before invoking a built-in
command without the BLT_ENV attribute (see data/builtins.c). When
the built-in completes, it gets the PWD's inode again and compares.
If they're different, it uses chdir(2) to change back to the old
working directory.
The corresponding commit in the ksh93-history repo contains no
relevant entries in src/cmd/ksh93/RELEASE so no form of rationale
for this addition is available.
Changing back to a previous directory by path name is unsafe,
because the directory may have been removed and even replaced by a
completely different one by then. This is a common vector for
symlink attacks.
In the 93v- beta, this code was improved to use fstat(2) and
fchdir(2) to guarantee changing back to the same directory.
But is this worth doing at all? Why should a built-in not be able
to change the current working directory? If it's not intended to do
this, it simply should not do it. Even in the case of dynamically
loadable third-party built-ins, we're running built-in code in the
same process as ksh, so we've already decided the code is trusted.
If it's not, there are far worse things than $PWD to worry about.
Not only that, this code comes at a performance hit as the file
system is accessed before and after running a non-BLT_ENV builtin.
Before removing this:
$ arch/*/bin/ksh.old -c 'typeset -i i; \
time for((i=0;i<=100000;i++)); do sleep 0; done >/dev/null'
real 0m00.83s
user 0m00.40s
sys 0m00.42s
After removing this:
$ arch/*/bin/ksh -c 'typeset -i i; \
time for((i=0;i<=100000;i++)); do sleep 0; done >/dev/null'
real 0m00.25s
user 0m00.25s
sys 0m00.00s
Removing this nonsense causes no regressions -- which is obvious.
because none of our built-ins except 'cd' change the PWD.1 parent 148a8a3 commit cfc7307
1 file changed
+0
-14
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1232 | 1232 | | |
1233 | 1233 | | |
1234 | 1234 | | |
1235 | | - | |
1236 | 1235 | | |
1237 | 1236 | | |
1238 | 1237 | | |
1239 | | - | |
1240 | 1238 | | |
1241 | 1239 | | |
1242 | 1240 | | |
| |||
1288 | 1286 | | |
1289 | 1287 | | |
1290 | 1288 | | |
1291 | | - | |
1292 | | - | |
1293 | | - | |
1294 | | - | |
1295 | 1289 | | |
1296 | 1290 | | |
1297 | 1291 | | |
| |||
1364 | 1358 | | |
1365 | 1359 | | |
1366 | 1360 | | |
1367 | | - | |
1368 | | - | |
1369 | | - | |
1370 | | - | |
1371 | | - | |
1372 | | - | |
1373 | | - | |
1374 | | - | |
1375 | 1361 | | |
1376 | 1362 | | |
1377 | 1363 | | |
| |||
0 commit comments