Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions master_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ users)

## Opamfile
* The `url` file now only supports the legacy opam 1.2 fields [#6827 @kit-ty-kate]
* Filter fields in .install files containing destinations with `..` or absolute filepaths as parse errors [#6897 @kit-ty-kate]

## External dependencies
* Restore the distribution detection on Gentoo [#6886 @kit-ty-kate - fix #6887]
Expand Down Expand Up @@ -154,6 +155,7 @@ users)
* Add more tests for depexts behaviour with unknown family types [#6489 @arozovyk]
* Add disabled depexts tests [#6489 @rjbou]
* Add depexts tests with debug section that demostrate system availability polling [#6489 @arozovyk]
* Add a test showing the behaviour of .install files containing destination filepath trying to escape their scope [#6897 @rjbou @kit-ty-kate]

### Engine

Expand All @@ -177,6 +179,7 @@ users)
* Correct configure instruction in README [#6858 @gridbugs @kit-ty-kate]

## Security fixes
* Invalidate .install fields containing destination filepath trying to escape their scope [#6897 @kit-ty-kate]

# API updates
## opam-client
Expand Down Expand Up @@ -235,3 +238,4 @@ users)
* `OpamCompat.Map.add_to_list`: was added [#6818 @dra27]
* `OpamSystem`: add `is_dir_read_only` [#6489 @rjbou]
* `OpamFilename`: add `is_dir_read_only` [#6489 @rjbou]
* `OpamFilename.might_escape`: ensure / is detected as a file separator when called with `~sep:Unspecified` on Windows [#6897 @kit-ty-kate]
10 changes: 7 additions & 3 deletions src/core/opamFilename.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@

let might_escape ~sep path =
let sep =
let real_sep = function
| `Unix -> Re.char '/'
| `Windows -> Re.alt Re.[ char '\\'; char '/' ]
in
match sep with
| `Unix -> Re.char '/'
| `Windows -> Re.alt Re.[ char '\\'; char '/' ]
| `Unspecified -> Re.str Filename.dir_sep
| `Unspecified when Sys.win32 -> real_sep `Windows
| `Unspecified -> real_sep `Unix
| `Unix | `Windows as sep -> real_sep sep
in
List.exists (String.equal Filename.parent_dir_name)
Re.(split (compile sep) path)
Expand Down
11 changes: 9 additions & 2 deletions src/format/opamFile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3824,8 +3824,15 @@ module Dot_installSyntax = struct
Pp.V.map_list ~depth:1 @@ Pp.V.map_option
(Pp.V.string -| pp_optional)
(Pp.opt @@
Pp.singleton -| Pp.V.string -|
Pp.of_module "rel-filename" (module OpamFilename.Base))
Pp.singleton -| Pp.V.string -| Pp.pp ~name:"rel-filename"
(fun ~pos s ->
if OpamFilename.might_escape ~sep:`Unspecified s then
Pp.bad_format ~pos "%s references its parent directory." s
else if Filename.is_relative s then
OpamFilename.Base.of_string s
else
Pp.bad_format ~pos "%s is an absolute filename." s)
OpamFilename.Base.to_string)
in
let pp_misc =
Pp.V.map_list ~depth:1 @@ Pp.V.map_option
Expand Down
115 changes: 115 additions & 0 deletions tests/reftests/dot-install.test
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,118 @@ OPAM/rem-dir/lib
OPAM/rem-dir/lib/shared
OPAM/rem-dir/lib/stublibs
OPAM/rem-dir/lib/toplevel
### OPAMDEBUG=0
### unset OPAMDEBUGSECTIONS
### : Escapability
### <pkg:eskape.1>
opam-version: "2.0"
install: [ "echo" "hellow" ]
### <pkg:eskape.1:eskape.install>
lib: [
"a-file" { "../../a-file" }
"fichier" { "/ab/so/lute/path/fichier" }
"dosiero" { "/tmp/../middle/dosiero" }
"good" { "good" }
]
bin: [
"a-file" { "../../a-file" }
"fichier" { "/ab/so/lute/path/fichier" }
"dosiero" { "/tmp/../middle/dosiero" }
"good" { "good" }
]
etc: [
"a-file" { "../../a-file" }
"fichier" { "/ab/so/lute/path/fichier" }
"dosiero" { "/tmp/../middle/dosiero" }
"good" { "good" }
]
share: [
"a-file" { "../../a-file" }
"fichier" { "/ab/so/lute/path/fichier" }
"dosiero" { "/tmp/../middle/dosiero" }
"good" { "good" }
]
misc: [
"a-file" { "../../a-file" }
"fichier" { "/ab/so/lute/path/fichier" }
"dosiero" { "/tmp/../middle/dosiero" }
"good" { "good" }
]
### <pkg:eskape.1:a-file>
hellow
### <pkg:eskape.1:fichier>
bonjour
### <pkg:eskape.1:dosiero>
saluton
### <pkg:eskape.1:good>
hallo
### opam update

<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><>
[default] no changes from file://${BASEDIR}/REPO
### opam switch create escapability --empty
### OPAMDEBUGSECTIONS="SYSTEM" OPAMDEBUG=-5
### opam install eskape
FILE(config) Read ${BASEDIR}/OPAM/config in 0.000s
SYSTEM LOCK ${BASEDIR}/OPAM/lock (none => read)
SYSTEM LOCK ${BASEDIR}/OPAM/repo/state-magicv.cache (none => read)
SYSTEM LOCK ${BASEDIR}/OPAM/repo/state-magicv.cache (read => none)
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/lock (none => write)
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/packages/cache (none => read)
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/packages/cache (read => none)
SYSTEM mkdir ${BASEDIR}/OPAM/escapability/.opam-switch/backup
The following actions will be performed:
=== install 1 package
- install eskape 1

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
SYSTEM rmdir ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1
SYSTEM mkdir ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/eskape.install
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/a-file
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/a-file
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/fichier
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/fichier
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/dosiero
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/dosiero
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/good
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/good
[WARNING] Errors in ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install, some fields have been ignored:
- At ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install:2:14-2:28::
../../a-file references its parent directory.
- At ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install:8:14-8:28::
../../a-file references its parent directory.
- At ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install:26:14-26:28::
../../a-file is not an absolute filename.
- At ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install:20:14-20:28::
../../a-file references its parent directory.
- At ${BASEDIR}/OPAM/escapability/.opam-switch/build/eskape.1/eskape.install:14:14-14:28::
../../a-file references its parent directory.

-> installed eskape.1
SYSTEM rm ${BASEDIR}/OPAM/escapability/.opam-switch/packages/cache
SYSTEM mkdir ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1
SYSTEM mkdir ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/eskape.install
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files/eskape.install
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/a-file
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files/a-file
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/fichier
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files/fichier
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/dosiero
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files/dosiero
SYSTEM read ${BASEDIR}/OPAM/repo/default/packages/eskape/eskape.1/files/good
SYSTEM write ${BASEDIR}/OPAM/escapability/.opam-switch/packages/eskape.1/files/good
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/packages/cache (none => write)
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/packages/cache (write => none)
Done.
SYSTEM LOCK ${BASEDIR}/OPAM/escapability/.opam-switch/lock (write => none)
SYSTEM rm ${BASEDIR}/OPAM/escapability/.opam-switch/backup/state-today.export
SYSTEM LOCK ${BASEDIR}/OPAM/repo/lock (none => none)
SYSTEM LOCK ${BASEDIR}/OPAM/config.lock (none => none)
### ocaml cat.ml escapability eskape
==> eskape installed file
Not found: ${BASEDIR}/OPAM/escapability/share/eskape/a-file
==> eskape changes
opam-version: "2.0"
Loading