diff --git a/.gitignore b/.gitignore index 2e2743f..cf7f075 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,10 @@ -# the gocryptfs executable -/gocryptfs +/build +/include +/lib +/openssl* # temporary files created by the tests /tmp -# binary releases and signatiures -/*.tar.gz -/*.asc - # Binaries created for cpu profiling *.test - -# Rendered manpage -gocryptfs.1 - -# Dependencies copied by "dep" -/vendor -/_vendor-* - -# Source tarball version. Should never be committed to git. -/VERSION diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9cfc238..0000000 --- a/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -language: go -os: linux - -# fuse on travis -sudo: required -dist: bionic # Ubuntu 18.04 "Bionic", https://docs.travis-ci.com/user/reference/bionic/ - -env: - - GO111MODULE=on - -git: - depth: 300 - -# Build with the lastest relevant Go versions -# Relevance is determined from: -# * https://golang.org/dl/ -# * https://packages.debian.org/search?keywords=golang&searchon=names&exact=1&suite=all§ion=all -# * https://packages.ubuntu.com/search?keywords=golang&searchon=names&exact=1&suite=all§ion=all -go: - - 1.11.x # Debian 10 "Buster" - - 1.12.x # Ubuntu 19.10 - - 1.13.x # Debian 11 "Bullseye" - - stable - -before_install: - - sudo apt-get install -qq fuse - - sudo modprobe fuse - - sudo chmod 666 /dev/fuse - - sudo chown root:$USER /etc/fuse.conf - -script: - - openssl version - - df -Th / /tmp - - env GO111MODULE=on go build - - ./build-without-openssl.bash - - ./build.bash - - ./gocryptfs -speed - - ./test.bash - - make root_test - - ./crossbuild.bash - - echo "rebuild with locked dependencies" - - go mod vendor - - ./build.bash -mod=vendor diff --git a/Documentation/.gitignore b/Documentation/.gitignore deleted file mode 100644 index d2f316c..0000000 --- a/Documentation/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Generated man pages -*.1 diff --git a/Documentation/CLI_ABI.md b/Documentation/CLI_ABI.md deleted file mode 100644 index 9581556..0000000 --- a/Documentation/CLI_ABI.md +++ /dev/null @@ -1,102 +0,0 @@ -Stable CLI ABI -============== - -If you want to call gocryptfs from your script or app, this is the -stable ABI. - -General -------- - -1. A password is piped into gocryptfs with an optional terminating - newline. Any unexpected data after the final newline will - cause gocryptfs to abort. -2. Always pass "--" after the options. This prevents a CIPERDIR that - starts with a dash ("-") to wreak havoc. -3. Use "-q" to get rid of all informational messages. Only error - messages (if any) will be printed to stderr (capture it!). -4. Check the exit code of gocryptfs. 0 is success, anything else is an - error and details about that error will have been printed to stderr. - -Initialize Filesystem ---------------------- - -#### Bash example - - $ cat mypassword.txt | gocryptfs -init -q -- CIPHERDIR - -Content of "mypassword.txt": - - mypassword1234 - -#### What you have to pipe to gocryptfs - -1. Password -2. Optional newline - -#### Notes - -1. The CIPHERDIR directory must exist and be empty - -#### Exit Codes - -* 0 = success -* 6 = CIPHERDIR is invalid: not an empty directory -* 22 = password is empty -* 24 = could not create gocryptfs.conf -* other = please inspect the message - -Mount ------ - -#### Bash example - - $ cat mypassword.txt | gocryptfs -q -- CIPHERDIR MOUNTPOINT - -#### What you have to pipe to gocryptfs - -Same as for "Initialize Filesystem". - -#### Notes - -1. The MOUNTPOINT directory must exist and be empty. - -#### Exit Codes - -* 0 = success -* 10 = MOUNTPOINT is not an empty directory or contains CIPHERDIR -* 12 = password incorrect -* 23 = gocryptfs.conf could not be opened (does not exist, is unreadable, ...) -* other = please inspect the message - -Change Password ---------------- - -#### Bash example - - $ cat change.txt | gocryptfs -passwd -q -- CIPHERDIR - -Content of "change.txt": - - mypassword1234 - newpassword9876 - -#### What you have to pipe to gocryptfs - -1. Old password -2. Newline -3. New password -4. Optional newline - -#### Exit Codes - -* 0 = success -* 12 = password incorrect -* 23 = gocryptfs.conf could not be opened for reading -* 24 = could not write the updated gocryptfs.conf -* other = please inspect the message - -Further Reading ---------------- - -Additional exit codes that are unlikely to occur are defined in -[exitcodes.go](../internal/exitcodes/exitcodes.go). diff --git a/Documentation/MANPAGE-STATFS.md b/Documentation/MANPAGE-STATFS.md deleted file mode 100644 index c519f4b..0000000 --- a/Documentation/MANPAGE-STATFS.md +++ /dev/null @@ -1,82 +0,0 @@ -% STATFS(1) -% github.com/rfjakob -% Sep 2019 - -NAME -==== - -statfs - dump the statfs(2) information for PATH to console in JSON format. - -SYNOPSIS -======== - -statfs PATH - -DESCRIPTION -=========== - -The statfs(2) system call returns information about a mounted filesystem -in a `statfs_t` structure. This tool dumps this information in JSON format. -It is developed as part of gocryptfs and written in Go. - -The `statfs_t` structure is architecture-dependent. On amd64 it looks like this: - -``` -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid struct { - Val [2]int32 - } - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} -``` - -See the statfs(2) man page for the meaning of these fields, and note -that the field names here are acc. to the Go `golang.org/x/sys/unix` -naming convention, and slightly different than in C. - -EXAMPLES -======== - -Get the statfs(2) information for /tmp: - -``` -$ statfs /tmp -{ - "Type": 16914836, - "Bsize": 4096, - "Blocks": 3067428, - "Bfree": 3067411, - "Bavail": 3067411, - "Files": 3067428, - "Ffree": 3067381, - "Fsid": { - "Val": [ - 0, - 0 - ] - }, - "Namelen": 255, - "Frsize": 4096, - "Flags": 38, - "Spare": [ - 0, - 0, - 0, - 0 - ] -} -``` - -SEE ALSO -======== -statfs(2) gocryptfs(1) diff --git a/Documentation/MANPAGE-XRAY.md b/Documentation/MANPAGE-XRAY.md deleted file mode 100644 index 5a5162c..0000000 --- a/Documentation/MANPAGE-XRAY.md +++ /dev/null @@ -1,64 +0,0 @@ -% GOCRYPTFS-XRAY(1) -% github.com/rfjakob -% Jan 2018 - -NAME -==== - -gocryptfs-xray - examine gocryptfs-related data - -SYNOPSIS -======== - -#### Examine encrypted file/directory -gocryptfs-xray CIPHERDIR/ENCRYPTED-FILE-OR-DIR - -#### Decrypt and show master key -gocryptfs-xray -dumpmasterkey CIPHERDIR/gocryptfs.conf - -#### Encrypt paths -gocryptfs-xray -encrypt-paths SOCKET - -DESCRIPTION -=========== - -Available options are listed below. - -#### -0 -Use \\0 instead of \\n as separator for -decrypt-paths and -encrypt-paths. - -#### -aessiv -Assume AES-SIV mode instead of AES-GCM when examining an encrypted file. -Is not needed and has no effect in `-dumpmasterkey` mode. - -#### -decrypt-paths -Decrypt file paths using gocryptfs control socket. Reads from stdin. -See `-ctlsock` in gocryptfs(1). - -#### -dumpmasterkey -Decrypts and shows the master key. - -#### -encrypt-paths -Encrypt file paths using gocryptfs control socket. Reads from stdin. -See `-ctlsock` in gocryptfs(1). - -EXAMPLES -======== - -Examine an encrypted file: - - gocryptfs-xray myfs/mCXnISiv7nEmyc0glGuhTQ - -Print the master key: - - gocryptfs-xray -dumpmasterkey myfs/gocryptfs.conf - -Mount gocryptfs with control socket and use gocryptfs-xray to -encrypt some paths: - - gocryptfs -ctlsock myfs.sock myfs myfs.mnt - echo -e "foo\nbar" | gocryptfs-xray -encrypt-paths myfs.sock - -SEE ALSO -======== -gocryptfs(1) fuse(8) diff --git a/Documentation/MANPAGE-render.bash b/Documentation/MANPAGE-render.bash deleted file mode 100755 index 74028ad..0000000 --- a/Documentation/MANPAGE-render.bash +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -set -eu -cd $(dirname "$0") - -# Render Markdown to a proper man(1) manpage -function render { - IN=$1 - OUT=$2 - echo "Rendering $IN to $OUT" - echo ".\\\" This man page was generated from $IN. View it using 'man ./$OUT'" > $OUT - echo ".\\\"" >> $OUT - pandoc "$IN" -s -t man >> $OUT -} - -render MANPAGE.md gocryptfs.1 -render MANPAGE-XRAY.md gocryptfs-xray.1 -render MANPAGE-STATFS.md statfs.1 diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md deleted file mode 100644 index 9ddf674..0000000 --- a/Documentation/MANPAGE.md +++ /dev/null @@ -1,619 +0,0 @@ -% GOCRYPTFS(1) -% github.com/rfjakob -% Aug 2017 - -NAME -==== - -gocryptfs - create or mount an encrypted filesystem - -SYNOPSIS -======== - -#### Initialize new encrypted filesystem -`gocryptfs -init [OPTIONS] CIPHERDIR` - -#### Mount -`gocryptfs [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]` - -#### Unmount -`fusermount -u MOUNTPOINT` - -#### Change password -`gocryptfs -passwd [OPTIONS] CIPHERDIR` - -#### Check consistency -`gocryptfs -fsck [OPTIONS] CIPHERDIR` - -#### Show filesystem information -`gocryptfs -info [OPTIONS] CIPHERDIR` - -DESCRIPTION -=========== - -gocryptfs is an encrypted overlay filesystem written in Go. -Encrypted files are stored in CIPHERDIR, and a plain-text -view can be presented by mounting the filesystem at MOUNTPOINT. - -gocryptfs was inspired by encfs(1) and strives to fix its -security issues while providing good performance. - -ACTION FLAGS -============ - -Unless one of the following *action flags* is passed, the default -action is to mount a filesystem (see SYNOPSIS). - -#### -fsck -Check CIPHERDIR for consistency. If corruption is found, the -exit code is 26. - -#### -h, -help -Print a short help text that shows the more-often used options. - -#### -hh -Long help text, shows all available options. - -#### -info -Pretty-print the contents of the config file in CIPHERDIR for -human consumption, stripping out sensitive data. - -Example: - - $ gocryptfs -info my_cipherdir - Creator: gocryptfs v2.0-beta2 - FeatureFlags: GCMIV128 HKDF DirIV EMENames LongNames Raw64 - EncryptedKey: 64B - ScryptObject: Salt=32B N=65536 R=8 P=1 KeyLen=32 - -#### -init -Initialize encrypted directory. - -#### -passwd -Change the password. Will ask for the old password, check if it is -correct, and ask for a new one. - -This can be used together with `-masterkey` if -you forgot the password but know the master key. Note that without the -old password, gocryptfs cannot tell if the master key is correct and will -overwrite the old one without mercy. It will, however, create a backup copy -of the old config file as `gocryptfs.conf.bak`. Delete it after -you have verified that you can access your files with the -new password. - -#### -speed -Run crypto speed test. Benchmark Go's built-in GCM against OpenSSL -(if available). The library that will be selected on "-openssl=auto" -(the default) is marked as such. - -#### -version -Print version and exit. The output contains three fields separated by ";". -Example: "gocryptfs v1.1.1-5-g75b776c; go-fuse 6b801d3; 2016-11-01 go1.7.3". -Field 1 is the gocryptfs version, field 2 is the version of the go-fuse -library, field 3 is the compile date and the Go version that was -used. - -INIT OPTIONS -============ - -Available options for `-init` are listed below. Usually, you don't need any. -Defaults are fine. - -#### -aessiv -Use the AES-SIV encryption mode. This is slower than GCM but is -secure with deterministic nonces as used in "-reverse" mode. - -#### -devrandom -Use `/dev/random` for generating the master key instead of the default Go -implementation. This is especially useful on embedded systems with Go versions -prior to 1.9, which fall back to weak random data when the getrandom syscall -is blocking. Using this option can block indefinitely when the kernel cannot -harvest enough entropy. - -#### -hkdf -Use HKDF to derive separate keys for content and name encryption from -the master key. Default true. - -#### -nosyslog -Diagnostic messages are normally redirected to syslog once gocryptfs -daemonizes. This option disables the redirection and messages will -continue be printed to stdout and stderr. - -#### -plaintextnames -Do not encrypt file names and symlink targets. - -#### -raw64 -Use unpadded base64 encoding for file names. This gets rid of the -trailing "\\=\\=". A filesystem created with this option can only be -mounted using gocryptfs v1.2 and higher. Default true. - -#### -reverse -Reverse mode shows a read-only encrypted view of a plaintext -directory. Implies "-aessiv". - -#### -scryptn int -scrypt cost parameter expressed as scryptn=log2(N). Possible values are -10 to 28, representing N=2^10 to N=2^28. - -Setting this to a lower -value speeds up mounting and reduces its memory needs, but makes -the password susceptible to brute-force attacks. The default is 16. - -MOUNT OPTIONS -============= - -Available options for mounting are listed below. Usually, you don't need any. -Defaults are fine. - -#### -allow_other -By default, the Linux kernel prevents any other user (even root) to -access a mounted FUSE filesystem. Settings this option allows access for -other users, subject to file permission checking. Only works if -user_allow_other is set in /etc/fuse.conf. This option is equivalent to -"allow_other" plus "default_permissions" described in fuse(8). - -#### -ctlsock string -Create a control socket at the specified location. The socket can be -used to decrypt and encrypt paths inside the filesystem. When using -this option, make sure that the directory you place the socket in is -not world-accessible. For example, `/run/user/UID/my.socket` would -be suitable. - -#### -dev, -nodev -Enable (`-dev`) or disable (`-nodev`) device files in a gocryptfs mount -(default: `-nodev`). If both are specified, `-nodev` takes precedence. -You need root permissions to use `-dev`. - -#### -e PATH, -exclude PATH -Only for reverse mode: exclude relative plaintext path from the encrypted -view, matching only from root of mounted filesystem. Can be passed multiple -times. Example: - - gocryptfs -reverse -exclude Music -exclude Movies /home/user /mnt/user.encrypted - -See also `-exclude-wildcard`, `-exclude-from` and the [EXCLUDING FILES](#excluding-files) section. - -#### -ew PATH, -exclude-wildcard PATH -Only for reverse mode: exclude paths from the encrypted view, matching anywhere. -Wildcards supported. Can be passed multiple times. Example: - - gocryptfs -reverse -exclude-wildcard '*~' /home/user /mnt/user.encrypted - -See also `-exclude`, `-exclude-from` and the [EXCLUDING FILES](#excluding-files) section. - -#### -exclude-from FILE -Only for reverse mode: reads exclusion patters (using `-exclude-wildcard` syntax) -from a file. Can be passed multiple times. Example: - - gocryptfs -reverse -exclude-from ~/crypt-exclusions /home/user /mnt/user.encrypted - -See also `-exclude`, `-exclude-wildcard` and the [EXCLUDING FILES](#excluding-files) section. - -#### -exec, -noexec -Enable (`-exec`) or disable (`-noexec`) executables in a gocryptfs mount -(default: `-exec`). If both are specified, `-noexec` takes precedence. - -#### -fg, -f -Stay in the foreground instead of forking away. -For compatibility, "-f" is also accepted, but "-fg" is preferred. - -Unless `-notifypid` is also passed, the logs go to stdout and stderr -instead of syslog. - -#### -force_owner string -If given a string of the form "uid:gid" (where both "uid" and "gid" are -substituted with positive integers), presents all files as owned by the given -uid and gid, regardless of their actual ownership. Implies "allow_other". - -This is rarely desired behavior: One should *usually* run gocryptfs as the -account which owns the backing-store files, which should *usually* be one and -the same with the account intended to access the decrypted content. An example -of a case where this may be useful is a situation where content is stored on a -filesystem that doesn't properly support UNIX ownership and permissions. - -#### -forcedecode -Force decode of encrypted files even if the integrity check fails, instead of -failing with an IO error. Warning messages are still printed to syslog if corrupted -files are encountered. -It can be useful to recover files from disks with bad sectors or other corrupted -media. It shall not be used if the origin of corruption is unknown, specially -if you want to run executable files. - -For corrupted media, note that you probably want to use dd_rescue(1) -instead, which will recover all but the corrupted 4kB block. - -This option makes no sense in reverse mode. It requires gocryptfs to be compiled with openssl -support and implies -openssl true. Because of this, it is not compatible with -aessiv, -that uses built-in Go crypto. - -Setting this option forces the filesystem to read-only and noexec. - -#### -fsname string -Override the filesystem name (first column in df -T). Can also be -passed as "-o fsname=" and is equivalent to libfuse's option of the -same name. By default, CIPHERDIR is used. - -#### -fusedebug -Enable fuse library debug output. - -#### -i duration, -idle duration -Only for forward mode: automatically unmount the filesystem if it has been idle -for the specified duration. Durations can be specified like "500s" or "2h45m". -0 (the default) means stay mounted indefinitely. - -When a process has open files or its working directory in the mount, -this will keep it not idle indefinitely. - -#### -kernel_cache -Enable the kernel_cache option of the FUSE filesystem, see fuse(8) for details. - -#### -ko -Pass additional mount options to the kernel (comma-separated list). -FUSE filesystems are mounted with "nodev,nosuid" by default. If gocryptfs -runs as root, you can enable device files by passing the opposite mount option, -"dev", and if you want to enable suid-binaries, pass "suid". -"ro" (equivalent to passing the "-ro" option) and "noexec" may also be -interesting. For a complete list see the section -`FILESYSTEM-INDEPENDENT MOUNT OPTIONS` in mount(8). On MacOS, "local", -"noapplexattr", "noappledouble" may be interesting. - -Note that unlike "-o", "-ko" is a regular option and must be passed BEFORE -the directories. Example: - - gocryptfs -ko noexec /tmp/foo /tmp/bar - -#### -longnames -Store names longer than 176 bytes in extra files (default true) -This flag is useful when recovering old gocryptfs filesystems using -"-masterkey". It is ignored (stays at the default) otherwise. - -#### -nodev -See `-dev, -nodev`. - -#### -noexec -See `-exec, -noexec`. - -#### -nofail -Having the `nofail` option in `/etc/fstab` instructs `systemd` to continue -booting normally even if the mount fails (see `man systemd.fstab`). - -The option is ignored by `gocryptfs` itself and has no effect outside `/etc/fstab`. - -#### -nonempty -Allow mounting over non-empty directories. FUSE by default disallows -this to prevent accidental shadowing of files. - -#### -noprealloc -Disable preallocation before writing. By default, gocryptfs -preallocates the space the next write will take using fallocate(2) -in mode FALLOC_FL_KEEP_SIZE. The preallocation makes sure it cannot -run out of space in the middle of the write, which would cause the -last 4kB block to be corrupt and unreadable. - -On ext4, preallocation is fast and does not cause a -noticeable performance hit. Unfortunately, on Btrfs, preallocation -is very slow, especially on rotational HDDs. The "-noprealloc" -option gives users the choice to trade robustness against -out-of-space errors for a massive speedup. - -For benchmarks and more details of the issue see -https://github.com/rfjakob/gocryptfs/issues/63 . - -#### -nosuid -See `-suid, -nosuid`. - -#### -notifypid int -Send USR1 to the specified process after successful mount. This is -used internally for daemonization. - -#### -rw, -ro -Mount the filesystem read-write (`-rw`, default) or read-only (`-ro`). -If both are specified, `-ro` takes precedence. - -#### -reverse -See the `-reverse` section in INIT FLAGS. You need to specifiy the -`-reverse` option both at `-init` and at mount. - -#### -serialize_reads -The kernel usually submits multiple concurrent reads to service -userspace requests and kernel readahead. gocryptfs serves them -concurrently and in arbitrary order. On backing storage that performs -poorly for concurrent or out-of-order reads (like Amazon Cloud Drive), -this behavior can cause very slow read speeds. - -The `-serialize_reads` -option does two things: (1) reads will be submitted one-by-one (no -concurrency) and (2) gocryptfs tries to order the reads by file -offset order. - -The ordering requires gocryptfs to wait a certain time before -submitting a read. The serialization introduces extra locking. -These factors will limit throughput to below 70MB/s. - -For more details visit https://github.com/rfjakob/gocryptfs/issues/92 . - -#### -sharedstorage -Enable work-arounds so gocryptfs works better when the backing -storage directory is concurrently accessed by multiple gocryptfs -instances. - -At the moment, it does two things: - -1. Disable stat() caching so changes to the backing storage show up - immediately. -2. Disable hard link tracking, as the inode numbers on the backing - storage are not stable when files are deleted and re-created behind - our back. This would otherwise produce strange "file does not exist" - and other errors. - -When "-sharedstorage" is active, performance is reduced and hard -links cannot be created. - -Even with this flag set, you may hit occasional problems. Running -gocryptfs on shared storage does not receive as much testing as the -usual (exclusive) use-case. Please test your workload in advance -and report any problems you may hit. - -More info: https://github.com/rfjakob/gocryptfs/issues/156 - -#### -suid, -nosuid -Enable (`-suid`) or disable (`-nosuid`) suid and sgid executables in a gocryptfs -mount (default: `-nosuid`). If both are specified, `-nosuid` takes precedence. -You need root permissions to use `-suid`. - -#### -zerokey -Use all-zero dummy master key. This options is only intended for -automated testing as it does not provide any security. - -COMMON OPTIONS -============== - -Options that apply to more than one action are listed below. -Each options lists where it is applicable. Again, usually you -don't need any. - -#### -config string -Use specified config file instead of `CIPHERDIR/gocryptfs.conf`. - -Applies to: all actions that use a config file: mount, `-fsck`, `-passwd`, `-info`, `-init`. - -#### -cpuprofile string -Write cpu profile to specified file. - -Applies to: all actions. - -#### -d, -debug -Enable debug output. - -Applies to: all actions. - -#### -extpass CMD [-extpass ARG1 ...] -Use an external program (like ssh-askpass) for the password prompt. -The program should return the password on stdout, a trailing newline is -stripped by gocryptfs. If you just want to read from a password file, see `-passfile`. - -When `-extpass` is specified once, the string argument will be split on spaces. -For example, `-extpass "md5sum my password.txt"` will be executed as -`"md5sum" "my" "password.txt"`, which is NOT what you want. - -Specify `-extpass` twice or more to use the string arguments as-is. -For example, you DO want to call `md5sum` like this: -`-extpass "md5sum" -extpass "my password.txt"`. - -If you want to prevent splitting on spaces but don't want to pass arguments -to your program, use `"--"`, which is accepted by most programs: -`-extpass "my program" -extpass "--"` - -Applies to: all actions that ask for a password. - -#### -fido2 DEVICE_PATH -Use a FIDO2 token to initialize and unlock the filesystem. -Use "fido2-token -L" to obtain the FIDO2 token device path. - -Applies to: all actions that ask for a password. - -#### -masterkey string -Use a explicit master key specified on the command line or, if the special -value "stdin" is used, read the masterkey from stdin, instead of reading -the config file and asking for the decryption password. - -Note that the command line, and with it the master key, is visible to -anybody on the machine who can execute "ps -auxwww". Use "-masterkey=stdin" -to avoid that risk. - -The masterkey option is meant as a recovery option for emergencies, such as -if you have forgotten the password or lost the config file. - -Even if a config file exists, it will not be used. All non-standard -settings have to be passed on the command line: `-aessiv` when you -mount a filesystem that was created using reverse mode, or -`-plaintextnames` for a filesystem that was created with that option. - -Examples: - - -masterkey=6f717d8b-6b5f8e8a-fd0aa206-778ec093-62c5669b-abd229cd-241e00cd-b4d6713d - -masterkey=stdin - -Applies to: all actions that ask for a password. - -#### -memprofile string -Write memory profile to the specified file. This is useful when debugging -memory usage of gocryptfs. - -Applies to: all actions. - -#### -o COMMA-SEPARATED-OPTIONS -For compatibility with mount(1), options are also accepted as -"-o COMMA-SEPARATED-OPTIONS" at the end of the command line. -For example, "-o q,zerokey" is equivalent to passing "-q -zerokey". - -Note that you can only use options that are understood by gocryptfs -with "-o". If you want to pass special flags to the kernel, you should -use "-ko" (*k*ernel *o*ption). This is different in libfuse-based -filesystems, that automatically pass any "-o" options they do not -understand along to the kernel. - -Example: - - gocryptfs /tmp/foo /tmp/bar -o q,zerokey - -Applies to: all actions. - -#### -openssl bool/"auto" -Use OpenSSL instead of built-in Go crypto (default "auto"). Using -built-in crypto is 4x slower unless your CPU has AES instructions and -you are using Go 1.6+. In mode "auto", gocrypts chooses the faster -option. - -Applies to: all actions. - -#### -passfile FILE [-passfile FILE2 ...] -Read password from the specified plain text file. The file should contain exactly -one line (do not use binary files!). -A warning will be printed if there is more than one line, and only -the first line will be used. A single -trailing newline is allowed and does not cause a warning. - -Pass this option multiple times to read the first line from multiple -files. They are concatenated for the effective password. - -Example: - - echo hello > hello.txt - echo word > world.txt - gocryptfs -passfile hello.txt -passfile world.txt - -The effective password will be "helloworld". - -Applies to: all actions that ask for a password. - -#### -q, -quiet -Quiet - silence informational messages. - -Applies to: all actions. - -#### -trace string -Write execution trace to file. View the trace using "go tool trace FILE". - -Applies to: all actions. - -#### -wpanic -When encountering a warning, panic and exit immediately. This is -useful in regression testing. - -Applies to: all actions. - -#### \-\- -Stop option parsing. Helpful when CIPHERDIR may start with a -dash "-". - -Applies to: all actions. - -EXCLUDING FILES -=============== - -In reverse mode, it is possible to exclude files from the encrypted view, using -the `-exclude`, `-exclude-wildcard` and `-exclude-from` options. - -`-exclude` matches complete paths, so `-exclude file.txt` only excludes a file -named `file.txt` in the root of the mounted filesystem; files named `file.txt` -in subdirectories are still visible. (This option is kept for compatibility -with the behavior up to version 1.6.x) - -`-exclude-wildcard` matches files anywhere, so `-exclude-wildcard file.txt` -excludes files named `file.txt` in any directory. If you want to match complete -paths, you can prefix the filename with a `/`: `-exclude-wildcard /file.txt` -excludes only `file.txt` in the root of the mounted filesystem. - -If there are many exclusions, you can use `-exclude-from` to read exclusion -patterns from a file. The syntax is that of `-exclude-wildcard`, so use a -leading `/` to match complete paths. - -The rules for exclusion are that of [gitignore](https://git-scm.com/docs/gitignore#_pattern_format). -In short: - -1. A blank line matches no files, so it can serve as a separator - for readability. -2. A line starting with `#` serves as a comment. Put a backslash (`\`) - in front of the first hash for patterns that begin with a hash. -3. Trailing spaces are ignored unless they are quoted with backslash (`\`). -4. An optional prefix `!` negates the pattern; any matching file - excluded by a previous pattern will become included again. It is not - possible to re-include a file if a parent directory of that file is - excluded. Put a backslash (`\`) in front of the first `!` for - patterns that begin with a literal `!`, for example, `\!important!.txt`. -5. If the pattern ends with a slash, it is removed for the purpose of the - following description, but it would only find a match with a directory. - In other words, `foo/` will match a directory foo and paths underneath it, - but will not match a regular file or a symbolic link foo. -6. If the pattern does not contain a slash `/`, it is treated as a shell glob - pattern and checked for a match against the pathname relative to the - root of the mounted filesystem. -7. Otherwise, the pattern is treated as a shell glob suitable for - consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the - pattern will not match a `/` in the pathname. For example, - `Documentation/*.html` matches `Documentation/git.html` but not - `Documentation/ppc/ppc.html` or `tools/perf/Documentation/perf.html`. -8. A leading slash matches the beginning of the pathname. For example, - `/*.c` matches `cat-file.c` but not `mozilla-sha1/sha1.c`. -9. Two consecutive asterisks (`**`) in patterns matched against full - pathname may have special meaning: - i. A leading `**` followed by a slash means match in all directories. - For example, `**/foo` matches file or directory `foo` anywhere, - the same as pattern `foo`. `**/foo/bar` matches file or directory - `bar` anywhere that is directly under directory `foo`. - ii. A trailing `/**` matches everything inside. For example, `abc/**` - matches all files inside directory `abc`, with infinite depth. - iii. A slash followed by two consecutive asterisks then a slash matches - zero or more directories. For example, `a/**/b` matches `a/b`, - `a/x/b`, `a/x/y/b` and so on. - iv. Other consecutive asterisks are considered invalid. - - -EXAMPLES -======== - -### Init - -Create an encrypted filesystem in directory "mydir.crypt", mount it on "mydir": - - mkdir mydir.crypt mydir - gocryptfs -init mydir.crypt - gocryptfs mydir.crypt mydir - -### Mount - -Mount an encrypted view of joe's home directory using reverse mode: - - mkdir /home/joe.crypt - gocryptfs -init -reverse /home/joe - gocryptfs -reverse /home/joe /home/joe.crypt - -### fstab - -Adding this line to `/etc/fstab` will mount `/tmp/cipher` to `/tmp/plain` on boot, using the -password in `/tmp/passfile`. Use `sudo mount -av` to test the line without having -to reboot. Adjust the gocryptfs path acc. to the output of the command `which gocryptfs`. -Do use the `nofail` option to prevent an unbootable system if the gocryptfs mount fails (see -the `-nofail` option for details). - - /tmp/cipher /tmp/plain fuse./usr/local/bin/gocryptfs nofail,allow_other,passfile=/tmp/password 0 0 - -EXIT CODES -========== - -0: success -6: CIPHERDIR is not an empty directory (on "-init") -10: MOUNTPOINT is not an empty directory -12: password incorrect -22: password is empty (on "-init") -23: could not read gocryptfs.conf -24: could not write gocryptfs.conf (on "-init" or "-password") -26: fsck found errors -other: please check the error message - -See also: https://github.com/rfjakob/gocryptfs/blob/master/internal/exitcodes/exitcodes.go - -SEE ALSO -======== -mount(2) fuse(8) fallocate(2) encfs(1) diff --git a/Documentation/SECURITY.md b/Documentation/SECURITY.md deleted file mode 100644 index 47edd1d..0000000 --- a/Documentation/SECURITY.md +++ /dev/null @@ -1 +0,0 @@ -This page has been moved to https://nuetzlich.net/gocryptfs/security/ . diff --git a/Documentation/XFSTESTS.md b/Documentation/XFSTESTS.md deleted file mode 100644 index bbf19e7..0000000 --- a/Documentation/XFSTESTS.md +++ /dev/null @@ -1,699 +0,0 @@ -# xfstests results - -Results of running [fuse-xfstests](https://github.com/rfjakob/fuse-xfstests) -against gocryptfs. - -## Failures - -### generic/035 - -Known [issue](https://github.com/hanwen/go-fuse/issues/55) in the -go-fuse library. Unlikely to have real-world impact. - -### generic/062 - -Only `user.\*` xattrs are supported, others are rejected. - -### generic/093 - -`security.\*` xattrs are not supported. - -### generic/097 - -`trusted.\*` xattrs are not supported. - -### generic/228 - -`ulimit -f` is not implemented in gocryptfs. - -### generic/273 - -Needs further analysis: -``` -_porter 28 not complete -cp: cannot create regular file '/var/tmp/check-gocryptfs/scratchdir/sub_28/origin/file_548': No such file or directory -``` - -### generic/403 - -`trusted.\*` xattrs are not supported. - -### generic/426, generic/467, generic/477 - -Needs further analysis. - -Failure related to the new system call open_by_handle_at(2) -([lwn article](https://lwn.net/Articles/375888/)). - -### generic/466 - -Harmless output caused by the fact that gocryptfs is not backed by -a block device. - -### generic/484 - -Needs further analysis: `record lock is not preserved across execve(2)` - -### generic/488 - -Needs further analysis: `Too many open files` - -## Full Test Output - -``` -0 jakob@brikett:~/code/fuse-xfstests$ sudo ./check-gocryptfs -gocryptfs v1.7.1; go-fuse v2.0.2-4-g8458b8a; 2019-10-10 go1.12.9 linux/amd64 -fuse-xfstests nlink0/dff383ab -Thu 10 Oct 2019 08:31:43 PM UTC - -FSTYP -- fuse.gocryptfs -PLATFORM -- Linux/x86_64 brikett 5.2.17-200.fc30.x86_64 -MKFS_OPTIONS -- /var/tmp/check-gocryptfs/scratchdev -MOUNT_OPTIONS -- -o context=system_u:object_r:root_t:s0 /var/tmp/check-gocryptfs/scratchdev /var/tmp/check-gocryptfs/scratchdir - -generic/001 6s ... 5s -generic/002 14s ... 1s -generic/003 [not run] atime related mount options have no effect on fuse.gocryptfs -generic/004 [not run] O_TMPFILE is not supported -generic/005 14s ... 0s -generic/006 16s ... 3s -generic/007 19s ... 7s -generic/008 [not run] xfs_io fzero failed (old kernel/wrong fs?) -generic/009 [not run] xfs_io fzero failed (old kernel/wrong fs?) -generic/010 15s ... 1s -generic/011 18s ... 4s -generic/012 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/013 97s ... 12s -generic/014 16s ... 2s -generic/015 2s ... 1s -generic/016 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/017 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/018 [not run] defragmentation not supported for fstype "fuse.gocryptfs" -generic/020 14s ... 1s -generic/021 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/022 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/023 15s ... 1s -generic/024 [not run] fs doesn't support RENAME_NOREPLACE -generic/025 [not run] fs doesn't support RENAME_EXCHANGE -generic/026 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/027 269s ... 101s -generic/028 19s ... 6s -generic/029 0s ... 0s -generic/030 2s ... 1s -generic/031 [not run] xfs_io fcollapse failed (old kernel/wrong fs?) -generic/032 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/033 [not run] xfs_io fzero failed (old kernel/wrong fs?) -generic/034 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/035 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/035.out.bad) - --- tests/generic/035.out 2018-01-20 14:29:39.062451937 +0100 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/035.out.bad 2019-10-10 22:34:13.622100130 +0200 - @@ -1,3 +1,7 @@ - QA output created by 035 - overwriting regular file: - +nlink is 1, should be 0 - +res=0 dev=54 ino=5770027 mode=100644 nlink=1 uid=0 - overwriting directory: - +t_rename_overwrite: fstat(3): No such file or directory - +res=-1 dev=0 ino=0 mode=0 nlink=0 uid=0 - ... - (Run 'diff -u tests/generic/035.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/035.out.bad' to see the entire diff) -generic/036 24s ... 10s -generic/037 5s ... 3s -generic/038 [not run] This test requires at least 10GB free on /var/tmp/check-gocryptfs/scratchdir to run -generic/039 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/040 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/041 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/043 [not run] fuse.gocryptfs does not support shutdown -generic/044 [not run] fuse.gocryptfs does not support shutdown -generic/045 [not run] fuse.gocryptfs does not support shutdown -generic/046 [not run] fuse.gocryptfs does not support shutdown -generic/047 [not run] fuse.gocryptfs does not support shutdown -generic/048 [not run] fuse.gocryptfs does not support shutdown -generic/049 [not run] fuse.gocryptfs does not support shutdown -generic/050 [not run] fuse.gocryptfs does not support shutdown -generic/051 [not run] fuse.gocryptfs does not support shutdown -generic/052 [not run] fuse.gocryptfs does not support shutdown -generic/053 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/054 [not run] fuse.gocryptfs does not support shutdown -generic/055 [not run] fuse.gocryptfs does not support shutdown -generic/056 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/057 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/058 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/059 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/060 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/061 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/062 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/062.out.bad) - --- tests/generic/062.out 2018-01-20 14:29:39.067451950 +0100 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/062.out.bad 2019-10-10 22:34:34.290196880 +0200 - @@ -13,7 +13,7 @@ - - *** set/get one initially empty attribute - # file: SCRATCH_MNT/reg - -user.name - +user.name="" - - *** overwrite empty, set several new attributes - ... - (Run 'diff -u tests/generic/062.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/062.out.bad' to see the entire diff) -generic/063 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/064 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/065 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/066 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/067 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/068 [not run] fuse.gocryptfs does not support freezing -generic/069 221s ... 216s -generic/070 22s ... 9s -generic/071 1s ... 1s -generic/072 [not run] xfs_io fcollapse failed (old kernel/wrong fs?) -generic/073 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/074 766s ... 328s -generic/075 69s ... 11s -generic/076 [not run] require /var/tmp/check-gocryptfs/scratchdev to be local device -generic/077 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/078 [not run] fs doesn't support RENAME_WHITEOUT -generic/079 [not run] file system doesn't support chattr +ia -generic/080 16s ... 2s -generic/081 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/082 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/083 15s ... 8s -generic/084 6s ... 5s -generic/085 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/086 15s ... 1s -generic/087 14s ... 0s -generic/088 14s ... 0s -generic/089 48s ... 53s -generic/090 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/091 19s ... 5s -generic/092 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/093 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/093.out.bad) - --- tests/generic/093.out 2018-06-27 21:12:13.629235005 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/093.out.bad 2019-10-10 22:45:22.194059446 +0200 - @@ -1,15 +1,22 @@ - QA output created by 093 - - **** Verifying that appending to file clears capabilities **** - -file = cap_chown+ep - +Failed to set capabilities on file '/var/tmp/check-gocryptfs/testdir/093.file' (Operation not supported) - +usage: setcap [-q] [-v] [-n ] (-r|-|) [ ... (-r|-|) ] - + - ... - (Run 'diff -u tests/generic/093.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/093.out.bad' to see the entire diff) -generic/094 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/095 [not run] fio utility required, skipped this test -generic/096 [not run] xfs_io fzero failed (old kernel/wrong fs?) -generic/097 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/097.out.bad) - --- tests/generic/097.out 2018-06-27 21:12:13.630235009 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/097.out.bad 2019-10-10 22:45:23.382064979 +0200 - @@ -110,18 +110,16 @@ - *** Test out the trusted namespace *** - - set EA : - +setfattr: TEST_DIR/foo: Operation not supported - - set EA : - - ... - (Run 'diff -u tests/generic/097.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/097.out.bad' to see the entire diff) -generic/098 1s ... 0s -generic/099 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/100 31s ... 15s -generic/101 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/102 32s ... 20s -generic/103 2s ... 2s -generic/104 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/105 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/106 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/107 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/108 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/109 3s ... 4s -generic/110 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/111 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/112 72s ... 14s -generic/113 155s ... 38s -generic/114 [not run] device block size: 4096 greater than 512 -generic/115 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/116 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/117 8s ... 10s -generic/118 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/119 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/120 [not run] atime related mount options have no effect on fuse.gocryptfs -generic/121 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/122 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/123 15s ... 1s -generic/124 19s ... 4s -generic/126 15s ... 1s -generic/127 540s ... 458s -generic/128 1s ... 0s -generic/129 43s ... 33s -generic/130 4s ... 5s -generic/131 16s ... 2s -generic/132 26s ... 17s -generic/133 79s ... 22s -generic/134 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/135 0s ... 1s -generic/136 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/137 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/138 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/139 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/140 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/141 1s ... 0s -generic/142 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/143 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/144 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/145 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/146 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/147 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/148 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/149 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/150 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/151 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/152 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/153 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/154 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/155 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/156 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/157 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/158 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/159 [not run] file system doesn't support chattr +i -generic/160 [not run] file system doesn't support chattr +i -generic/161 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/162 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/163 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/164 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/165 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/166 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/167 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/168 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/169 1s ... 1s -generic/170 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/171 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/172 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/173 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/174 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/175 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/176 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/177 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/178 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/179 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/180 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/181 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/182 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/183 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/184 16s ... 0s -generic/185 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/186 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/187 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/188 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/189 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/190 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/191 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/192 [not run] atime related mount options have no effect on fuse.gocryptfs -generic/193 16s ... 1s -generic/194 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/195 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/196 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/197 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/198 17s ... 1s -generic/199 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/200 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/201 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/202 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/203 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/204 20s ... 16s -generic/205 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/206 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/207 15s ... 1s -generic/208 216s ... 201s -generic/209 46s ... 31s -generic/210 15s ... 1s -generic/211 15s ... 1s -generic/212 15s ... 1s -generic/213 47s ... 20s -generic/214 15s ... 1s -generic/215 17s ... 4s -generic/216 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/217 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/218 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/219 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/220 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/221 17s ... 2s -generic/222 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/223 [not run] can't mkfs fuse.gocryptfs with geometry -generic/224 129s ... 34s -generic/225 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/226 14s ... 12s -generic/227 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/228 1s -generic/229 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/230 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/231 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/232 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/233 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/234 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/235 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/236 17s ... 2s -generic/237 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/238 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/239 21s ... 10s -generic/240 [not run] fs block size must be larger than the device block size. fs block size: 4096, device block size: 4096 -generic/241 87s ... 74s -generic/242 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/243 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/244 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/245 15s ... 1s -generic/246 16s ... 2s -generic/247 32s ... 13s -generic/248 12s ... 2s -generic/249 14s ... 4s -generic/250 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/252 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/253 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/254 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/255 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/256 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/257 12s ... 3s -generic/258 12s ... 2s -generic/259 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/260 [not run] FITRIM not supported on /var/tmp/check-gocryptfs/scratchdir -generic/261 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/262 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/263 30s ... 22s -generic/264 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/265 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/266 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/267 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/268 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/269 34s ... 29s -generic/270 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/271 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/272 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/273 56s ... 42s -generic/274 42s ... 50s -generic/275 46s ... 54s -generic/276 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/277 [not run] file system doesn't support chattr +A -generic/278 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/279 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/280 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/281 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/282 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/283 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/284 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/285 12s ... 3s -generic/286 35s ... 26s -generic/287 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/288 [not run] FITRIM not supported on /var/tmp/check-gocryptfs/scratchdir -generic/289 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/290 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/291 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/292 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/293 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/294 0s ... 1s -generic/295 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/296 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/297 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/298 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/299 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/300 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/301 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/302 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/303 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/304 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/305 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/306 12s ... 3s -generic/307 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/308 11s ... 2s -generic/309 13s ... 4s -generic/310 76s ... 69s -generic/311 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/312 2s ... 1s -generic/313 14s ... 7s -generic/314 11s ... 2s -generic/315 10s ... 3s -generic/316 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/317 0s ... 1s -generic/318 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/319 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/320 59s ... 48s -generic/321 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/322 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/323 131s ... 123s -generic/324 [not run] defragmentation not supported for fstype "fuse.gocryptfs" -generic/325 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/326 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/327 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/328 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/329 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/330 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/331 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/332 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/333 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/334 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/335 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/336 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/337 0s ... 0s -generic/338 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/339 13s ... 17s -generic/340 9s ... 4s -generic/341 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/342 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/343 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/344 36s ... 24s -generic/345 18s ... 8s -generic/346 29s ... 22s -generic/347 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/348 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/352 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/353 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/354 7s ... 5s -generic/355 11s ... 3s -generic/356 [not run] swapfiles are not supported -generic/357 [not run] swapfiles are not supported -generic/358 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/359 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/360 10s ... 2s -generic/361 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/362 [not run] this test requires richacl support on $SCRATCH_DEV -generic/363 [not run] this test requires richacl support on $SCRATCH_DEV -generic/364 [not run] this test requires richacl support on $SCRATCH_DEV -generic/365 [not run] this test requires richacl support on $SCRATCH_DEV -generic/366 [not run] this test requires richacl support on $SCRATCH_DEV -generic/367 [not run] this test requires richacl support on $SCRATCH_DEV -generic/368 [not run] this test requires richacl support on $SCRATCH_DEV -generic/369 [not run] this test requires richacl support on $SCRATCH_DEV -generic/370 [not run] this test requires richacl support on $SCRATCH_DEV -generic/371 159s ... 145s -generic/372 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/373 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/374 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/375 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/376 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/377 0s ... 0s -generic/378 11s ... 2s -generic/379 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/380 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/381 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/382 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/383 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/384 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/385 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/386 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/387 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/388 [not run] require /var/tmp/check-gocryptfs/scratchdev to be local device -generic/389 [not run] O_TMPFILE is not supported -generic/390 [not run] fuse.gocryptfs does not support freezing -generic/391 19s ... 9s -generic/392 [not run] fuse.gocryptfs does not support shutdown -generic/393 0s ... 1s -generic/394 16s ... 4s -generic/395 [not run] No encryption support for fuse.gocryptfs -generic/396 [not run] No encryption support for fuse.gocryptfs -generic/397 [not run] No encryption support for fuse.gocryptfs -generic/398 [not run] No encryption support for fuse.gocryptfs -generic/399 [not run] No encryption support for fuse.gocryptfs -generic/400 [not run] disk quotas not supported by this filesystem type: fuse.gocryptfs -generic/401 0s ... 0s -generic/402 [not run] no kernel support for y2038 sysfs switch -generic/403 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/403.out.bad) - --- tests/generic/403.out 2018-06-27 21:12:13.659235117 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/403.out.bad 2019-10-10 23:16:53.291612884 +0200 - @@ -1,2 +1,204 @@ - QA output created by 403 - +setfattr: /var/tmp/check-gocryptfs/scratchdir/file: Operation not supported - +/var/tmp/check-gocryptfs/scratchdir/file: trusted.small: Operation not supported - +setfattr: /var/tmp/check-gocryptfs/scratchdir/file: Operation not supported - +setfattr: /var/tmp/check-gocryptfs/scratchdir/file: Operation not supported - +setfattr: /var/tmp/check-gocryptfs/scratchdir/file: Operation not supported - +setfattr: /var/tmp/check-gocryptfs/scratchdir/file: Operation not supported - ... - (Run 'diff -u tests/generic/403.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/403.out.bad' to see the entire diff) -generic/404 [not run] xfs_io finsert failed (old kernel/wrong fs?) -generic/405 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/406 3s ... 2s -generic/407 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/408 [not run] Dedupe not supported by test filesystem type: fuse.gocryptfs -generic/409 [not run] require /var/tmp/check-gocryptfs/scratchdev to be local device -generic/410 [not run] require /var/tmp/check-gocryptfs/scratchdev to be local device -generic/411 [not run] require /var/tmp/check-gocryptfs/scratchdev to be local device -generic/412 2s ... 3s -generic/413 [not run] /var/tmp/check-gocryptfs/scratchdev fuse.gocryptfs does not support -o dax -generic/414 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/415 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/416 105s ... 102s -generic/417 [not run] fuse.gocryptfs does not support shutdown -generic/418 [not run] require /var/tmp/check-gocryptfs/testdev to be valid block disk -generic/419 [not run] No encryption support for fuse.gocryptfs -generic/420 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/421 [not run] No encryption support for fuse.gocryptfs -generic/422 15s ... 3s -generic/423 15s ... 4s -generic/424 [not run] file system doesn't support any of /usr/bin/chattr +a/+c/+d/+i -generic/425 [not run] xfs_io fiemap failed (old kernel/wrong fs?) -generic/426 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/426.out.bad) - --- tests/generic/426.out 2018-06-27 21:12:13.662235128 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/426.out.bad 2019-10-10 23:18:59.149149787 +0200 - @@ -1,5 +1,3077 @@ - QA output created by 426 - test_file_handles TEST_DIR/426-dir -d - test_file_handles TEST_DIR/426-dir - +open_by_handle(/var/tmp/check-gocryptfs/testdir/426-dir/file000000) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/426-dir/file000001) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/426-dir/file000002) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/426-dir/file000003) returned 116 incorrectly on a linked file! - ... - (Run 'diff -u tests/generic/426.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/426.out.bad' to see the entire diff) -generic/427 6s ... 4s -generic/428 15s ... 4s -generic/429 [not run] No encryption support for fuse.gocryptfs -generic/430 15s ... 4s -generic/431 15s ... 4s -generic/432 15s ... 4s -generic/433 15s ... 3s -generic/434 15s ... 4s -generic/435 [not run] No encryption support for fuse.gocryptfs -generic/436 15s ... 4s -generic/437 16s ... 4s -generic/438 57s ... 40s -generic/439 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/440 [not run] No encryption support for fuse.gocryptfs -generic/441 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/443 15s ... 4s -generic/444 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/445 15s ... 4s -generic/446 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/447 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/448 15s ... 4s -generic/449 [not run] ACLs not supported by this filesystem type: fuse.gocryptfs -generic/450 [not run] Only test on sector size < half of block size -generic/451 45s ... 34s -generic/452 0s ... 0s -generic/453 1s ... 1s -generic/454 1s ... 1s -generic/455 [not run] This test requires a valid $LOGWRITES_DEV -generic/456 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/457 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/458 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/459 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/460 [not run] This test requires at least 1GB free on /var/tmp/check-gocryptfs/scratchdir to run -generic/461 [not run] fuse.gocryptfs does not support shutdown -generic/462 [not run] /var/tmp/check-gocryptfs/scratchdev fuse.gocryptfs does not support -o dax -generic/463 [not run] Reflink not supported by test filesystem type: fuse.gocryptfs -generic/464 94s ... 63s -generic/465 5s ... 2s -generic/466 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/466.out.bad) - --- tests/generic/466.out 2018-06-27 21:12:13.667235146 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/466.out.bad 2019-10-10 23:22:14.813984485 +0200 - @@ -1,2 +1,3 @@ - QA output created by 466 - Silence is golden - +blockdev: ioctl error on BLKGETSIZE64: Inappropriate ioctl for device - ... - (Run 'diff -u tests/generic/466.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/466.out.bad' to see the entire diff) -generic/467 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/467.out.bad) - --- tests/generic/467.out 2018-06-27 21:12:13.667235146 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/467.out.bad 2019-10-10 23:22:22.324016522 +0200 - @@ -1,9 +1,82 @@ - QA output created by 467 - test_file_handles TEST_DIR/467-dir -dp - test_file_handles TEST_DIR/467-dir -rp - +open_by_handle(/var/tmp/check-gocryptfs/testdir/467-dir/file000000) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/467-dir/file000001) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/467-dir/file000002) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/467-dir/file000003) returned 116 incorrectly on a linked file! - ... - (Run 'diff -u tests/generic/467.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/467.out.bad' to see the entire diff) -generic/468 [not run] fuse.gocryptfs does not support shutdown -generic/469 16s ... 4s -generic/470 [not run] This test requires a valid $LOGWRITES_DEV -generic/471 [not run] xfs_io pwrite failed (old kernel/wrong fs?) -generic/472 [not run] swapfiles are not supported -generic/474 [not run] fuse.gocryptfs does not support shutdown -generic/475 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/476 979s ... 940s -generic/477 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/477.out.bad) - --- tests/generic/477.out 2018-06-27 21:12:13.669235154 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/477.out.bad 2019-10-10 23:38:15.586197915 +0200 - @@ -1,5 +1,48 @@ - QA output created by 477 - test_file_handles after cycle mount - +open_by_handle(/var/tmp/check-gocryptfs/testdir/file000000) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/file000001) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/file000002) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/file000003) returned 116 incorrectly on a linked file! - +open_by_handle(/var/tmp/check-gocryptfs/testdir/file000004) returned 116 incorrectly on a linked file! - ... - (Run 'diff -u tests/generic/477.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/477.out.bad' to see the entire diff) -generic/478 44s ... 35s -generic/479 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/480 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/481 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/482 [not run] This test requires a valid $LOGWRITES_DEV -generic/483 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/484 - output mismatch (see /home/jakob.donotbackup/code/fuse-xfstests/results//generic/484.out.bad) - --- tests/generic/484.out 2018-06-27 21:12:13.676235180 +0200 - +++ /home/jakob.donotbackup/code/fuse-xfstests/results//generic/484.out.bad 2019-10-10 23:38:54.996371174 +0200 - @@ -1,2 +1,3 @@ - QA output created by 484 - +record lock is not preserved across execve(2) - Silence is golden - ... - (Run 'diff -u tests/generic/484.out /home/jakob.donotbackup/code/fuse-xfstests/results//generic/484.out.bad' to see the entire diff) -generic/485 [not run] xfs_io finsert failed (old kernel/wrong fs?) -generic/486 0s ... 0s -generic/487 [not run] This test requires a valid $SCRATCH_LOGDEV -generic/488 1s ... 2s -generic/489 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/490 15s ... 3s -generic/491 [not run] fuse.gocryptfs does not support freezing -generic/492 [not run] xfs_io label support is missing (missing syscall?) -generic/493 [not run] swapfiles are not supported -generic/494 [not run] swapfiles are not supported -generic/495 [not run] swapfiles are not supported -generic/496 [not run] swapfiles are not supported -generic/497 [not run] swapfiles are not supported -generic/498 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/499 [not run] xfs_io fcollapse failed (old kernel/wrong fs?) -generic/500 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/501 [not run] Reflink not supported by scratch filesystem type: fuse.gocryptfs -generic/502 [not run] require /var/tmp/check-gocryptfs/scratchdev to be valid block disk -generic/503 [not run] xfs_io fpunch failed (old kernel/wrong fs?) -generic/504 15s ... 3s -shared/001 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/002 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/003 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/004 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/006 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/008 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/009 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/010 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/032 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/272 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/289 [not run] not suitable for this filesystem type: fuse.gocryptfs -shared/298 [not run] not suitable for this filesystem type: fuse.gocryptfs -Ran: generic/001 generic/002 generic/003 generic/004 generic/005 generic/006 generic/007 generic/008 generic/009 generic/010 generic/011 generic/012 generic/013 generic/014 generic/015 generic/016 generic/017 generic/018 generic/020 generic/021 generic/022 generic/023 generic/024 generic/025 generic/026 generic/027 generic/028 generic/029 generic/030 generic/031 generic/032 generic/033 generic/034 generic/035 generic/036 generic/037 generic/038 generic/039 generic/040 generic/041 generic/043 generic/044 generic/045 generic/046 generic/047 generic/048 generic/049 generic/050 generic/051 generic/052 generic/053 generic/054 generic/055 generic/056 generic/057 generic/058 generic/059 generic/060 generic/061 generic/062 generic/063 generic/064 generic/065 generic/066 generic/067 generic/068 generic/069 generic/070 generic/071 generic/072 generic/073 generic/074 generic/075 generic/076 generic/077 generic/078 generic/079 generic/080 generic/081 generic/082 generic/083 generic/084 generic/085 generic/086 generic/087 generic/088 generic/089 generic/090 generic/091 generic/092 generic/093 generic/094 generic/095 generic/096 generic/097 generic/098 generic/099 generic/100 generic/101 generic/102 generic/103 generic/104 generic/105 generic/106 generic/107 generic/108 generic/109 generic/110 generic/111 generic/112 generic/113 generic/114 generic/115 generic/116 generic/117 generic/118 generic/119 generic/120 generic/121 generic/122 generic/123 generic/124 generic/126 generic/127 generic/128 generic/129 generic/130 generic/131 generic/132 generic/133 generic/134 generic/135 generic/136 generic/137 generic/138 generic/139 generic/140 generic/141 generic/142 generic/143 generic/144 generic/145 generic/146 generic/147 generic/148 generic/149 generic/150 generic/151 generic/152 generic/153 generic/154 generic/155 generic/156 generic/157 generic/158 generic/159 generic/160 generic/161 generic/162 generic/163 generic/164 generic/165 generic/166 generic/167 generic/168 generic/169 generic/170 generic/171 generic/172 generic/173 generic/174 generic/175 generic/176 generic/177 generic/178 generic/179 generic/180 generic/181 generic/182 generic/183 generic/184 generic/185 generic/186 generic/187 generic/188 generic/189 generic/190 generic/191 generic/192 generic/193 generic/194 generic/195 generic/196 generic/197 generic/198 generic/199 generic/200 generic/201 generic/202 generic/203 generic/204 generic/205 generic/206 generic/207 generic/208 generic/209 generic/210 generic/211 generic/212 generic/213 generic/214 generic/215 generic/216 generic/217 generic/218 generic/219 generic/220 generic/221 generic/222 generic/223 generic/224 generic/225 generic/226 generic/227 generic/228 generic/229 generic/230 generic/231 generic/232 generic/233 generic/234 generic/235 generic/236 generic/237 generic/238 generic/239 generic/240 generic/241 generic/242 generic/243 generic/244 generic/245 generic/246 generic/247 generic/248 generic/249 generic/250 generic/252 generic/253 generic/254 generic/255 generic/256 generic/257 generic/258 generic/259 generic/260 generic/261 generic/262 generic/263 generic/264 generic/265 generic/266 generic/267 generic/268 generic/269 generic/270 generic/271 generic/272 generic/273 generic/274 generic/275 generic/276 generic/277 generic/278 generic/279 generic/280 generic/281 generic/282 generic/283 generic/284 generic/285 generic/286 generic/287 generic/288 generic/289 generic/290 generic/291 generic/292 generic/293 generic/294 generic/295 generic/296 generic/297 generic/298 generic/299 generic/300 generic/301 generic/302 generic/303 generic/304 generic/305 generic/306 generic/307 generic/308 generic/309 generic/310 generic/311 generic/312 generic/313 generic/314 generic/315 generic/316 generic/317 generic/318 generic/319 generic/320 generic/321 generic/322 generic/323 generic/324 generic/325 generic/326 generic/327 generic/328 generic/329 generic/330 generic/331 generic/332 generic/333 generic/334 generic/335 generic/336 generic/337 generic/338 generic/339 generic/340 generic/341 generic/342 generic/343 generic/344 generic/345 generic/346 generic/347 generic/348 generic/352 generic/353 generic/354 generic/355 generic/356 generic/357 generic/358 generic/359 generic/360 generic/361 generic/362 generic/363 generic/364 generic/365 generic/366 generic/367 generic/368 generic/369 generic/370 generic/371 generic/372 generic/373 generic/374 generic/375 generic/376 generic/377 generic/378 generic/379 generic/380 generic/381 generic/382 generic/383 generic/384 generic/385 generic/386 generic/387 generic/388 generic/389 generic/390 generic/391 generic/392 generic/393 generic/394 generic/395 generic/396 generic/397 generic/398 generic/399 generic/400 generic/401 generic/402 generic/403 generic/404 generic/405 generic/406 generic/407 generic/408 generic/409 generic/410 generic/411 generic/412 generic/413 generic/414 generic/415 generic/416 generic/417 generic/418 generic/419 generic/420 generic/421 generic/422 generic/423 generic/424 generic/425 generic/426 generic/427 generic/428 generic/429 generic/430 generic/431 generic/432 generic/433 generic/434 generic/435 generic/436 generic/437 generic/438 generic/439 generic/440 generic/441 generic/443 generic/444 generic/445 generic/446 generic/447 generic/448 generic/449 generic/450 generic/451 generic/452 generic/453 generic/454 generic/455 generic/456 generic/457 generic/458 generic/459 generic/460 generic/461 generic/462 generic/463 generic/464 generic/465 generic/466 generic/467 generic/468 generic/469 generic/470 generic/471 generic/472 generic/474 generic/475 generic/476 generic/477 generic/478 generic/479 generic/480 generic/481 generic/482 generic/483 generic/484 generic/485 generic/486 generic/487 generic/488 generic/489 generic/490 generic/491 generic/492 generic/493 generic/494 generic/495 generic/496 generic/497 generic/498 generic/499 generic/500 generic/501 generic/502 generic/503 generic/504 shared/001 shared/002 shared/003 shared/004 shared/006 shared/008 shared/009 shared/010 shared/032 shared/272 shared/289 shared/298 -Not run: generic/003 generic/004 generic/008 generic/009 generic/012 generic/016 generic/017 generic/018 generic/021 generic/022 generic/024 generic/025 generic/026 generic/031 generic/032 generic/033 generic/034 generic/038 generic/039 generic/040 generic/041 generic/043 generic/044 generic/045 generic/046 generic/047 generic/048 generic/049 generic/050 generic/051 generic/052 generic/053 generic/054 generic/055 generic/056 generic/057 generic/058 generic/059 generic/060 generic/061 generic/063 generic/064 generic/065 generic/066 generic/067 generic/068 generic/072 generic/073 generic/076 generic/077 generic/078 generic/079 generic/081 generic/082 generic/085 generic/090 generic/092 generic/094 generic/095 generic/096 generic/099 generic/101 generic/104 generic/105 generic/106 generic/107 generic/108 generic/110 generic/111 generic/114 generic/115 generic/116 generic/118 generic/119 generic/120 generic/121 generic/122 generic/134 generic/136 generic/137 generic/138 generic/139 generic/140 generic/142 generic/143 generic/144 generic/145 generic/146 generic/147 generic/148 generic/149 generic/150 generic/151 generic/152 generic/153 generic/154 generic/155 generic/156 generic/157 generic/158 generic/159 generic/160 generic/161 generic/162 generic/163 generic/164 generic/165 generic/166 generic/167 generic/168 generic/170 generic/171 generic/172 generic/173 generic/174 generic/175 generic/176 generic/177 generic/178 generic/179 generic/180 generic/181 generic/182 generic/183 generic/185 generic/186 generic/187 generic/188 generic/189 generic/190 generic/191 generic/192 generic/194 generic/195 generic/196 generic/197 generic/199 generic/200 generic/201 generic/202 generic/203 generic/205 generic/206 generic/216 generic/217 generic/218 generic/219 generic/220 generic/222 generic/223 generic/225 generic/227 generic/229 generic/230 generic/231 generic/232 generic/233 generic/234 generic/235 generic/237 generic/238 generic/240 generic/242 generic/243 generic/244 generic/250 generic/252 generic/253 generic/254 generic/255 generic/256 generic/259 generic/260 generic/261 generic/262 generic/264 generic/265 generic/266 generic/267 generic/268 generic/270 generic/271 generic/272 generic/276 generic/277 generic/278 generic/279 generic/280 generic/281 generic/282 generic/283 generic/284 generic/287 generic/288 generic/289 generic/290 generic/291 generic/292 generic/293 generic/295 generic/296 generic/297 generic/298 generic/299 generic/300 generic/301 generic/302 generic/303 generic/304 generic/305 generic/307 generic/311 generic/316 generic/318 generic/319 generic/321 generic/322 generic/324 generic/325 generic/326 generic/327 generic/328 generic/329 generic/330 generic/331 generic/332 generic/333 generic/334 generic/335 generic/336 generic/338 generic/341 generic/342 generic/343 generic/347 generic/348 generic/352 generic/353 generic/356 generic/357 generic/358 generic/359 generic/361 generic/362 generic/363 generic/364 generic/365 generic/366 generic/367 generic/368 generic/369 generic/370 generic/372 generic/373 generic/374 generic/375 generic/376 generic/379 generic/380 generic/381 generic/382 generic/383 generic/384 generic/385 generic/386 generic/387 generic/388 generic/389 generic/390 generic/392 generic/395 generic/396 generic/397 generic/398 generic/399 generic/400 generic/402 generic/404 generic/405 generic/407 generic/408 generic/409 generic/410 generic/411 generic/413 generic/414 generic/415 generic/417 generic/418 generic/419 generic/420 generic/421 generic/424 generic/425 generic/429 generic/435 generic/439 generic/440 generic/441 generic/444 generic/446 generic/447 generic/449 generic/450 generic/455 generic/456 generic/457 generic/458 generic/459 generic/460 generic/461 generic/462 generic/463 generic/468 generic/470 generic/471 generic/472 generic/474 generic/475 generic/479 generic/480 generic/481 generic/482 generic/483 generic/485 generic/487 generic/489 generic/491 generic/492 generic/493 generic/494 generic/495 generic/496 generic/497 generic/498 generic/499 generic/500 generic/501 generic/502 generic/503 shared/001 shared/002 shared/003 shared/004 shared/006 shared/008 shared/009 shared/010 shared/032 shared/272 shared/289 shared/298 -Failures: generic/035 generic/062 generic/093 generic/097 generic/403 generic/426 generic/466 generic/467 generic/477 generic/484 -Failed 10 of 507 tests - -Runtime was 4046 seconds -``` diff --git a/Documentation/duplicate-inodes.txt b/Documentation/duplicate-inodes.txt deleted file mode 100644 index 36fb89c..0000000 --- a/Documentation/duplicate-inodes.txt +++ /dev/null @@ -1,36 +0,0 @@ -ls: cannot access foo: No such file or directory -ls: cannot access foo: No such file or directory -ls: cannot access foo: No such file or directory -ls: cannot access foo: No such file or directory -36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo -36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo -36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo -36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo - - -u1026@d8min:/mnt/synology/public/tmp/g1$ strace -e lstat -p 8899 -f -Process 8899 attached with 10 threads -2017/11/11 18:12:21 Dispatch 238: LOOKUP, NodeId: 1. names: [foo] 4 bytes -[pid 10539] lstat("/mnt/synology/public/tmp/g1/a/4DZNVle_txclugO7n_FRIg", 0xc4241adbe8) = -1 ENOENT (No such file or directory) -2017/11/11 18:12:21 Serialize 238: LOOKUP code: OK value: {NodeId: 0 Generation=0 EntryValid=1.000 AttrValid=0.000 Attr={M00 SZ=0 L=0 0:0 B0*0 i0:0 A 0.000000000 M 0.000000000 C 0.000000000}} -2017/11/11 18:12:22 Dispatch 239: LOOKUP, NodeId: 1. names: [foo] 4 bytes -[pid 8903] lstat("/mnt/synology/public/tmp/g1/a/Xsy8mhdcIh0u9aiI7-iLiw", {st_mode=S_IFREG|0777, st_size=0, ...}) = 0 -2017/11/11 18:12:22 Serialize 239: LOOKUP code: OK value: {NodeId: 3 Generation=4 EntryValid=1.000 AttrValid=1.000 Attr={M0100777 SZ=0 L=1 1026:100 B0*16384 i0:36962337 A 1510419642.457639700 M 1510419642.457639700 C 1510419702.353712800}} - - -Call Trace: - -nodefs/fsops.go (c *rawBridge) Lookup - nodefs/fsops.go (c *FileSystemConnector) internalLookup - nodefs/inode.go (n *Inode) GetChild - pathfs/pathfs.go (n *pathInode) GetAttr - pathfs/pathfs.go (n *pathInode) GetPath - nodefs/inode.go (n *Inode) Parent() - pathfs/loopback.go (fs *loopbackFileSystem) GetAttr - -Call Trace 2 (new child): - -nodefs/fsops.go (c *rawBridge) Lookup - nodefs/fsops.go (c *FileSystemConnector) internalLookup - pathfs/pathfs.go (n *pathInode) Lookup - pathfs/pathfs.go (n *pathInode) findChild diff --git a/Documentation/extractloop.md b/Documentation/extractloop.md deleted file mode 100644 index eca66bb..0000000 --- a/Documentation/extractloop.md +++ /dev/null @@ -1,56 +0,0 @@ -# extractloop.bash results - -Memory usage stabilises at 141MiB, we do not run out of fds, -and the iteration time is stable around 38 seconds: - -![](extractloop_plot_csv.png) - -What the extractloop stress test does is (top comment in `tests/stress_tests/extractloop.bash`): - -``` -# Mount a gocryptfs filesystem somewhere on /tmp, then run two parallel -# infinite loops inside that do the following: -# 1) Extract linux-3.0.tar.gz -# 2) Verify the md5sums -# 3) Delete, go to (1) -# -# This test is good at discovering inode-related memory leaks because it creates -# huge numbers of files. -``` - -Test output (trimmed for brevity): -``` -~/go/src/github.com/rfjakob/gocryptfs/tests/stress_tests$ ./extractloop.bash - -20803 (process ID) old priority 0, new priority 19 -Testing gocryptfs -Test dir: /tmp/extractloop_tmpdir/SMc -'/tmp/extractloop.csv' -> '/tmp/extractloop_tmpdir/SMc.csv' -[looper 2] Starting -[looper 1] Starting -[looper 2] Iteration 1 done, 42 seconds, RSS 36020 kiB -[looper 1] Iteration 1 done, 42 seconds, RSS 36020 kiB -[looper 2] Iteration 2 done, 40 seconds, RSS 45400 kiB -[looper 1] Iteration 2 done, 40 seconds, RSS 45400 kiB -[looper 1] Iteration 3 done, 40 seconds, RSS 53396 kiB -[looper 2] Iteration 3 done, 40 seconds, RSS 53396 kiB -[looper 1] Iteration 4 done, 39 seconds, RSS 64588 kiB -[looper 2] Iteration 4 done, 40 seconds, RSS 64588 kiB -[looper 1] Iteration 5 done, 40 seconds, RSS 64588 kiB -[looper 2] Iteration 5 done, 39 seconds, RSS 64588 kiB -[looper 1] Iteration 6 done, 39 seconds, RSS 71628 kiB -[...] -[looper 1] Iteration 945 done, 38 seconds, RSS 140832 kiB -[looper 2] Iteration 946 done, 38 seconds, RSS 140832 kiB -[looper 1] Iteration 946 done, 38 seconds, RSS 140832 kiB -[looper 1] Iteration 947 done, 37 seconds, RSS 140832 kiB -[looper 2] Iteration 947 done, 37 seconds, RSS 140832 kiB -[looper 1] Iteration 948 done, 38 seconds, RSS 140832 kiB -[looper 2] Iteration 948 done, 38 seconds, RSS 140832 kiB -[looper 1] Iteration 949 done, 38 seconds, RSS 140832 kiB -[looper 2] Iteration 949 done, 38 seconds, RSS 140832 kiB -[looper 1] Iteration 950 done, 38 seconds, RSS 140832 kiB -[looper 2] Iteration 950 done, 38 seconds, RSS 140832 kiB -[looper 1] Iteration 951 done, 38 seconds, RSS 140832 kiB -[looper 2] Iteration 951 done, 38 seconds, RSS 140832 kiB -``` diff --git a/Documentation/extractloop_plot_csv.png b/Documentation/extractloop_plot_csv.png deleted file mode 100644 index 788fdb9..0000000 Binary files a/Documentation/extractloop_plot_csv.png and /dev/null differ diff --git a/Documentation/file-format.md b/Documentation/file-format.md deleted file mode 100644 index 04bd2fe..0000000 --- a/Documentation/file-format.md +++ /dev/null @@ -1,39 +0,0 @@ -File Format -=========== - -Header - - 2 bytes header version (big endian uint16, currently 2) - 16 bytes file id - -Data block, default AES-GCM mode - - 16 bytes GCM IV (nonce) - 1-4096 bytes encrypted data - 16 bytes GHASH - -Data block, AES-SIV mode (used in reverse mode, or when explicitly enabled with `-init -aessiv`) - - 16 bytes nonce - 16 bytes SIV - 1-4096 bytes encrypted data - -Full block overhead = 32/4096 = 1/128 = 0.78125 % - -Example: 1-byte file --------------------- - - Header 18 bytes - Data block 33 bytes - -Total: 51 bytes - - -Example: 5000-byte file ------------------------ - - Header 18 bytes - Data block 4128 bytes - Data block 936 bytes - -Total: 5082 bytes diff --git a/Documentation/folders-side-by-side.gif b/Documentation/folders-side-by-side.gif deleted file mode 100644 index c0664af..0000000 Binary files a/Documentation/folders-side-by-side.gif and /dev/null differ diff --git a/Documentation/gocryptfs-logo.png b/Documentation/gocryptfs-logo.png deleted file mode 100644 index 0965dc4..0000000 Binary files a/Documentation/gocryptfs-logo.png and /dev/null differ diff --git a/Documentation/performance-reverse.txt b/Documentation/performance-reverse.txt deleted file mode 100644 index 071b31d..0000000 --- a/Documentation/performance-reverse.txt +++ /dev/null @@ -1,10 +0,0 @@ -Results from benchmark-reverse.bash - -VERSION LS CAT ENV -------- --- ---- --- -v1.3 2.1 19.9 go1.9.2 -v1.4 2.1 18.2 -v1.5 3.4 19.6 go1.10.3, Linux 4.17.12 -v1.6 3.6 19.9 go1.10.3, Linux 4.17.12 - -(seconds) diff --git a/Documentation/performance.txt b/Documentation/performance.txt deleted file mode 100644 index ab35de1..0000000 --- a/Documentation/performance.txt +++ /dev/null @@ -1,86 +0,0 @@ -Tests of gocryptfs v1.7 and later are run on an -Intel Core i5-3470 CPU (quad-core Ivy Bridge, AES-NI supported). -Earlier tests on a Pentium G630 (Dual-core Sandy Bridge, no AES-NI). - -The working directory is on tmpfs. -The untar test uses https://cdn.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.gz . -The archive is placed on tmpfs as well. - -WRITE: dd if=/dev/zero of=zero bs=131072 count=2000 -READ: dd if=zero of=/dev/null bs=131072 count=2000 -UNTAR: time tar xzf ../linux-3.0.tar.gz -MD5: time md5sum --quiet -c linux-3.0.md5sums -LS: time ls -lR linux-3.0 > /dev/null -RM: time rm -Rf linux-3.0 - -(or just run benchmark.bash) - -VERSION WRITE READ UNTAR MD5 LS RM ENV CHANGE? COMMIT MSG -********************** -* CPU = Pentium G630 * -********************** -v0.4 48 1.5 5 -v0.5-rc1 56 7 19 -v0.5-rc1-1 54 4.1 9 -v0.5-rc1-2 45 1.7 3.4 -v0.6 47 1.8 4.3 -v0.7 43 1.7 4.3 -v0.7.2 26 1.8 4.3 -v0.8 23 1.8 4.3 -v0.9-rc2 94 24 1.8 4.5 -v0.9 94 24 1.8 4.5 -v0.11 104 22 1.7 4.5 -v1.1 104 20 1.5 3.4 go1.7.1 -v1.1.1-34 112 22 1.5 3.6 go1.7.3 -v1.2.1-33 112 21 12 1.6 4.4 go1.8 --serialize_reads 116 21 39 1.5 4.4 (v1.2.1-33 with -serialize_reads) -v1.3-27 113 20 11 1.4 4.2 -v1.3-53-gf44902a 119 19 12 1.6 4.1 -v1.3-64-g80516ed 123 19 11 1.3 4.2 -v1.3-67-g9837cb0 125 19 11 1.4 4.2 go1.8.3, Linux 4.10 -v1.3-69-ge52594d 145 19.0 11.6 1.4 4.1 -v1.4-1-g3c6fe98 154 17.2 11.7 1.4 4.1 -v1.4-5-g0cc6f53 182 144 16.7 11.1 1.3 3.3 -v1.4-8-g80676c6 178 148 16.1 11.0 1.3 4.0 -v1.4-14-g9f4bd76 182 286 15.4 7.5 1.3 4.1 -v1.4-45-gd5671b7 183 282 14.9 7.3 1.1 2.9 -v1.4-45-gd5671b7 252 285 15.5 7.2 1.1 2.9 go1.8.3, Linux 4.11 -v1.4.1 253 285 16.0 7.4 1.3 3.0 go1.9, Linux 4.12.5 -v1.4.1-6-g276567e 258 289 16.1 7.5 1.3 3.0 -v1.5 228 292 17.6 9.3 1.5 3.5 go1.10.2, Linux 4.16.8 -v1.6 250 289 17.7 8.0 1.3 3.2 go1.10.3, Linux 4.17.12 -v1.7-beta1 229 278 17.1 8.8 1.7 3.2 go1.11.4, Linux 4.19.12 -v1.7-rc1 226 289 17.6 8.9 1.7 2.9 -******************************************** -* CPU = Core i5-3470, governor = powersave * -******************************************** -v1.7 232 698 12.2 9.4 1.7 4.3 go1.12.9, Linux 5.2.17 -v1.7.1 450 697 11.5 9.5 1.5 3.6 -********************************************** -* CPU = Core i5-3470, governor = performance * -********************************************** -v1.7.1 556 1000 9.0 4.2 0.9 2.0 go1.13.6, Linux 5.4.17 -v1.7.1 577 1100 8.3 4.2 0.9 2.0 go1.14.2, Linux 5.6.7 -v1.7.1-60-gb23f77c 472 1100 12.7 4.2 0.8 2.0 -v1.8.0 410 1000 17.5 6.7 5.4 7.8 go1.15.3, Linux 5.8.13 -v2.0-beta1 387 1100 36.2 14.4 12.8 19.3 -v2.0-beta1-5-gc943ed3 417 1000 30.4 12.7 9.9 16.4 -v2.0-beta1-6 529 1100 17.5 9.0 3.6 9.0 -v2.0-beta1-9-g029e44d 477 1000 15.5 8.7 2.8 7.6 -v2.0-beta2-16-geaca820 542 997 15.9 8.8 6.2 7.8 go1.16.2, Linux 5.11.10 fusefrontend: do not encrypt ACLs -v2.0-beta2-36-g6aae2aa 505 1000 16.1 8.2 6.3 7.7 -v2.0-beta2-37-g24d5d39 558 1000 12.3 6.4 4.4 2.8 fs: add initial dirfd caching -v2.0-beta2-42-g4a07d65 549 1000 8.2 4.7 1.8 2.4 fusefrontend: make dirCache work for "node itself" -v2.0 420 1000 8.5 4.5 1.8 2.3 go1.16.5, Linux 5.11.21 - -Results for EncFS for comparison (benchmark.bash -encfs): - -VERSION WRITE READ UNTAR MD5 LS RM -********************** -* CPU = Pentium G630 * -********************** -encfs v1.9.1 95 20 8 2.8 3.8 -********************************************** -* CPU = Core i5-3470, governor = performance * -********************************************** -encfs v1.9.5 138 459 12.2 5.1 2.2 3.0 diff --git a/Makefile b/Makefile deleted file mode 100644 index bdc05cf..0000000 --- a/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -.phony: build -build: - ./build.bash - ./Documentation/MANPAGE-render.bash - -.phony: test -test: - ./test.bash - -.phony: root_test -root_test: - ./build.bash - cd tests/root_test && go test -c && sudo ./root_test.test -test.v - -.phony: format -format: - go fmt ./... - -.phony: install -install: - install -Dm755 -t "$(DESTDIR)/usr/bin/" gocryptfs - install -Dm755 -t "$(DESTDIR)/usr/bin/" gocryptfs-xray/gocryptfs-xray - install -Dm644 -t "$(DESTDIR)/usr/share/man/man1/" Documentation/gocryptfs.1 - install -Dm644 -t "$(DESTDIR)/usr/share/man/man1/" Documentation/gocryptfs-xray.1 - install -Dm644 -t "$(DESTDIR)/usr/share/licenses/gocryptfs" LICENSE diff --git a/README.md b/README.md index cac5f97..ca05427 100644 --- a/README.md +++ b/README.md @@ -1,700 +1,6 @@ -[![gocryptfs](Documentation/gocryptfs-logo.png)](https://nuetzlich.net/gocryptfs/) -[![Build Status](https://travis-ci.org/rfjakob/gocryptfs.svg?branch=master)](https://travis-ci.org/rfjakob/gocryptfs) -[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -[![Go Report Card](https://goreportcard.com/badge/github.com/rfjakob/gocryptfs)](https://goreportcard.com/report/github.com/rfjakob/gocryptfs) -[![Latest release](https://img.shields.io/github/release/rfjakob/gocryptfs.svg)](https://github.com/rfjakob/gocryptfs/releases) -[![Homebrew version](https://img.shields.io/homebrew/v/gocryptfs.svg)](https://formulae.brew.sh/formula/gocryptfs#default) +libgocryptfs is a re-desing of the original [gocryptfs](https://github.com/rfjakob/gocryptfs) code to work as a library. Volumes are not mounted with [FUSE](https://www.kernel.org/doc/html/latest/filesystems/fuse.html) but rather opened in memory and accessed through API calls. What the purpose ? +- Allow the use of gocryptfs in embedded devices where FUSE is not available (such as Android) +- Reduce attack surface by restricting volumes access to only one process rather than one user -An encrypted overlay filesystem written in Go. -Official website: https://nuetzlich.net/gocryptfs ([markdown source](https://github.com/rfjakob/gocryptfs-website/blob/master/docs/index.md)). - -![Folders side-by-side animation](Documentation/folders-side-by-side.gif) - -gocryptfs is built on top the excellent -[go-fuse](https://github.com/hanwen/go-fuse) FUSE library. -This project was inspired by EncFS and strives to fix its security -issues while providing good performance -([benchmarks](https://nuetzlich.net/gocryptfs/comparison/#performance)). -For details on the security of gocryptfs see the -[Security](https://nuetzlich.net/gocryptfs/security/) design document. - -All tags from v0.4 onward are signed by the *gocryptfs signing key*. -Please check [Signed Releases](https://nuetzlich.net/gocryptfs/releases/) -for details. - -Current Status --------------- - -gocryptfs has reached version 1.0 on July 17, 2016. It has gone through -hours and hours of stress (fsstress, extractloop.bash) and correctness -testing (xfstests). It is now considered ready for general consumption. - -The old principle still applies: Important data should have a backup. -Also, keep a copy of your master key (printed on mount) in a safe place. -This allows you to access the data even if the gocryptfs.conf config -file is damaged or you lose the password. - -The security of gocryptfs has been audited in March 3, 2017. The audit -is available [here (defuse.ca)](https://defuse.ca/audits/gocryptfs.htm). - -Platforms ---------- - -Linux is gocryptfs' native platform. - -Beta-quality Mac OS X support is available, which means most things work -fine but you may hit an occasional problem. Check out -[ticket #15](https://github.com/rfjakob/gocryptfs/issues/15) for the history -of Mac OS X support but please create a new ticket if you hit a problem. - -For Windows, an independent C++ reimplementation can be found here: -[cppcryptfs](https://github.com/bailey27/cppcryptfs) - -A standalone Python tool that can decrypt files & file names is here: -[gocryptfs-inspect](https://github.com/slackner/gocryptfs-inspect) - -Installation ------------- -Precompiled binaries that work on all x86_64 Linux systems are available for download from the github releases page. - -On Debian, gocryptfs is available as a deb package: -```bash -apt install gocryptfs -``` - -On Mac OS X, gocryptfs is available as a Homebrew formula: -```bash -brew install gocryptfs -``` - -On Fedora, gocryptfs is available as an rpm package: -```bash -sudo dnf install gocryptfs -``` - -If you use the standalone binary, make sure you install the `fuse` package -from your distributions package repository before running `gocryptfs`. - -See the [Quickstart](https://nuetzlich.net/gocryptfs/quickstart/) page for more info. - -Testing -------- - -gocryptfs comes with is own test suite that is constantly expanded as features are -added. Run it using `./test.bash`. It takes about 1 minute and requires FUSE -as it mounts several test filesystems. - -The `stress_tests` directory contains stress tests that run indefinitely. - -In addition, I have ported `xfstests` to FUSE, the result is the -[fuse-xfstests](https://github.com/rfjakob/fuse-xfstests) project. gocryptfs -passes the "generic" tests with one exception, results: [XFSTESTS.md](Documentation/XFSTESTS.md) - -A lot of work has gone into this. The testing has found bugs in gocryptfs -as well as in the go-fuse library. - -Compile -------- - -Install Go 1.11 or higher: - -* Debian/Ubuntu: `apt install golang` -* Fedora: `dnf install golang` - -Then, download the source code and compile: - - $ git clone https://github.com/rfjakob/gocryptfs.git - $ cd gocryptfs - $ ./build-without-openssl.bash - -This will compile a static binary that uses the Go stdlib crypto backend. - -If you want to use the OpenSSL crypto backend (faster on -old CPUs lacking AES-NI), you have to install a few dependencies: - -* Debian/Ubuntu: `apt install libssl-dev gcc pkg-config` -* Fedora: `dnf install openssl-devel gcc pkg-config` - -Then, run: - - $ ./build.bash - -Use ---- - - $ mkdir cipher plain - $ ./gocryptfs -init cipher - $ ./gocryptfs cipher plain - -See the [Quickstart](https://nuetzlich.net/gocryptfs/quickstart/) page for more info. - -The [MANPAGE.md](Documentation/MANPAGE.md) describes all available command-line options. - -Use: Reverse Mode ------------------ - - $ mkdir cipher plain - $ ./gocryptfs -reverse -init plain - $ ./gocryptfs -reverse plain cipher - -Graphical Interface -------------------- - -The [SiriKali](https://mhogomchungu.github.io/sirikali/) project supports -gocryptfs and runs on Linux and OSX. - -[cppcryptfs](https://github.com/bailey27/cppcryptfs) on Windows provides -its own GUI. - -Stable CLI ABI --------------- - -If you want to call gocryptfs from your app or script, see -[CLI_ABI.md](Documentation/CLI_ABI.md) for the official stable -ABI. This ABI is regression-tested by the test suite. - -Storage Overhead ----------------- - -* Empty files take 0 bytes on disk -* 18 byte file header for non-empty files (2 bytes version, 16 bytes random file id) -* 32 bytes of storage overhead per 4kB block (16 byte nonce, 16 bytes auth tag) - -[file-format.md](Documentation/file-format.md) contains a more detailed description. - -Performance ------------ - -Since version 0.7.2, gocryptfs is as fast as EncFS in the default mode, -and significantly faster than EncFS' "paranoia" mode that provides -a security level comparable to gocryptfs. - -On CPUs without AES-NI, gocryptfs uses OpenSSL through a thin wrapper called `stupidgcm`. -This provides a 4x speedup compared to Go's builtin AES-GCM -implementation. See [CPU-Benchmarks](https://github.com/rfjakob/gocryptfs/wiki/CPU-Benchmarks) -for details, or run `gocryptfs -speed` to see the encryption performance of your CPU. -Example for a CPU without AES-NI: - -``` -$ ./gocryptfs -speed -gocryptfs v2.0; go-fuse v2.1.1-0.20210508151621-62c5aa1919a7; 2021-06-06 go1.16.5 linux/amd64 -AES-GCM-256-OpenSSL 536.63 MB/s -AES-GCM-256-Go 831.84 MB/s (selected in auto mode) -AES-SIV-512-Go 155.85 MB/s -XChaCha20-Poly1305-Go 700.02 MB/s (benchmark only, not selectable yet) -``` - -You can run `./benchmark.bash` to run gocryptfs' canonical set of -benchmarks that include streaming write, extracting a linux kernel -tarball, recursively listing and finally deleting it. The output will -look like this: - -``` -$ ./benchmark.bash -Testing gocryptfs at /tmp/benchmark.bash.xFD: gocryptfs v2.0; go-fuse v2.1.1-0.20210508151621-62c5aa1919a7; 2021-06-06 go1.16.5 linux/amd64 -WRITE: 262144000 bytes (262 MB, 250 MiB) copied, 0,698174 s, 375 MB/s -READ: 262144000 bytes (262 MB, 250 MiB) copied, 0,268916 s, 975 MB/s -UNTAR: 8,970 -MD5: 4,846 -LS: 1,851 -RM: 2,367 -``` - -Changelog ---------- - -v2.0.1, 2021-06-07 -* Fix symlink creation reporting the wrong size, causing git to report it as modified - ([#574](https://github.com/rfjakob/gocryptfs/issues/574)) - -v2.0, 2021-06-05 -* Fix a few [issues discovered by xfstests](https://github.com/rfjakob/fuse-xfstests/wiki/results_2021-05-19) - * Biggest change: rewrite SEEK_HOLE / SEEK_DATA logic (now emulates 4k alignment) - -v2.0-beta4, 2021-05-15 -* **Make ACLs *actually* work (pass `-acl` to enable)** ([#536](https://github.com/rfjakob/gocryptfs/issues/536)) -* Blocklist `RENAME_EXCHANGE` and `RENAME_WHITEOUT` (broken as discovered by [fuse-xfstest/gocryptfs-2019-12](https://github.com/rfjakob/fuse-xfstests/tree/gocryptfs-2019-12)) - -v2.0-beta3, 2021-04-24 -* MANPAGE: Split options into sections acc. to where they apply ([#517](https://github.com/rfjakob/gocryptfs/issues/517)) -* `-idle`: count cwd inside the mount as busy ([#533](https://github.com/rfjakob/gocryptfs/issues/533)) -* Make `gocryptfs.diriv` and `gocryptfs.xxx.name` files world-readable to make encrypted backups easier - when mounting via [/etc/fstab](Documentation/MANPAGE.md#fstab) ([#539](https://github.com/rfjakob/gocryptfs/issues/539)) -* Make it work with MacFUSE v4.x ([#524](https://github.com/rfjakob/gocryptfs/issues/524)) -* **Disable ACL encryption**, it causes a lot of problems ([#543](https://github.com/rfjakob/gocryptfs/issues/543), - [#536](https://github.com/rfjakob/gocryptfs/issues/536)) - * Old encrypted ACLs are reported by `gocryptfs -fsck` but otherwise ignored - * This fixes inheritance, but does not yet enforce them correctly -* Include `gocryptfs-xray` in binary releases ([#496](https://github.com/rfjakob/gocryptfs/issues/496)) -* go-fuse: track *most recent* parent. This improves robustness when the filesystem is modified behind - the back of gocryptfs. Helps both with `-sharedstorage` and also without. - ([commit 1](https://github.com/hanwen/go-fuse/commit/c3186132bf8b7a04b5e5bc27489d88181f92e4e0), - [commit 2](https://github.com/hanwen/go-fuse/commit/a90e1f463c3f172a7690a6449fe5955a180dfec3), - [#549](https://github.com/rfjakob/gocryptfs/issues/549)) -* Add directory fd caching for 2x - 3x speed boost in small file ops compared to v2.0-beta2 - ([performance numbers](https://github.com/rfjakob/gocryptfs/blob/5cb1e55714aa92a848c0fb5fc3fa7b91625210fe/Documentation/performance.txt#L73)) - -v2.0-beta2, 2020-11-14 -* Improve [performance](Documentation/performance.txt#L69) -* Fix [GETATTR panic](https://github.com/rfjakob/gocryptfs/issues/519#issuecomment-718790790) in reverse mode - -v2.0-beta1, 2020-10-15 -* **Switch to the improved go-fuse [v2 API](https://pkg.go.dev/github.com/hanwen/go-fuse/v2@v2.0.3/fs)** - * This is a big change, a lot of code has been reorganized or rewritten - to fit the v2 API model. - * Please test & report bugs - * No changes to the on-disk format - * File descriptor caching is not yet implemented, - causing a slowdown. Caching will be implemented for v2.0 final. -* **Add support for FIDO2 tokens (`-fido2`, [#505](https://github.com/rfjakob/gocryptfs/pull/505))** -* Add `-encrypt-paths` / `-decrypt-paths` functionality to `gocryptfs-xray` - ([#416](https://github.com/rfjakob/gocryptfs/issues/416)) -* Accept multiple `-passfile`s - ([#288](https://github.com/rfjakob/gocryptfs/issues/288)) -* Make `-masterkey=stdin` work together with `-passwd` - ([#461](https://github.com/rfjakob/gocryptfs/issues/461)) -* Fix `Unknown opcode 2016` crash on Google Cloud - ([go-fuse #276](https://github.com/hanwen/go-fuse/issues/276), - [gocryptfs commit ec74d1d](https://github.com/rfjakob/gocryptfs/commit/ec74d1d2f4217a9a337d1db9902f32ae2aecaf33)) - -v1.8.0, 2020-05-09 -* Enable ACL support ([#453](https://github.com/rfjakob/gocryptfs/issues/453)) - * **Warning 2021-02-07**: This feature is incomplete! Do not use ACLs before gocryptfs v2.0 final! - Reading and writing ACLs works, but they are not enforced or inherited ([#542](https://github.com/rfjakob/gocryptfs/issues/542)) -* Ignore `.nfsXXX` temporary files - ([#367](https://github.com/rfjakob/gocryptfs/issues/431)) -* Handle inode number collisions from multiple devices - ([#435](https://github.com/rfjakob/gocryptfs/issues/435)) -* Drop `-nonempty` for fusermount3 - ([#440](https://github.com/rfjakob/gocryptfs/pull/440)) -* Reverse mode: improve inode number mapping and max=1000000000000000000 limitation - ([#457](https://github.com/rfjakob/gocryptfs/issues/457)) -* Enable `--buildmode=pie` ([#460](https://github.com/rfjakob/gocryptfs/pull/460)) -* Migrate from dep to Go Modules - ([commit cad711993](https://github.com/rfjakob/gocryptfs/commit/cad711993d67dd920f9749a09414dbbba6ab8136)) -* go mod: update dependencies - ([commit b23f77c](https://github.com/rfjakob/gocryptfs/commit/b23f77c8ead0dbb5ed59dd50e94f13aacf7dbaf1)) -* `gocryptfs -speed`: add XChaCha20-Poly1305-Go - ([#452](https://github.com/rfjakob/gocryptfs/issues/452)) -* Respect `GOMAXPROCS` environment variable - ([commit ff210a06f](https://github.com/rfjakob/gocryptfs/commit/ff210a06fb3097eecd5668ddb3ace9c76873eb00) -* Completely remove Trezor-related code (commit 1364b44ae356da31e24e5605fe73a307e9d6fb03) - * Has been disabled since v1.7 due to issues a third-party module. - * Please use FIDO2 instead (gocryptfs v2.0) - -v1.7.1, 2019-10-06 -* Support wild cards in reverse mode via `--exclude-wildcard` - ([#367](https://github.com/rfjakob/gocryptfs/pull/367)). Thanks @ekalin! -* Create `gocryptfs.diriv` files with 0440 permissions to make it easier to - share an encrypted folder via a network drive - ([#387](https://github.com/rfjakob/gocryptfs/issues/387)). - Note: as a security precaution, the owner must still manually - `chmod gocryptfs.conf 0440` to allow mounting. -* Allow the `nofail` option in `/etc/fstab` -* `-passwd` can now change the `-scryptn` parameter for existing filesystems - ([#400](https://github.com/rfjakob/gocryptfs/issues/400)) -* Fix `-idle` unmounting the filesystem despite recent activity - ([#421](https://github.com/rfjakob/gocryptfs/issues/421)) -* **Fix a race condition related to inode number reuse - ([#363](https://github.com/rfjakob/gocryptfs/issues/363))**. - It could be triggered by concurrently creating and deleting files and can lead to data loss - in the affected file. This bug was found by the automated tests on Travis - and was very hard to trigger locally. -* tests: use /var/tmp instead of /tmp by default - ([commit 8c4429](https://github.com/rfjakob/gocryptfs/commit/8c4429408716d9890a98a48c246d616dbfea7e31)) - -v1.7, 2019-03-17 -* **Fix possible symlink race attacks in forward mode** when using allow_other + plaintextnames - * If you use *both* `-allow_other` *and* `-plaintextnames`, you should upgrade. - Malicious users could trick gocryptfs into modifying files outside of `CIPHERDIR`, - or reading files inside `CIPHERDIR` that they should not have access to. - * If you do not use `-plaintextnames` (disabled per default), these attacks do - not work as symlinks are encrypted. - * Forward mode has been reworked to use the "\*at" family of system calls everywhere - (`Openat/Unlinkat/Symlinkat/...`). - * As a result, gocryptfs may run slightly slower, as the caching logic has been - replaced and is very simple at the moment. - * The possibility for such attacks was found during an internal code review. -* Reverse mode: fix excluded, unaccessible files showing up in directory listings - ([#285](https://github.com/rfjakob/gocryptfs/issues/285), - [#286](https://github.com/rfjakob/gocryptfs/issues/286)) -* gocryptfs-xray: add `-aessiv` flag for correctly parsing AES-SIV format files - ([#299](https://github.com/rfjakob/gocryptfs/issues/299)) -* Ensure that standard fds 0,1,2 are always initialized - ([#320](https://github.com/rfjakob/gocryptfs/issues/320)). - Prevents trouble in the unlikely case that gocryptfs is called with - stdin,stdout and/or stderr closed. -* `-extpass` now can be specified multiple times to support arguments containing spaces - ([#289](https://github.com/rfjakob/gocryptfs/issues/289)) -* Drop Fstatat, Mkdirat, Syslinkat, Fchownat, Unlinkat, Renameat, Openat emulation of MacOS - and instead use native functions (thanks @slackner !) -* Use `Setreuid` to robustly set the owner with allow_other (@slackner, - ([commit](https://github.com/rfjakob/gocryptfs/commit/03b9d65cce53fb95b7d489ecd03d0853b9b923fb))) -* Pack the rendered man page into the source code archive for user convenience - ([issue 355](https://github.com/rfjakob/gocryptfs/issues/355)) -* Disable Trezor support again (commit 16fac26c57ba303bf60266d24c17f5243e5ea376) - * Trezor support has been broken since Sept 2018 due to issues - in a third-party module ([#261](https://github.com/rfjakob/gocryptfs/issues/261)) - -v1.6.1, 2018-12-12 -* Fix "Operation not supported" chmod errors on Go 1.11 - ([#271](https://github.com/rfjakob/gocryptfs/issues/271)) - -v1.6, 2018-08-18 -* **Add `-e` / `-exclude` option** for reverse mode - ([#235](https://github.com/rfjakob/gocryptfs/issues/235), - [commit](https://github.com/rfjakob/gocryptfs/commit/ec2fdc19cf9358ae7ba09c528a5807b6b0760f9b)) -* Add support for the Trezor One HSM [PR#247](https://github.com/rfjakob/gocryptfs/pull/247), thanks @xaionaro! - * Use `./build.bash -tags enable_trezor` to compile with Trezor support - * Then, use `gocryptfs -init -trezor` to create a filesystem locked with a physical Trezor device. - * Note 2021-01-31: Support was removed again in gocryptfs v1.7. Please use `-fido2` in gocryptfs v2.0. -* Only print master key once, on init - ([#76](https://github.com/rfjakob/gocryptfs/issues/76), - [commit](https://github.com/rfjakob/gocryptfs/commit/6d64dfe8f7acd8e9ca4a659d26318e442c2db85a)) -* Fall back to buffered IO even when passed `O_DIRECT` - ([commit](https://github.com/rfjakob/gocryptfs/commit/893e41149ed353f355047003b89eeff456990e76)) - -v1.5, 2018-06-12 -* **Support extended attributes (xattr)** in forward mode - ([#217](https://github.com/rfjakob/gocryptfs/issues/217)). Older gocryptfs versions - will ignore the extended attributes. -* **Add `-fsck` function** - ([#191](https://github.com/rfjakob/gocryptfs/issues/191)) -* Fix clobbered timestamps on MacOS High Sierra - ([#229](https://github.com/rfjakob/gocryptfs/issues/229)) -* Add `-masterkey=stdin` functionality - ([#218](https://github.com/rfjakob/gocryptfs/issues/218)) -* Accept `-dev`/`-nodev`, `suid`/`nosuid`, `-exec`/`-noexec`, - `-ro`/`-rw` flags to make mounting via `/etc/fstab` possible. - Thanks @mahkoh! ([#233](https://github.com/rfjakob/gocryptfs/pull/233), - [commit](https://github.com/rfjakob/gocryptfs/commit/53d6a9999dd0e4c31636d16179f284fff35a35d9), - [commit](https://github.com/rfjakob/gocryptfs/commit/10212d791a3196c2c8705a7a3cccdeb14a8efdbe)) -* Fix a `logger` path issue on SuSE - [#225](https://github.com/rfjakob/gocryptfs/issues/225) -* Stop printing the help text on a "flag provided but not defined" - error ([commit](https://github.com/rfjakob/gocryptfs/commit/5ad26495fc86527bbfe75ac6b46528d49a373676)) - -v1.4.4, 2018-03-18 -* Overwrite secrets in memory with zeros as soon as possible - ([#211](https://github.com/rfjakob/gocryptfs/issues/211)) -* Fix Getdents problems on i386 and mips64le - ([#197](https://github.com/rfjakob/gocryptfs/issues/197), - [#200](https://github.com/rfjakob/gocryptfs/issues/200)) -* Make building with gccgo work - ([#201](https://github.com/rfjakob/gocryptfs/issues/201)) -* MacOS: fix `osxfuse: vnode changed generation` / `Error code -36` issue in go-fuse - ([#213](https://github.com/rfjakob/gocryptfs/issues/213), - [commit](https://github.com/hanwen/go-fuse/commit/a9ddcb8a4b609500fc59c89ccc9ee05f00a5fefd)) -* Fix various test issues on MacOS - -v1.4.3, 2018-01-21 -* **Fix several symlink race attacks** in connection with reverse mode - and allow_other. Thanks to @slackner for reporting and helping to fix - the issues: - * Fix symlink races in reverse mode - ([issue #165](https://github.com/rfjakob/gocryptfs/issues/165)) - * Fix symlink races in connection with `-allow_other` - ([issue #177](https://github.com/rfjakob/gocryptfs/issues/177)) -* Fix problems with special names when using `-plaintextnames` - ([issue #174](https://github.com/rfjakob/gocryptfs/issues/174)) -* Add `-devrandom` command-line option - ([commit](https://github.com/rfjakob/gocryptfs/commit/f3c777d5eaa682d878c638192311e52f9c204294)) -* Add `-sharedstorage` command-line option - ([commit](https://github.com/rfjakob/gocryptfs/commit/e36a0ebf189a826aaa63909c5518c16356f5f903), - [issue #156](https://github.com/rfjakob/gocryptfs/issues/156)) -* MacOS: let OSXFuse create the mountpoint if it does not exist - ([issue #194](https://github.com/rfjakob/gocryptfs/issues/194)) - -v1.4.2, 2017-11-01 -* Add `Gopkg.toml` file for `dep` vendoring and reproducible builds - ([issue #142](https://github.com/rfjakob/gocryptfs/issues/142)) -* MacOS: deal with `.DS_Store` files inside CIPHERDIR - ([issue #140](https://github.com/rfjakob/gocryptfs/issues/140)) -* Reverse mode: fix ENOENT error affecting names exactly 176 bytes long - ([issue #143](https://github.com/rfjakob/gocryptfs/issues/143)) -* Support kernels compiled with > 128 kiB FUSE request size (Synology NAS) - ([issue #145](https://github.com/rfjakob/gocryptfs/issues/145), - [commit](https://github.com/rfjakob/gocryptfs/commit/4954c87979efaf5b8184efccc7d9a38c21e4209b)) -* Fix a startup hang when `$PATH` contains the mountpoint - ([issue #146](https://github.com/rfjakob/gocryptfs/issues/146)) - -v1.4.1, 2017-08-21 -* **Use memory pools for buffer handling** ( - [3c6fe98](https://github.com/rfjakob/gocryptfs/commit/3c6fe98), - [b2a23e9](https://github.com/rfjakob/gocryptfs/commit/b2a23e9), - [12c0101](https://github.com/rfjakob/gocryptfs/commit/12c0101)) - * On my machine, this **doubles** the streaming read speed - (see [performance.txt](https://github.com/rfjakob/gocryptfs/blob/v1.4.1/Documentation/performance.txt#L38)) -* Implement and use the getdents(2) syscall for a more efficient - OpenDir implementation - ([e50a6a5](https://github.com/rfjakob/gocryptfs/commit/e50a6a5)) -* Purge masterkey from memory as soon as possible - ([issue #137](https://github.com/rfjakob/gocryptfs/issues/137)) -* Reverse mode: fix inode number collision between .name and .diriv - files - ([d12aa57](https://github.com/rfjakob/gocryptfs/commit/d12aa57)) -* Prevent the logger from holding stdout open - ([issue #130](https://github.com/rfjakob/gocryptfs/issues/130)) -* MacOS: make testing without openssl work properly - ([ccf1a84](https://github.com/rfjakob/gocryptfs/commit/ccf1a84)) -* MacOS: specify a volume name - ([9f8e19b](https://github.com/rfjakob/gocryptfs/commit/9f8e19b)) -* Enable writing to write-only files - ([issue #125](https://github.com/rfjakob/gocryptfs/issues/125)) - -v1.4, 2017-06-20 -* **Switch to static binary releases** - * From gocryptfs v1.4, I will only release statically-built binaries. - These support all Linux distributions but cannot use OpenSSL. - * OpenSSL is still supported - just compile from source! -* Add `-force_owner` option to allow files to be presented as owned by a - different user or group from the user running gocryptfs. Please see caveats - and guidance in the man page before using this functionality. -* Increase open file limit to 4096 ([#82](https://github.com/rfjakob/gocryptfs/issues/82)). -* Implement path decryption via ctlsock ([#84](https://github.com/rfjakob/gocryptfs/issues/84)). - Previously, decryption was only implemented for reverse mode. Now both - normal and reverse mode support both decryption and encryption of - paths via ctlsock. -* Add more specific exit codes for the most common failure modes, - documented in [CLI_ABI.md](Documentation/CLI_ABI.md) -* Reverse mode: make sure hard-linked files always return the same - ciphertext - ([commit 9ecf2d1a](https://github.com/rfjakob/gocryptfs/commit/9ecf2d1a3f69e3d995012073afe3fc664bd928f2)) -* Display a shorter, friendlier help text by default. -* **Parallelize file content encryption** by splitting data blocks into two - threads ([ticket#116](https://github.com/rfjakob/gocryptfs/issues/116)) -* Prefetch random nonces in the background - ([commit 80516ed](https://github.com/rfjakob/gocryptfs/commit/80516ed3351477793eec882508969b6b29b69b0a)) -* Add `-info` option to pretty-print infos about a filesystem. - -v1.3, 2017-04-29 -* **Use HKDF to derive separate keys for GCM and EME** - * New feature flag: `HKDF` (enabled by default) - * This is a forwards-compatible change. gocryptfs v1.3 can mount - filesystems created by earlier versions but not the other way round. -* **Enable Raw64 filename encoding by default (gets rid of trailing `==` characters)** - * This is a forwards-compatible change. gocryptfs v1.3 can mount - filesystems created by earlier versions but not the other way round. -* Drop Go 1.4 compatibility. You now need Go 1.5 (released 2015-08-19) - or higher to build gocryptfs. -* Add `-serialize_reads` command-line option - * This can greatly improve performance on storage - that is very slow for concurrent out-of-order reads. Example: - Amazon Cloud Drive ([#92](https://github.com/rfjakob/gocryptfs/issues/92)) -* Reject file-header-only files - ([#90 2.2](https://github.com/rfjakob/gocryptfs/issues/90), - [commit](https://github.com/rfjakob/gocryptfs/commit/14038a1644f17f50b113a05d09a2a0a3b3e973b2)) -* Increase max password size to 2048 bytes ([#93](https://github.com/rfjakob/gocryptfs/issues/93)) -* Use stable 64-bit inode numbers in reverse mode - * This may cause problems for very old 32-bit applications - that were compiled without Large File Support. -* Passing "--" now also blocks "-o" parsing - -v1.2.1, 2017-02-26 -* Add an integrated speed test, `gocryptfs -speed` -* Limit password size to 1000 bytes and reject trailing garbage after the newline -* Make the test suite work on [Mac OS X](https://github.com/rfjakob/gocryptfs/issues/15) -* Handle additional corner cases in `-ctlsock` path sanitization -* Use dedicated exit code 12 on "password incorrect" - -v1.2, 2016-12-04 -* Add a control socket interface. Allows to encrypt and decrypt filenames. - For details see [backintime#644](https://github.com/bit-team/backintime/issues/644#issuecomment-259835183). - * New command-line option: `-ctlsock` -* Under certain circumstances, concurrent truncate and read could return - an I/O error. This is fixed by introducing a global open file table - that stores the file IDs - ([commit](https://github.com/rfjakob/gocryptfs/commit/0489d08ae21107990d0efd0685443293aa26b35f)). -* Coalesce 4kB ciphertext block writes up to the size requested through - the write FUSE call - ([commit with benchmarks](https://github.com/rfjakob/gocryptfs/commit/024511d9c71558be4b1169d6bb43bd18d65539e0)) -* Add `-noprealloc` command-line option - * Greatly speeds up writes on Btrfs - ([#63](https://github.com/rfjakob/gocryptfs/issues/63)) - at the cost of reduced out-of-space robustness. - * This is a workaround for Btrfs' slow fallocate(2) -* Preserve owner for symlinks an device files (fixes bug [#64](https://github.com/rfjakob/gocryptfs/issues/64)) -* Include rendered man page `gocryptfs.1` in the release tarball - -v1.1.1, 2016-10-30 -* Fix a panic on setting file timestamps ([go-fuse#131](https://github.com/hanwen/go-fuse/pull/131)) -* Work around an issue in tmpfs that caused a panic in xfstests generic/075 - ([gocryptfs#56](https://github.com/rfjakob/gocryptfs/issues/56)) -* Optimize NFS streaming writes - ([commit](https://github.com/rfjakob/gocryptfs/commit/a08d55f42d5b11e265a8617bee16babceebfd026)) - -v1.1, 2016-10-19 -* **Add reverse mode ([#19](https://github.com/rfjakob/gocryptfs/issues/19))** - * AES-SIV (RFC5297) encryption to implement deterministic encryption - securely. Uses the excellent - [jacobsa/crypto](https://github.com/jacobsa/crypto) library. - The corresponding feature flag is called `AESSIV`. - * New command-line options: `-reverse`, `-aessiv` - * Filesystems using reverse mode can only be mounted with gocryptfs v1.1 - and later. - * The default, forward mode, stays fully compatible with older versions. - Forward mode will keep using GCM because it is much faster. -* Accept `-o foo,bar,baz`-style options that are passed at the end of - the command-line, like mount(1) does. All other options must still - precede the passed paths. - * This allows **mounting from /etc/fstab**. See - [#45](https://github.com/rfjakob/gocryptfs/issues/45) for details. - * **Mounting on login using pam_mount** works as well. It is - [described in the wiki](https://github.com/rfjakob/gocryptfs/wiki/Mounting-on-login-using-pam_mount). -* To prevent confusion, the old `-o` option had to be renamed. It is now - called `-ko`. Arguments to `-ko` are passed directly to the kernel. -* New `-passfile` command-line option. Provides an easier way to read - the password from a file. Internally, this is equivalent to - `-extpass "/bin/cat FILE"`. -* Enable changing the password when you only know the master key - ([#28](https://github.com/rfjakob/gocryptfs/issues/28)) - -v1.0, 2016-07-17 -* Deprecate very old filesystems, stage 3/3 - * Filesystems created by v0.6 can no longer be mounted - * Drop command-line options `-gcmiv128`, `-emenames`, `-diriv`. These - are now always enabled. -* Add fallocate(2) support -* New command-line option `-o` - * Allows to pass mount options directly to the kernel -* Add support for device files and suid binaries - * Only works when running as root - * Must be explicitly enabled by passing "-o dev" or "-o suid" or "-o suid,dev" -* Experimental Mac OS X support. See - [ticket #15](https://github.com/rfjakob/gocryptfs/issues/15) for details. - -v0.12, 2016-06-19 -* Deprecate very old filesystems, stage 2/3 - * Filesystems created by v0.6 and older can only be mounted read-only - * A [message](https://github.com/rfjakob/gocryptfs/blob/v0.12/internal/configfile/config_file.go#L120) - explaining the situation is printed as well -* New command line option: `-ro` - * Mounts the filesystem read-only -* Accept password from stdin as well ([ticket #30](https://github.com/rfjakob/gocryptfs/issues/30)) - -v0.11, 2016-06-10 -* Deprecate very old filesystems, stage 1/3 - * Filesystems created by v0.6 and older can still be mounted but a - [warning](https://github.com/rfjakob/gocryptfs/blob/v0.11/internal/configfile/config_file.go#L120) - is printed - * See [ticket #29](https://github.com/rfjakob/gocryptfs/issues/29) for details and - join the discussion -* Add rsync stress test "pingpong-rsync.bash" - * Fix chown and utimens failures that caused rsync to complain -* Build release binaries with Go 1.6.2 - * Big speedup for CPUs with AES-NI, see [ticket #23](https://github.com/rfjakob/gocryptfs/issues/23) - -v0.10, 2016-05-30 -* **Replace `spacemonkeygo/openssl` with `stupidgcm`** - * gocryptfs now has its own thin wrapper to OpenSSL's GCM implementation - called `stupidgcm`. - * This should fix the [compile issues](https://github.com/rfjakob/gocryptfs/issues/21) - people are seeing with `spacemonkeygo/openssl`. It also gets us - a 20% performance boost for streaming writes. -* **Automatically choose between OpenSSL and Go crypto** [issue #23](https://github.com/rfjakob/gocryptfs/issues/23) - * Go 1.6 added an optimized GCM implementation in amd64 assembly that uses AES-NI. - This is faster than OpenSSL and is used if available. In all other - cases OpenSSL is much faster and is used instead. - * `-openssl=auto` is the new default - * Passing `-openssl=true/false` overrides the autodetection. -* Warn but continue anyway if fallocate(2) is not supported by the - underlying filesystem, see [issue #22](https://github.com/rfjakob/gocryptfs/issues/22) - * Enables to use gocryptfs on ZFS and ext3, albeit with reduced out-of-space safety. -* [Fix statfs](https://github.com/rfjakob/gocryptfs/pull/27), by @lxp -* Fix a fsstress [failure](https://github.com/hanwen/go-fuse/issues/106) - in the go-fuse library. - -v0.9, 2016-04-10 -* **Long file name support** - * gocryptfs now supports file names up to 255 characters. - * This is a forwards-compatible change. gocryptfs v0.9 can mount filesystems - created by earlier versions but not the other way round. -* Refactor gocryptfs into multiple "internal" packages -* New command-line options: - * `-longnames`: Enable long file name support (default true) - * `-nosyslog`: Print messages to stdout and stderr instead of syslog (default false) - * `-wpanic`: Make warning messages fatal (used for testing) - * `-d`: Alias for `-debug` - * `-q`: Alias for `-quiet` - -v0.8, 2016-01-23 -* Redirect output to syslog when running in the background -* New command-line option: - * `-memprofile`: Write a memory allocation debugging profile the specified - file - -v0.7.2, 2016-01-19 -* **Fix performance issue in small file creation** - * This brings performance on-par with EncFS paranoia mode, with streaming writes - significantly faster - * The actual [fix](https://github.com/hanwen/go-fuse/commit/c4b6b7949716d13eec856baffc7b7941ae21778c) - is in the go-fuse library. There are no code changes in gocryptfs. - -v0.7.1, 2016-01-09 -* Make the `build.bash` script compatible with Go 1.3 -* Disable fallocate on OSX (system call not available) -* Introduce pre-built binaries for Fedora 23 and Debian 8 - -v0.7, 2015-12-20 -* **Extend GCM IV size to 128 bit from Go's default of 96 bit** - * This pushes back the birthday bound to make IV collisions virtually - impossible - * This is a forwards-compatible change. gocryptfs v0.7 can mount filesystems - created by earlier versions but not the other way round. -* New command-line option: - * `-gcmiv128`: Use 128-bit GCM IVs (default true) - -v0.6, 2015-12-08 -* **Wide-block filename encryption using EME + DirIV** - * EME (ECB-Mix-ECB) provides even better security than CBC as it fixes - the prefix leak. The used Go EME implementation is - https://github.com/rfjakob/eme which is, as far as I know, the first - implementation of EME in Go. - * This is a forwards-compatible change. gocryptfs v0.6 can mount filesystems - created by earlier versions but not the other way round. -* New command-line option: - * `-emenames`: Enable EME filename encryption (default true) - -v0.5.1, 2015-12-06 -* Fix a rename regression caused by DirIV and add test case -* Use fallocate to guard against out-of-space errors - -v0.5, 2015-12-04 -* **Stronger filename encryption: DirIV** - * Each directory gets a random 128 bit file name IV on creation, - stored in `gocryptfs.diriv` - * This makes it impossible to identify identically-named files across - directories - * A single-entry IV cache brings the performance cost of DirIV close to - zero for common operations (see performance.txt) - * This is a forwards-compatible change. gocryptfs v0.5 can mount filesystems - created by earlier versions but not the other way round. -* New command-line option: - * `-diriv`: Use the new per-directory IV file name encryption (default true) - * `-scryptn`: allows to set the scrypt cost parameter N. This option - can be used for faster mounting at the cost of lower brute-force - resistance. It was mainly added to speed up the automated tests. - -v0.4, 2015-11-15 -* New command-line options: - * `-plaintextnames`: disables filename encryption, added on user request - * `-extpass`: calls an external program for prompting for the password - * `-config`: allows to specify a custom gocryptfs.conf path -* Add `FeatureFlags` gocryptfs.conf parameter - * This is a config format change, hence the on-disk format is incremented - * Used for ext4-style filesystem feature flags. This should help avoid future - format changes. The first user is `-plaintextnames`. -* On-disk format 2 - -v0.3, 2015-11-01 -* **Add a random 128 bit file header to authenticate file->block ownership** - * This is an on-disk-format change -* On-disk format 1 - -v0.2, 2015-10-11 -* Replace bash daemonization wrapper with native Go implementation -* Better user feedback on mount failures - -v0.1, 2015-10-07 -* First release -* On-disk format 0 +## Warning ! +The only goal of this library is to be integrated in [DroidFS](https://forge.chapril.org/hardcoresushi/DroidFS). It's not actually ready for other usages. libgocryptfs doesn't implement all features provided by gocryptfs like symbolic links creation, thread-safety, reverse volume creation... Use it at your own risk ! \ No newline at end of file diff --git a/allocator/allocator32.go b/allocator/allocator32.go new file mode 100644 index 0000000..7fb5605 --- /dev/null +++ b/allocator/allocator32.go @@ -0,0 +1,13 @@ +// +build !arm64 +// +build !amd64 + +package allocator + +import ( + "C" + "unsafe" +) + +func Malloc(size int) unsafe.Pointer { + return C.malloc(C.uint(C.sizeof_int * size)) +} diff --git a/allocator/allocator64.go b/allocator/allocator64.go new file mode 100644 index 0000000..11a51d7 --- /dev/null +++ b/allocator/allocator64.go @@ -0,0 +1,12 @@ +// +build arm64 amd64 + +package allocator + +import ( + "C" + "unsafe" +) + +func Malloc(size int) unsafe.Pointer { + return C.malloc(C.ulong(C.sizeof_int * size)) +} diff --git a/benchmark-reverse.bash b/benchmark-reverse.bash deleted file mode 100755 index be98fc1..0000000 --- a/benchmark-reverse.bash +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -eu - -# Benchmark gocryptfs' reverse mode - -cd "$(dirname "$0")" -MYNAME=$(basename "$0") -source tests/fuse-unmount.bash - -# Download /tmp/linux-3.0.tar.gz -./tests/dl-linux-tarball.bash - -cd /tmp -PLAIN=linux-3.0 - -SIZE=0 -if [[ -d $PLAIN ]]; then - SIZE=$(du -s --apparent-size $PLAIN | cut -f1) -fi - - -if [[ $SIZE -ne 412334 ]] ; then - echo "Extracting linux-3.0.tar.gz" - rm -Rf $PLAIN - tar xf linux-3.0.tar.gz -fi - -rm -f $PLAIN/.gocryptfs.reverse.conf -gocryptfs -q -init -reverse -extpass="echo test" -scryptn=10 $PLAIN - -MNT=$(mktemp -d /tmp/linux-3.0.reverse.mnt.XXX) - -# Cleanup trap -trap 'rm -f "$PLAIN/.gocryptfs.reverse.conf" ; fuse-unmount -z "$MNT" ; rmdir "$MNT"' EXIT - -# Mount -gocryptfs -q -reverse -extpass="echo test" "$PLAIN" "$MNT" - -# Execute command, discard all stdout output, print elapsed time -# (to stderr, unfortunately). -function etime { - # Make the bash builtin "time" print out only the elapse wall clock - # seconds - TIMEFORMAT=%R - time "$@" > /dev/null -} - -echo -n "LS: " -etime ls -lR "$MNT" -echo -n "CAT: " -etime find "$MNT" -type f -exec cat {} + diff --git a/benchmark.bash b/benchmark.bash deleted file mode 100755 index 578979d..0000000 --- a/benchmark.bash +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -eu - -# Run the set of "canonical" benchmarks that are shown on -# https://nuetzlich.net/gocryptfs/comparison/ - -cd "$(dirname "$0")" -MYNAME=$(basename "$0") -source tests/fuse-unmount.bash - -function usage { - echo "Usage: $MYNAME [-encfs] [-openssl=true] [-openssl=false] [-dd] [DIR]" -} - -OPT_ENCFS=0 -OPT_LOOPBACK=0 -OPT_OPENSSL="" -OPT_DIR="" -DD_ONLY="" - -while [[ $# -gt 0 ]] ; do - case $1 in - -h) - usage - exit 1 - ;; - -encfs) - OPT_ENCFS=1 - ;; - -openssl=true) - OPT_OPENSSL="-openssl=true" - ;; - -openssl=false) - OPT_OPENSSL="-openssl=false" - ;; - -dd) - DD_ONLY=1 - ;; - -loopback) - OPT_LOOPBACK=1 - ;; - -*) - echo "Invalid option: $1" - usage - exit 2 - ;; - *) - if [[ -n $OPT_DIR ]] ; then - echo "Duplicate DIR argument: $1" - usage - exit 3 - fi - OPT_DIR=$1 - ;; - esac - shift -done - -if [[ -z $OPT_DIR ]] ; then - OPT_DIR=/tmp -fi - -# Create directories -CRYPT=$(mktemp -d "$OPT_DIR/$MYNAME.XXX") -MNT=$CRYPT.mnt -mkdir "$MNT" - -# Mount -if [[ $OPT_ENCFS -eq 1 ]]; then - if [[ -n $OPT_OPENSSL ]] ; then - echo "The option $OPT_OPENSSL only works with gocryptfs" - exit 1 - fi - echo -n "Testing EncFS at $CRYPT: " - encfs --version - encfs --extpass="echo test" --standard "$CRYPT" "$MNT" > /dev/null -elif [[ $OPT_LOOPBACK -eq 1 ]]; then - echo "Testing go-fuse loopback" - "$HOME/go/src/github.com/hanwen/go-fuse/example/loopback/loopback" "$MNT" "$CRYPT" & - sleep 0.5 -else - echo -n "Testing gocryptfs at $CRYPT: " - gocryptfs -version - gocryptfs -q -init -extpass="echo test" -scryptn=10 "$CRYPT" - gocryptfs -q -extpass="echo test" $OPT_OPENSSL "$CRYPT" "$MNT" -fi - -# Make sure we have actually mounted something -if ! mountpoint "$MNT" ; then - exit 1 -fi - -# Cleanup trap -trap 'cd /; fuse-unmount -z "$MNT"; rm -rf "$CRYPT" "$MNT"' EXIT - -# Benchmarks -if [[ $DD_ONLY -eq 1 ]]; then - echo -n "WRITE: " - dd if=/dev/zero "of=$MNT/zero" bs=131072 count=20000 2>&1 | tail -n 1 - rm "$MNT/zero" -else - ./tests/canonical-benchmarks.bash "$MNT" -fi - diff --git a/build-without-openssl.bash b/build-without-openssl.bash deleted file mode 100755 index d5dc218..0000000 --- a/build-without-openssl.bash +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -CGO_ENABLED=0 source ./build.bash -tags without_openssl - -if ldd gocryptfs 2> /dev/null ; then - echo "build-without-openssl.bash: error: compiled binary is not static" - exit 1 -fi diff --git a/build.bash b/build.bash deleted file mode 100755 index 627a31d..0000000 --- a/build.bash +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash -eu -# -# Compile gocryptfs and bake the git version string of itself and the go-fuse -# library into the binary. -# -# If you want to fake a build date to reproduce a specific build, -# you can use: -# BUILDDATE=2017-02-03 ./build.bash -# or -# SOURCE_DATE_EPOCH=1544192417 ./build.bash -# . - -cd "$(dirname "$0")" - -# Make sure we have the go binary -go version > /dev/null - -# Enable Go Modules on Go 1.11 and 1.12 -# https://dev.to/maelvls/why-is-go111module-everywhere-and-everything-about-go-modules-24k#-raw-go111module-endraw-with-go-111-and-112 -export GO111MODULE=on - -# GOPATH may contain multiple paths separated by ":" -GOPATH1=$(go env GOPATH | cut -f1 -d:) - -# gocryptfs version according to git or a VERSION file -if [[ -d .git ]] ; then - GITVERSION=$(git describe --tags --dirty || echo "[no_tags_found]") - GITBRANCH=$(git rev-parse --abbrev-ref HEAD) - if [[ -n $GITBRANCH && $GITBRANCH != master ]] ; then - GITVERSION="$GITVERSION.$GITBRANCH" - fi -elif [[ -f VERSION ]] ; then - GITVERSION=$(cat VERSION) -else - echo "Warning: could not determine gocryptfs version" - GITVERSION="[unknown]" -fi - -# go-fuse version, if available -if [[ -d vendor/github.com/hanwen/go-fuse ]] ; then - GITVERSIONFUSE="[vendored]" -else - # go-fuse version according to Go Modules - FAIL=0 - OUT=$(go list -m github.com/hanwen/go-fuse/v2 | cut -d' ' -f2-) || FAIL=1 - if [[ $FAIL -eq 0 ]]; then - GITVERSIONFUSE=$OUT - else - echo "Warning: could not determine go-fuse version" - GITVERSIONFUSE="[unknown]" - fi -fi - -# Build date, something like "2017-09-06". Don't override BUILDDATE -# if it is already set. This may be done for reproducible builds. -if [[ -z ${BUILDDATE:-} ]] ; then - BUILDDATE=$(date +%Y-%m-%d) -fi - -# If SOURCE_DATE_EPOCH is set, it overrides BUILDDATE. This is the -# standard environment variable for faking the date in reproducible builds. -if [[ -n ${SOURCE_DATE_EPOCH:-} ]] ; then - BUILDDATE=$(date --utc --date="@${SOURCE_DATE_EPOCH}" +%Y-%m-%d) -fi - -# Only set GOFLAGS if it is not already set by the user -if [[ -z ${GOFLAGS:-} ]] ; then - GOFLAGS="" - # For reproducible builds, we get rid of $HOME references in the - # binary using "-trimpath". - # However, -trimpath needs Go 1.13+, and we support Go 1.11 and Go 1.12 - # too. So don't add it there. - GV=$(go version) - if [[ $GV != *"1.11"* && $GV != *"1.12"* ]] ; then - GOFLAGS="-trimpath" - fi - # Also, Fedora and Arch want pie enabled, so enable it. - # * https://fedoraproject.org/wiki/Changes/golang-buildmode-pie - # * https://github.com/rfjakob/gocryptfs/pull/460 - # But not with CGO_ENABLED=0 (https://github.com/golang/go/issues/30986)! - if [[ ${CGO_ENABLED:-1} -ne 0 ]] ; then - GOFLAGS="$GOFLAGS -buildmode=pie" - fi - export GOFLAGS -fi - -GO_LDFLAGS="-X \"main.GitVersion=$GITVERSION\" -X \"main.GitVersionFuse=$GITVERSIONFUSE\" -X \"main.BuildDate=$BUILDDATE\"" - -# If LDFLAGS is set, add it as "-extldflags". -if [[ -n ${LDFLAGS:-} ]] ; then - GO_LDFLAGS="$GO_LDFLAGS \"-extldflags=$LDFLAGS\"" -fi - -# Actual "go build" call for gocryptfs -go build "-ldflags=$GO_LDFLAGS" "$@" -# Additional binaries -for d in gocryptfs-xray contrib/statfs contrib/findholes contrib/atomicrename ; do - (cd "$d"; go build "-ldflags=$GO_LDFLAGS" "$@") -done - -./gocryptfs -version - -mkdir -p "$GOPATH1/bin" -cp -af gocryptfs "$GOPATH1/bin" diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..909f164 --- /dev/null +++ b/build.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +if [ -z ${ANDROID_NDK_HOME+x} ]; then + echo "Error: \$ANDROID_NDK_HOME is not defined." +elif [ -z ${OPENSSL_PATH+x} ]; then + echo "Error: \$OPENSSL_PATH is not defined." +else + NDK_BIN_PATH="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" + declare -a ABIs=("x86_64" "x86" "arm64-v8a" "armeabi-v7a") + + compile_openssl(){ + if [ ! -d "./lib/$1" ]; then + if [ "$1" = "x86_64" ]; then + OPENSSL_ARCH="android-x86_64" + elif [ "$1" = "x86" ]; then + OPENSSL_ARCH="android-x86" + elif [ "$1" = "arm64-v8a" ]; then + OPENSSL_ARCH="android-arm64" + elif [ "$1" = "armeabi-v7a" ]; then + OPENSSL_ARCH="android-arm" + else + echo "Invalid ABI: $1" + exit + fi + + export CFLAGS=-D__ANDROID_API__=21 + export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH + (cd "$OPENSSL_PATH" && if [ -f "Makefile" ]; then make clean; fi && ./Configure $OPENSSL_ARCH -D__ANDROID_API__=21 && make -j4 build_libs) + mkdir -p "./lib/$1" && cp "$OPENSSL_PATH/libcrypto.a" "$OPENSSL_PATH/libssl.a" "./lib/$1" + mkdir -p "./include/$1" && cp -r "$OPENSSL_PATH"/include/* "./include/$1/" + fi + } + + compile_for_arch() { + compile_openssl $1 + if [ "$1" = "x86_64" ]; then + CFN="x86_64-linux-android21-clang" + elif [ "$1" = "x86" ]; then + export GOARCH=386 + CFN="i686-linux-android21-clang" + elif [ "$1" = "arm64-v8a" ]; then + CFN="aarch64-linux-android21-clang" + export GOARCH=arm64 + export GOARM=7 + elif [ "$1" = "armeabi-v7a" ]; then + CFN="armv7a-linux-androideabi21-clang" + export GOARCH=arm + export GOARM=7 + else + echo "Invalid ABI: $1" + exit + fi + + export CC="$NDK_BIN_PATH/$CFN" + export CXX="$NDK_BIN_PATH/$CFN++" + export CGO_ENABLED=1 + export GOOS=android + export CGO_CFLAGS="-I ${PWD}/include/$1" + export CGO_LDFLAGS="-Wl,-soname=libgocryptfs.so -L${PWD}/lib/$1" + go build -o build/$1/libgocryptfs.so -buildmode=c-shared + } + + if [ "$#" -eq 1 ]; then + compile_for_arch $1 + else + for abi in ${ABIs[@]}; do + echo "Compiling for $abi..." + compile_for_arch $abi + done + fi + echo "Done." +fi \ No newline at end of file diff --git a/cli_args.go b/cli_args.go deleted file mode 100644 index 7743120..0000000 --- a/cli_args.go +++ /dev/null @@ -1,332 +0,0 @@ -package main - -// Should be initialized before anything else. -// This import line MUST be in the alphabitcally first source code file of -// package main! -import _ "github.com/rfjakob/gocryptfs/internal/ensurefds012" - -import ( - "flag" - "fmt" - "net" - "os" - "strconv" - "strings" - "time" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// argContainer stores the parsed CLI options and arguments -type argContainer struct { - debug, init, zerokey, fusedebug, openssl, passwd, fg, version, - plaintextnames, quiet, nosyslog, wpanic, - longnames, allow_other, reverse, aessiv, nonempty, raw64, - noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info, - sharedstorage, devrandom, fsck bool - // Mount options with opposites - dev, nodev, suid, nosuid, exec, noexec, rw, ro, kernel_cache, acl bool - masterkey, mountpoint, cipherdir, cpuprofile, - memprofile, ko, ctlsock, fsname, force_owner, trace, fido2 string - // -extpass, -badname, -passfile can be passed multiple times - extpass, badname, passfile multipleStrings - // For reverse mode, several ways to specify exclusions. All can be specified multiple times. - exclude, excludeWildcard, excludeFrom multipleStrings - // Configuration file name override - config string - notifypid, scryptn int - // Idle time before autounmount - idle time.Duration - // Helper variables that are NOT cli options all start with an underscore - // _configCustom is true when the user sets a custom config file name. - _configCustom bool - // _ctlsockFd stores the control socket file descriptor (ctlsock stores the path) - _ctlsockFd net.Listener - // _forceOwner is, if non-nil, a parsed, validated Owner (as opposed to the string above) - _forceOwner *fuse.Owner - // _explicitScryptn is true then the user passed "-scryptn=xyz" - _explicitScryptn bool -} - -type multipleStrings []string - -func (s *multipleStrings) String() string { - s2 := []string(*s) - return fmt.Sprint(s2) -} - -func (s *multipleStrings) Set(val string) error { - *s = append(*s, val) - return nil -} - -func (s *multipleStrings) Empty() bool { - s2 := []string(*s) - return len(s2) == 0 -} - -var flagSet *flag.FlagSet - -// prefixOArgs transform options passed via "-o foo,bar" into regular options -// like "-foo -bar" and prefixes them to the command line. -// Testcases in TestPrefixOArgs(). -func prefixOArgs(osArgs []string) ([]string, error) { - // Need at least 3, example: gocryptfs -o foo,bar - // ^ 0 ^ 1 ^ 2 - if len(osArgs) < 3 { - return osArgs, nil - } - // Passing "--" disables "-o" parsing. Ignore element 0 (program name). - for _, v := range osArgs[1:] { - if v == "--" { - return osArgs, nil - } - } - // Find and extract "-o foo,bar" - var otherArgs, oOpts []string - for i := 1; i < len(osArgs); i++ { - if osArgs[i] == "-o" { - // Last argument? - if i+1 >= len(osArgs) { - return nil, fmt.Errorf("The \"-o\" option requires an argument") - } - oOpts = strings.Split(osArgs[i+1], ",") - // Skip over the arguments to "-o" - i++ - } else if strings.HasPrefix(osArgs[i], "-o=") { - oOpts = strings.Split(osArgs[i][3:], ",") - } else { - otherArgs = append(otherArgs, osArgs[i]) - } - } - // Start with program name - newArgs := []string{osArgs[0]} - // Add options from "-o" - for _, o := range oOpts { - if o == "" { - continue - } - if o == "o" || o == "-o" { - tlog.Fatal.Printf("You can't pass \"-o\" to \"-o\"") - os.Exit(exitcodes.Usage) - } - newArgs = append(newArgs, "-"+o) - } - // Add other arguments - newArgs = append(newArgs, otherArgs...) - return newArgs, nil -} - -// parseCliOpts - parse command line options (i.e. arguments that start with "-") -func parseCliOpts() (args argContainer) { - var err error - var opensslAuto string - - os.Args, err = prefixOArgs(os.Args) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Usage) - } - - flagSet = flag.NewFlagSet(tlog.ProgramName, flag.ContinueOnError) - flagSet.Usage = func() {} - flagSet.BoolVar(&args.debug, "d", false, "") - flagSet.BoolVar(&args.debug, "debug", false, "Enable debug output") - flagSet.BoolVar(&args.fusedebug, "fusedebug", false, "Enable fuse library debug output") - flagSet.BoolVar(&args.init, "init", false, "Initialize encrypted directory") - flagSet.BoolVar(&args.zerokey, "zerokey", false, "Use all-zero dummy master key") - // Tri-state true/false/auto - flagSet.StringVar(&opensslAuto, "openssl", "auto", "Use OpenSSL instead of built-in Go crypto") - flagSet.BoolVar(&args.passwd, "passwd", false, "Change password") - flagSet.BoolVar(&args.fg, "f", false, "") - flagSet.BoolVar(&args.fg, "fg", false, "Stay in the foreground") - flagSet.BoolVar(&args.version, "version", false, "Print version and exit") - flagSet.BoolVar(&args.plaintextnames, "plaintextnames", false, "Do not encrypt file names") - flagSet.BoolVar(&args.quiet, "q", false, "") - flagSet.BoolVar(&args.quiet, "quiet", false, "Quiet - silence informational messages") - flagSet.BoolVar(&args.nosyslog, "nosyslog", false, "Do not redirect output to syslog when running in the background") - flagSet.BoolVar(&args.wpanic, "wpanic", false, "When encountering a warning, panic and exit immediately") - flagSet.BoolVar(&args.longnames, "longnames", true, "Store names longer than 176 bytes in extra files") - flagSet.BoolVar(&args.allow_other, "allow_other", false, "Allow other users to access the filesystem. "+ - "Only works if user_allow_other is set in /etc/fuse.conf.") - flagSet.BoolVar(&args.reverse, "reverse", false, "Reverse mode") - flagSet.BoolVar(&args.aessiv, "aessiv", false, "AES-SIV encryption") - flagSet.BoolVar(&args.nonempty, "nonempty", false, "Allow mounting over non-empty directories") - flagSet.BoolVar(&args.raw64, "raw64", true, "Use unpadded base64 for file names") - flagSet.BoolVar(&args.noprealloc, "noprealloc", false, "Disable preallocation before writing") - flagSet.BoolVar(&args.speed, "speed", false, "Run crypto speed test") - flagSet.BoolVar(&args.hkdf, "hkdf", true, "Use HKDF as an additional key derivation step") - flagSet.BoolVar(&args.serialize_reads, "serialize_reads", false, "Try to serialize read operations") - flagSet.BoolVar(&args.forcedecode, "forcedecode", false, "Force decode of files even if integrity check fails."+ - " Requires gocryptfs to be compiled with openssl support and implies -openssl true") - flagSet.BoolVar(&args.hh, "hh", false, "Show this long help text") - flagSet.BoolVar(&args.info, "info", false, "Display information about CIPHERDIR") - flagSet.BoolVar(&args.sharedstorage, "sharedstorage", false, "Make concurrent access to a shared CIPHERDIR safer") - flagSet.BoolVar(&args.devrandom, "devrandom", false, "Use /dev/random for generating master key") - flagSet.BoolVar(&args.fsck, "fsck", false, "Run a filesystem check on CIPHERDIR") - - // Mount options with opposites - flagSet.BoolVar(&args.dev, "dev", false, "Allow device files") - flagSet.BoolVar(&args.nodev, "nodev", false, "Deny device files") - flagSet.BoolVar(&args.suid, "suid", false, "Allow suid binaries") - flagSet.BoolVar(&args.nosuid, "nosuid", false, "Deny suid binaries") - flagSet.BoolVar(&args.exec, "exec", false, "Allow executables") - flagSet.BoolVar(&args.noexec, "noexec", false, "Deny executables") - flagSet.BoolVar(&args.rw, "rw", false, "Mount the filesystem read-write") - flagSet.BoolVar(&args.ro, "ro", false, "Mount the filesystem read-only") - flagSet.BoolVar(&args.kernel_cache, "kernel_cache", false, "Enable the FUSE kernel_cache option") - flagSet.BoolVar(&args.acl, "acl", false, "Enforce ACLs") - - flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key") - flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file") - flagSet.StringVar(&args.memprofile, "memprofile", "", "Write memory profile to specified file") - flagSet.StringVar(&args.config, "config", "", "Use specified config file instead of CIPHERDIR/gocryptfs.conf") - flagSet.StringVar(&args.ko, "ko", "", "Pass additional options directly to the kernel, comma-separated list") - flagSet.StringVar(&args.ctlsock, "ctlsock", "", "Create control socket at specified path") - flagSet.StringVar(&args.fsname, "fsname", "", "Override the filesystem name") - flagSet.StringVar(&args.force_owner, "force_owner", "", "uid:gid pair to coerce ownership") - flagSet.StringVar(&args.trace, "trace", "", "Write execution trace to file") - flagSet.StringVar(&args.fido2, "fido2", "", "Protect the masterkey using a FIDO2 token instead of a password") - - // Exclusion options - flagSet.Var(&args.exclude, "e", "Alias for -exclude") - flagSet.Var(&args.exclude, "exclude", "Exclude relative path from reverse view") - flagSet.Var(&args.excludeWildcard, "ew", "Alias for -exclude-wildcard") - flagSet.Var(&args.excludeWildcard, "exclude-wildcard", "Exclude path from reverse view, supporting wildcards") - flagSet.Var(&args.excludeFrom, "exclude-from", "File from which to read exclusion patterns (with -exclude-wildcard syntax)") - - // multipleStrings options ([]string) - flagSet.Var(&args.extpass, "extpass", "Use external program for the password prompt") - flagSet.Var(&args.badname, "badname", "Glob pattern invalid file names that should be shown") - flagSet.Var(&args.passfile, "passfile", "Read password from file") - - flagSet.IntVar(&args.notifypid, "notifypid", 0, "Send USR1 to the specified process after "+ - "successful mount - used internally for daemonization") - const scryptn = "scryptn" - flagSet.IntVar(&args.scryptn, scryptn, configfile.ScryptDefaultLogN, "scrypt cost parameter logN. Possible values: 10-28. "+ - "A lower value speeds up mounting and reduces its memory needs, but makes the password susceptible to brute-force attacks") - - flagSet.DurationVar(&args.idle, "i", 0, "Alias for -idle") - flagSet.DurationVar(&args.idle, "idle", 0, "Auto-unmount after specified idle duration (ignored in reverse mode). "+ - "Durations are specified like \"500s\" or \"2h45m\". 0 means stay mounted indefinitely.") - - var nofail bool - flagSet.BoolVar(&nofail, "nofail", false, "Ignored for /etc/fstab compatibility") - - var dummyString string - flagSet.StringVar(&dummyString, "o", "", "For compatibility with mount(1), options can be also passed as a comma-separated list to -o on the end.") - // Actual parsing - err = flagSet.Parse(os.Args[1:]) - if err == flag.ErrHelp { - helpShort() - os.Exit(0) - } - if err != nil { - tlog.Fatal.Printf("Invalid command line: %s. Try '%s -help'.", prettyArgs(), tlog.ProgramName) - os.Exit(exitcodes.Usage) - } - // We want to know if -scryptn was passed explicitly - if isFlagPassed(flagSet, scryptn) { - args._explicitScryptn = true - } - // "-openssl" needs some post-processing - if opensslAuto == "auto" { - args.openssl = stupidgcm.PreferOpenSSL() - } else { - args.openssl, err = strconv.ParseBool(opensslAuto) - if err != nil { - tlog.Fatal.Printf("Invalid \"-openssl\" setting: %v", err) - os.Exit(exitcodes.Usage) - } - } - // "-forcedecode" only works with openssl. Check compilation and command line parameters - if args.forcedecode == true { - if stupidgcm.BuiltWithoutOpenssl == true { - tlog.Fatal.Printf("The -forcedecode flag requires openssl support, but gocryptfs was compiled without it!") - os.Exit(exitcodes.Usage) - } - if args.aessiv == true { - tlog.Fatal.Printf("The -forcedecode and -aessiv flags are incompatible because they use different crypto libs (openssl vs native Go)") - os.Exit(exitcodes.Usage) - } - if args.reverse == true { - tlog.Fatal.Printf("The reverse mode and the -forcedecode option are not compatible") - os.Exit(exitcodes.Usage) - } - // Has the user explicitly disabled openssl using "-openssl=false/0"? - if !args.openssl && opensslAuto != "auto" { - tlog.Fatal.Printf("-forcedecode requires openssl, but is disabled via command-line option") - os.Exit(exitcodes.Usage) - } - args.openssl = true - - // Try to make it harder for the user to shoot himself in the foot. - args.ro = true - args.allow_other = false - args.ko = "noexec" - } - if !args.extpass.Empty() && len(args.passfile) != 0 { - tlog.Fatal.Printf("The options -extpass and -passfile cannot be used at the same time") - os.Exit(exitcodes.Usage) - } - if len(args.passfile) != 0 && args.masterkey != "" { - tlog.Fatal.Printf("The options -passfile and -masterkey cannot be used at the same time") - os.Exit(exitcodes.Usage) - } - if !args.extpass.Empty() && args.masterkey != "" { - tlog.Fatal.Printf("The options -extpass and -masterkey cannot be used at the same time") - os.Exit(exitcodes.Usage) - } - if !args.extpass.Empty() && args.fido2 != "" { - tlog.Fatal.Printf("The options -extpass and -fido2 cannot be used at the same time") - os.Exit(exitcodes.Usage) - } - if args.idle < 0 { - tlog.Fatal.Printf("Idle timeout cannot be less than 0") - os.Exit(exitcodes.Usage) - } - return args -} - -// prettyArgs pretty-prints the command-line arguments. -func prettyArgs() string { - pa := fmt.Sprintf("%v", os.Args) - // Get rid of "[" and "]" - pa = pa[1 : len(pa)-1] - return pa -} - -// countOpFlags counts the number of operation flags we were passed. -func countOpFlags(args *argContainer) int { - var count int - if args.info { - count++ - } - if args.passwd { - count++ - } - if args.init { - count++ - } - if args.fsck { - count++ - } - return count -} - -// isFlagPassed finds out if the flag was explictely passed on the command line. -// https://stackoverflow.com/a/54747682/1380267 -func isFlagPassed(flagSet *flag.FlagSet, name string) bool { - found := false - flagSet.Visit(func(f *flag.Flag) { - if f.Name == name { - found = true - } - }) - return found -} diff --git a/cli_args_test.go b/cli_args_test.go deleted file mode 100644 index 8e5ae3d..0000000 --- a/cli_args_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "reflect" - "testing" -) - -type testcase struct { - // i is the input - i []string - // o is the expected output - o []string - // Do we expect an error? - e bool -} - -// TestPrefixOArgs checks that the "-o x,y,z" parsing works correctly. -func TestPrefixOArgs(t *testing.T) { - testcases := []testcase{ - { - i: nil, - o: nil, - }, - { - i: []string{"gocryptfs"}, - o: []string{"gocryptfs"}, - }, - { - i: []string{"gocryptfs", "-v"}, - o: []string{"gocryptfs", "-v"}, - }, - { - i: []string{"gocryptfs", "foo", "bar", "-v"}, - o: []string{"gocryptfs", "foo", "bar", "-v"}, - }, - { - i: []string{"gocryptfs", "foo", "bar", "-o", "a"}, - o: []string{"gocryptfs", "-a", "foo", "bar"}, - }, - { - i: []string{"gocryptfs", "foo", "bar", "-o", "a,b,xxxxx"}, - o: []string{"gocryptfs", "-a", "-b", "-xxxxx", "foo", "bar"}, - }, - { - i: []string{"gocryptfs", "foo", "bar", "-d", "-o=a,b,xxxxx"}, - o: []string{"gocryptfs", "-a", "-b", "-xxxxx", "foo", "bar", "-d"}, - }, - { - i: []string{"gocryptfs", "foo", "bar", "-oooo", "a,b,xxxxx"}, - o: []string{"gocryptfs", "foo", "bar", "-oooo", "a,b,xxxxx"}, - }, - // https://github.com/mhogomchungu/sirikali/blob/a36d91d3e39f0c1eb9a79680ed6c28ddb6568fa8/src/siritask.cpp#L192 - { - i: []string{"gocryptfs", "-o", "rw", "--config", "fff", "ccc", "mmm"}, - o: []string{"gocryptfs", "-rw", "--config", "fff", "ccc", "mmm"}, - }, - // "--" should also block "-o" parsing. - { - i: []string{"gocryptfs", "foo", "bar", "--", "-o", "a"}, - o: []string{"gocryptfs", "foo", "bar", "--", "-o", "a"}, - }, - { - i: []string{"gocryptfs", "--", "-o", "a"}, - o: []string{"gocryptfs", "--", "-o", "a"}, - }, - // This should error out - { - i: []string{"gocryptfs", "foo", "bar", "-o"}, - e: true, - }, - } - for _, tc := range testcases { - o, err := prefixOArgs(tc.i) - e := (err != nil) - if !reflect.DeepEqual(o, tc.o) || e != tc.e { - t.Errorf("\n in=%q\nwant=%q err=%v\n got=%q err=%v", tc.i, tc.o, tc.e, o, e) - } - } -} - -func TestStringSlice(t *testing.T) { - var s multipleStrings - s.Set("foo") - s.Set("bar") - want := "[foo bar]" - have := s.String() - if want != have { - t.Errorf("Wrong string representation: want=%q have=%q", want, have) - } -} diff --git a/codelingo.yaml b/codelingo.yaml deleted file mode 100644 index 8e5d778..0000000 --- a/codelingo.yaml +++ /dev/null @@ -1,4 +0,0 @@ -tenets: -- import: codelingo/effective-go -- import: codelingo/code-review-comments -- import: codelingo/rfjakob-gocryptfs diff --git a/common_ops.go b/common_ops.go new file mode 100644 index 0000000..cb61e86 --- /dev/null +++ b/common_ops.go @@ -0,0 +1,88 @@ +package main + +import ( + "C" + "syscall" + + "golang.org/x/sys/unix" + + "./internal/nametransform" + "./internal/syscallcompat" +) + +//export gcf_get_attrs +func gcf_get_attrs(sessionID int, relPath string) (uint64, int64, bool) { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(relPath) + if err != nil { + return 0, 0, false + } + defer syscall.Close(dirfd) + + st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + return 0, 0, false + } + + // Translate ciphertext size to plaintext size + size := volume.translateSize(dirfd, cName, st) + + return size, int64(st.Mtim.Sec), true +} + +//export gcf_rename +func gcf_rename(sessionID int, oldPath string, newPath string) bool { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(oldPath) + if err != nil { + return false + } + defer syscall.Close(dirfd) + + dirfd2, cName2, err := volume.prepareAtSyscall(newPath) + if err != nil { + return false + } + defer syscall.Close(dirfd2) + + // Easy case. + if volume.plainTextNames { + return errToBool(syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, 0)) + } + // Long destination file name: create .name file + nameFileAlreadyThere := false + if nametransform.IsLongContent(cName2) { + err = volume.nameTransform.WriteLongNameAt(dirfd2, cName2, newPath) + // Failure to write the .name file is expected when the target path already + // exists. Since hashes are pretty unique, there is no need to modify the + // .name file in this case, and we ignore the error. + if err == syscall.EEXIST { + nameFileAlreadyThere = true + } else if err != nil { + return false + } + } + // Actual rename + err = syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, 0) + if err == syscall.ENOTEMPTY || err == syscall.EEXIST { + // If an empty directory is overwritten we will always get an error as + // the "empty" directory will still contain gocryptfs.diriv. + // Interestingly, ext4 returns ENOTEMPTY while xfs returns EEXIST. + // We handle that by trying to fs.Rmdir() the target directory and trying + // again. + if gcf_rmdir(sessionID, newPath) { + err = syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, 0) + } + } + if err != nil { + if nametransform.IsLongContent(cName2) && !nameFileAlreadyThere { + // Roll back .name creation unless the .name file was already there + nametransform.DeleteLongNameAt(dirfd2, cName2) + } + return false + } + if nametransform.IsLongContent(cName) { + nametransform.DeleteLongNameAt(dirfd, cName) + } + return true +} diff --git a/contrib/atomicrename/.gitignore b/contrib/atomicrename/.gitignore deleted file mode 100644 index b91a212..0000000 --- a/contrib/atomicrename/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/atomicrename diff --git a/contrib/atomicrename/main.go b/contrib/atomicrename/main.go deleted file mode 100644 index 67088b0..0000000 --- a/contrib/atomicrename/main.go +++ /dev/null @@ -1,101 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "io/ioutil" - "os" - "strings" - "sync/atomic" - "syscall" -) - -const fileCount = 100 - -type stats struct { - renameOk int - renameError int - readOk int - readError int - readContentMismatch int -} - -func usage() { - fmt.Printf(`atomicrename creates %d "src" files in the current directory, renames -them in random order over a single "dst" file while reading the "dst" -file concurrently in a loop. - -Progress and errors are reported as they occour in addition to a summary -printed at the end. cifs and fuse filesystems are known to fail, local -filesystems and nfs seem ok. - -See https://github.com/hanwen/go-fuse/issues/398 for background info. -`, fileCount) - os.Exit(1) -} - -func main() { - flag.Usage = usage - flag.Parse() - - hello := []byte("hello world") - srcFiles := make(map[string]struct{}) - - // prepare source files - fmt.Print("creating files") - for i := 0; i < fileCount; i++ { - srcName := fmt.Sprintf("src.atomicrename.%d", i) - srcFiles[srcName] = struct{}{} - buf := bytes.Repeat([]byte("_"), i) - buf = append(buf, hello...) - if err := ioutil.WriteFile(srcName, buf, 0600); err != nil { - panic(err) - } - fmt.Print(".") - } - fmt.Print("\n") - - // prepare destination file - const dstName = "dst.atomicrename" - if err := ioutil.WriteFile(dstName, hello, 0600); err != nil { - panic(err) - } - - var running int32 = 1 - - stats := stats{} - - // read thread - go func() { - for atomic.LoadInt32(&running) == 1 { - have, err := ioutil.ReadFile(dstName) - if err != nil { - fmt.Println(err) - stats.readError++ - continue - } - if !strings.HasSuffix(string(have), string(hello)) { - fmt.Printf("content mismatch: have %q\n", have) - stats.readContentMismatch++ - continue - } - fmt.Printf("content ok len=%d\n", len(have)) - stats.readOk++ - } - }() - - // rename thread = main thread - for srcName := range srcFiles { - if err := os.Rename(srcName, dstName); err != nil { - fmt.Println(err) - stats.renameError++ - } - stats.renameOk++ - } - // Signal the Read goroutine to stop when loop is done - atomic.StoreInt32(&running, 0) - - syscall.Unlink(dstName) - fmt.Printf("stats: %#v\n", stats) -} diff --git a/contrib/cleanup-tmp-mounts.sh b/contrib/cleanup-tmp-mounts.sh deleted file mode 100755 index 481d2b7..0000000 --- a/contrib/cleanup-tmp-mounts.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# -# Umount all FUSE filesystems mounted below /tmp and /var/tmp. -# -# Useful when you have lots of broken mounts after something in -# the test suite went wrong. - -set -eu - -MOUNTS=$(mount | grep ' type fuse\.' | grep 'on /var/tmp/\|on /tmp/\|on /mnt/ext4-ramdisk/' | cut -d' ' -f 3) - -for i in $MOUNTS ; do - echo "Unmounting $i" - fusermount -u -z "$i" -done diff --git a/contrib/findholes/.gitignore b/contrib/findholes/.gitignore deleted file mode 100644 index 15c37f6..0000000 --- a/contrib/findholes/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/findholes diff --git a/contrib/findholes/holes/holes.go b/contrib/findholes/holes/holes.go deleted file mode 100644 index 7d77ae1..0000000 --- a/contrib/findholes/holes/holes.go +++ /dev/null @@ -1,199 +0,0 @@ -// Package holes finds and pretty-prints holes & data sections of a file. -// Used by TestFileHoleCopy in the gocryptfs test suite. -package holes - -import ( - "fmt" - "log" - "math/rand" - "os" - "syscall" - "time" -) - -const ( - SEEK_DATA = 3 - SEEK_HOLE = 4 - - SegmentHole = SegmentType(100) - SegmentData = SegmentType(101) - SegmentEOF = SegmentType(102) -) - -type Whence int - -func (w Whence) String() string { - switch w { - case SEEK_DATA: - return "SEEK_DATA" - case SEEK_HOLE: - return "SEEK_HOLE" - default: - return "???" - } -} - -type Segment struct { - Offset int64 - Type SegmentType -} - -func (s Segment) String() string { - return fmt.Sprintf("%10d %v", s.Offset, s.Type) -} - -type SegmentType int - -func (s SegmentType) String() string { - switch s { - case SegmentHole: - return "hole" - case SegmentData: - return "data" - case SegmentEOF: - return "eof" - default: - return "???" - } -} - -// PrettyPrint pretty-prints the Segments. -func PrettyPrint(segments []Segment) (out string) { - for i, s := range segments { - out += s.String() - if i < len(segments)-1 { - out += "\n" - } - } - return out -} - -// Find examines the file passed via file descriptor and returns the found holes -// and data sections. -func Find(fd int) (segments []Segment, err error) { - var st syscall.Stat_t - err = syscall.Fstat(fd, &st) - if err != nil { - return nil, err - } - totalSize := st.Size - - var cursor int64 - - // find out if file starts with data or hole - off, err := syscall.Seek(fd, 0, SEEK_DATA) - // starts with hole and has no data - if err == syscall.ENXIO { - segments = append(segments, - Segment{0, SegmentHole}, - Segment{totalSize, SegmentEOF}) - return segments, nil - } - if err != nil { - return nil, err - } - // starts with data - if off == cursor { - segments = append(segments, Segment{0, SegmentData}) - } else { - // starts with hole - segments = append(segments, - Segment{0, SegmentHole}, - Segment{off, SegmentData}) - cursor = off - } - - // now we are at the start of data. - // find next hole, then next data, then next hole, then next data... - for { - oldCursor := cursor - // Next hole - off, err = syscall.Seek(fd, cursor, SEEK_HOLE) - if err != nil { - return nil, err - } - segments = append(segments, Segment{off, SegmentHole}) - cursor = off - - // Next data - off, err := syscall.Seek(fd, cursor, SEEK_DATA) - // No more data? - if err == syscall.ENXIO { - segments = append(segments, - Segment{totalSize, SegmentEOF}) - return segments, nil - } - if err != nil { - return nil, err - } - segments = append(segments, Segment{off, SegmentData}) - cursor = off - - if oldCursor == cursor { - return nil, fmt.Errorf("%s\nerror: seek loop!", PrettyPrint(segments)) - } - } - return segments, nil -} - -// Verify the gives `segments` using a full bytewise file scan -func Verify(fd int, segments []Segment) (err error) { - last := segments[len(segments)-1] - if last.Type != SegmentEOF { - log.Panicf("BUG: last segment is not EOF. segments: %v", segments) - } - - for i, s := range segments { - var whence int - switch s.Type { - case SegmentHole: - whence = SEEK_HOLE - case SegmentData: - whence = SEEK_DATA - case SegmentEOF: - continue - default: - log.Panicf("BUG: unkown segment type %d", s.Type) - } - for off := s.Offset; off < segments[i+1].Offset; off++ { - res, err := syscall.Seek(fd, off, whence) - if err != nil { - return fmt.Errorf("error: seek(%d, %s) returned error %v", off, Whence(whence).String(), err) - } - if res != off { - return fmt.Errorf("error: seek(%d, %s) returned new offset %d", off, Whence(whence).String(), res) - } - } - } - return err -} - -// Create a test file at `path` with random holes -func Create(path string) { - f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600) - if err != nil { - panic(err) - } - defer f.Close() - - rand.Seed(time.Now().UnixNano()) - offsets := make([]int64, 10) - for i := range offsets { - offsets[i] = int64(rand.Int31n(60000)) - } - - buf := []byte("x") - for _, off := range offsets { - _, err = f.WriteAt(buf, off) - if err != nil { - panic(err) - } - } - - // Expand the file to 50000 bytes so we sometimes have a hole on the end - if offsets[len(offsets)-1] < 50000 { - f.Truncate(50000) - } - - f.Sync() -} diff --git a/contrib/findholes/main.go b/contrib/findholes/main.go deleted file mode 100644 index 17597ae..0000000 --- a/contrib/findholes/main.go +++ /dev/null @@ -1,57 +0,0 @@ -// Find and pretty-print holes & data sections of a file. -package main - -import ( - "flag" - "fmt" - "os" - - "github.com/rfjakob/gocryptfs/contrib/findholes/holes" -) - -func main() { - flags := struct { - verify *bool - create *bool - }{} - flags.verify = flag.Bool("verify", false, "Verify results using full file scan") - flags.create = flag.Bool("create", false, "Create test file with random holes") - flag.Parse() - if flag.NArg() != 1 { - fmt.Printf("Usage: findholes FILE\n") - os.Exit(1) - } - - path := flag.Arg(0) - - if *flags.create { - holes.Create(path) - } - - f, err := os.Open(path) - if err != nil { - // os.Open() gives nicer error messages than syscall.Open() - fmt.Println(err) - os.Exit(1) - } - defer f.Close() - - segments, err := holes.Find(int(f.Fd())) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println(holes.PrettyPrint(segments)) - - if *flags.verify { - err = holes.Verify(int(f.Fd()), segments) - if err != nil { - fmt.Println(err) - os.Exit(1) - } else { - fmt.Println("verify ok") - } - } - -} diff --git a/contrib/getdents-debug/getdents/.gitignore b/contrib/getdents-debug/getdents/.gitignore deleted file mode 100644 index 6dae481..0000000 --- a/contrib/getdents-debug/getdents/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/getdents diff --git a/contrib/getdents-debug/getdents/getdents.go b/contrib/getdents-debug/getdents/getdents.go deleted file mode 100644 index a3cdac4..0000000 --- a/contrib/getdents-debug/getdents/getdents.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Small tool to try to debug unix.Getdents problems on CIFS mounts -( https://github.com/rfjakob/gocryptfs/issues/483 ) - -Example output: - -$ while sleep 1 ; do ./getdents /mnt/synology/public/tmp/g1 ; done -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=3192, err= -unix.Getdents fd3: n=0, err= -total 24072 bytes -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=-1, err=no such file or directory -total 16704 bytes -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=4176, err= -unix.Getdents fd3: n=3192, err= -unix.Getdents fd3: n=0, err= -total 24072 bytes - - -Failure looks like this in strace: - -[pid 189974] getdents64(6, 0xc000105808, 10000) = -1 ENOENT (No such file or directory) -*/ - -package main - -import ( - "flag" - "fmt" - "os" - "time" - - "golang.org/x/sys/unix" -) - -const ( - myName = "getdents" -) - -func main() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s PATH\n", myName) - fmt.Fprintf(os.Stderr, "Run getdents(2) on PATH in a 100ms loop until we hit an error\n") - os.Exit(1) - } - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - } - path := flag.Arg(0) - - tmp := make([]byte, 10000) - for i := 1; ; i++ { - sum := 0 - fd, err := unix.Open(path, unix.O_RDONLY, 0) - if err != nil { - fmt.Printf("%3d: unix.Open returned err=%v\n", i, err) - os.Exit(1) - } - fmt.Printf("%3d: unix.Getdents: ", i) - for { - n, err := unix.Getdents(fd, tmp) - fmt.Printf("n=%d; ", n) - if n <= 0 { - fmt.Printf("err=%v; total %d bytes\n", err, sum) - if err != nil { - os.Exit(1) - } - break - } - sum += n - } - unix.Close(fd) - time.Sleep(100 * time.Millisecond) - } -} diff --git a/contrib/getdents-debug/getdents_c/.gitignore b/contrib/getdents-debug/getdents_c/.gitignore deleted file mode 100644 index 2f94993..0000000 --- a/contrib/getdents-debug/getdents_c/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/getdents_c diff --git a/contrib/getdents-debug/getdents_c/Makefile b/contrib/getdents-debug/getdents_c/Makefile deleted file mode 100644 index 95e47dc..0000000 --- a/contrib/getdents-debug/getdents_c/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -getdents_c: *.c Makefile - gcc getdents.c -o getdents_c diff --git a/contrib/getdents-debug/getdents_c/getdents.c b/contrib/getdents-debug/getdents_c/getdents.c deleted file mode 100644 index 94f8c97..0000000 --- a/contrib/getdents-debug/getdents_c/getdents.c +++ /dev/null @@ -1,53 +0,0 @@ -// See ../getdents/getdents.go for some info on why -// this exists. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - if(argc != 2) { - printf("Usage: %s PATH\n", argv[0]); - printf("Run getdents(2) on PATH in a 100ms loop\n"); - exit(1); - } - - const char *path = argv[1]; - - for (int i = 1 ; ; i ++ ) { - int fd = open(path, O_RDONLY); - if (fd == -1) { - printf("%3d: open: %s\n", i, strerror(errno)); - if(errno == EINTR) { - continue; - } - exit(1); - } - - char tmp[10000]; - int sum = 0; - printf("%3d: getdents64: ", i); - for ( ; ; ) { - errno = 0; - int n = syscall(SYS_getdents64, fd, tmp, sizeof(tmp)); - printf("n=%d; ", n); - if (n <= 0) { - printf("errno=%d total %d bytes\n", errno, sum); - if (n < 0) { - exit(1); - } - break; - } - sum += n; - } - close(fd); - usleep(100000); - } -} diff --git a/contrib/getdents-debug/readdirnames/.gitignore b/contrib/getdents-debug/readdirnames/.gitignore deleted file mode 100644 index 228dbb3..0000000 --- a/contrib/getdents-debug/readdirnames/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/readdirnames diff --git a/contrib/getdents-debug/readdirnames/readdirnames.go b/contrib/getdents-debug/readdirnames/readdirnames.go deleted file mode 100644 index dc33512..0000000 --- a/contrib/getdents-debug/readdirnames/readdirnames.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Small tool to try to debug unix.Getdents problems on CIFS mounts -( https://github.com/rfjakob/gocryptfs/issues/483 ) - -Example output: - -$ while sleep 1 ; do ./readdirnames /mnt/synology/public/tmp/g1 ; done -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=868, err=readdirent: no such file or directory -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -2020/05/24 23:50:39 os.Open returned err=open /mnt/synology/public/tmp/g1: interrupted system call -Readdirnames: len=1001, err= -Readdirnames: len=1001, err= -*/ - -package main - -import ( - "flag" - "fmt" - "log" - "os" -) - -const ( - myName = "readdirnames" -) - -func main() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s PATH\n", myName) - fmt.Fprintf(os.Stderr, "Run os.File.Readdirnames on PATH\n") - os.Exit(1) - } - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - } - path := flag.Arg(0) - - f, err := os.Open(path) - if err != nil { - log.Fatalf("os.Open returned err=%v", err) - } - - names, err := f.Readdirnames(0) - fmt.Printf("Readdirnames: len=%d, err=%v\n", len(names), err) -} diff --git a/contrib/gocryptfs-maybe.bash b/contrib/gocryptfs-maybe.bash deleted file mode 100755 index 78a6b2c..0000000 --- a/contrib/gocryptfs-maybe.bash +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# -# Conditionally try to mount a gocryptfs filesystem. If either -# * CIPHERDIR/gocryptfs.conf does not exist OR -# * something is already mounted on MOUNTPOINT -# print a message to stdout (not stderr!) but exit with 0. -# -# This is meant to be called from automated mount systems like pam_mount, -# where you want to avoid error messages if the filesystem does not exist, -# or duplicate mounts if the filesystem has already been mounted. -# -# Note that pam_mount ignores messages on stdout which is why printing -# to stdout is ok. -set -eu -MYNAME=$(basename $0) -if [[ $# -lt 2 || $1 == -* ]]; then - echo "Usage: $MYNAME CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]" >&2 - exit 1 -fi -if [[ ! -f $1/gocryptfs.conf ]]; then - echo "$MYNAME: \"$1\" does not look like a gocryptfs filesystem, ignoring mount request" - exit 0 -fi -if mountpoint "$2" > /dev/null; then - echo "$MYNAME: something is already mounted on \"$2\", ignoring mount request" - exit 0 -fi -exec gocryptfs "$@" diff --git a/contrib/mount-ext4-ramdisk.sh b/contrib/mount-ext4-ramdisk.sh deleted file mode 100755 index 5ff7ef1..0000000 --- a/contrib/mount-ext4-ramdisk.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -ex - -MNT=/mnt/ext4-ramdisk - -if mountpoint $MNT ; then - exit 1 -fi - -IMG=$(mktemp /tmp/ext4-ramdisk-XXX.img) - -# unlink the file when done, space will be -# reclaimed once the fs is unmounted. Also -# cleans up in the error case. -trap 'rm "$IMG"' EXIT - -dd if=/dev/zero of="$IMG" bs=1M count=1030 status=none -mkfs.ext4 -q "$IMG" -mkdir -p "$MNT" -mount "$IMG" "$MNT" -chmod 777 "$MNT" diff --git a/contrib/statfs/.gitignore b/contrib/statfs/.gitignore deleted file mode 100644 index 1ad5baa..0000000 --- a/contrib/statfs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/statfs diff --git a/contrib/statfs/statfs.go b/contrib/statfs/statfs.go deleted file mode 100644 index 163d95a..0000000 --- a/contrib/statfs/statfs.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "encoding/json" - "flag" - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -const ( - myName = "statfs" -) - -func main() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s PATH\n", myName) - fmt.Fprintf(os.Stderr, "Dump the statfs information for PATH to the console, JSON format.\n") - os.Exit(1) - } - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - } - path := flag.Arg(0) - var st unix.Statfs_t - err := unix.Statfs(path, &st) - if err != nil { - fmt.Fprintf(os.Stderr, "statfs syscall returned error: %v\n", err) - os.Exit(2) - } - jsn, _ := json.MarshalIndent(st, "", "\t") - fmt.Println(string(jsn)) -} diff --git a/contrib/statvsfstat/.gitignore b/contrib/statvsfstat/.gitignore deleted file mode 100644 index 7f17e5f..0000000 --- a/contrib/statvsfstat/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/statvsfstat diff --git a/contrib/statvsfstat/statvsfstat.go b/contrib/statvsfstat/statvsfstat.go deleted file mode 100644 index e5159ce..0000000 --- a/contrib/statvsfstat/statvsfstat.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -const ( - myName = "statvsfstat" -) - -func main() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s PATH\n", myName) - fmt.Fprintf(os.Stderr, "Dump the stat and fstat information for PATH to the console, JSON format.\n") - os.Exit(1) - } - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - } - path := flag.Arg(0) - - var st unix.Stat_t - err := unix.Stat(path, &st) - if err != nil { - fmt.Fprintf(os.Stderr, "stat syscall returned error: %v\n", err) - os.Exit(4) - } - - fd, err := unix.Open(path, unix.O_RDONLY, 0) - if err != nil { - fmt.Fprintf(os.Stderr, "open syscall returned error: %v\n", err) - os.Exit(3) - } - var fst unix.Stat_t - err = unix.Fstat(fd, &fst) - if err != nil { - fmt.Fprintf(os.Stderr, "fstat syscall returned error: %v\n", err) - os.Exit(2) - } - - fmt.Printf("stat result: %#v\n", st) - fmt.Printf("fstat result: %#v\n", fst) - if st == fst { - fmt.Println("results are identical") - } else { - fmt.Println("results differ") - } -} diff --git a/crossbuild.bash b/crossbuild.bash deleted file mode 100755 index 0904d54..0000000 --- a/crossbuild.bash +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -eu -# -# Build on all supported architectures & operating systems - -cd "$(dirname "$0")" - -export GO111MODULE=on -B="go build -tags without_openssl" - -set -x - -export CGO_ENABLED=0 - -GOOS=linux GOARCH=amd64 $B - -# See https://github.com/golang/go/wiki/GoArm -GOOS=linux GOARCH=arm GOARM=7 $B -GOOS=linux GOARCH=arm64 $B - -# MacOS on Intel -GOOS=darwin GOARCH=amd64 $B - -# MacOS on Apple Silicon M1. -# Go 1.16 added support for the M1 and added ios/arm64, -# so we use this to check if we should attempt a build. -if go tool dist list | grep ios/arm64 ; then - GOOS=darwin GOARCH=arm64 $B -fi - -# The cross-built binary is not useful on the compile host. -rm gocryptfs diff --git a/ctlsock/ctlsock.go b/ctlsock/ctlsock.go deleted file mode 100644 index 1c440b5..0000000 --- a/ctlsock/ctlsock.go +++ /dev/null @@ -1,61 +0,0 @@ -// Package ctlsock is a Go library that can be used to query the -// gocryptfs control socket interface. This interface can be -// activated by passing `-ctlsock /tmp/my.sock` to gocryptfs on the -// command line. -// See gocryptfs-xray for a usage example. -package ctlsock - -import ( - "encoding/json" - "fmt" - "net" - "time" -) - -func (r *ResponseStruct) Error() string { - return fmt.Sprintf("errno %d: %s", r.ErrNo, r.ErrText) -} - -// CtlSock encapsulates a control socket -type CtlSock struct { - Conn net.Conn -} - -// New opens the socket at `socketPath` and stores it in a `CtlSock` object. -func New(socketPath string) (*CtlSock, error) { - conn, err := net.DialTimeout("unix", socketPath, 1*time.Second) - if err != nil { - return nil, err - } - return &CtlSock{Conn: conn}, nil -} - -// Query sends a request to the control socket returns the response. -func (c *CtlSock) Query(req *RequestStruct) (*ResponseStruct, error) { - c.Conn.SetDeadline(time.Now().Add(time.Second)) - msg, err := json.Marshal(req) - if err != nil { - return nil, err - } - _, err = c.Conn.Write(msg) - if err != nil { - return nil, err - } - buf := make([]byte, 5000) - n, err := c.Conn.Read(buf) - if err != nil { - return nil, err - } - buf = buf[:n] - var resp ResponseStruct - json.Unmarshal(buf, &resp) - if resp.ErrNo != 0 { - return nil, &resp - } - return &resp, nil -} - -// Close closes the socket -func (c *CtlSock) Close() { - c.Conn.Close() -} diff --git a/ctlsock/json_abi.go b/ctlsock/json_abi.go deleted file mode 100644 index 7deff08..0000000 --- a/ctlsock/json_abi.go +++ /dev/null @@ -1,26 +0,0 @@ -package ctlsock - -// RequestStruct is sent by a client (encoded as JSON). -// You cannot perform both encryption and decryption in the same request. -type RequestStruct struct { - // EncryptPath is the path that should be encrypted. - EncryptPath string - // DecryptPath is the path that should be decrypted. - DecryptPath string -} - -// ResponseStruct is sent by the server in response to a request -// (encoded as JSON). -type ResponseStruct struct { - // Result is the resulting decrypted or encrypted path. Empty on error. - Result string - // ErrNo is the error number as defined in errno.h. - // 0 means success and -1 means that the error number is not known - // (look at ErrText in this case). - ErrNo int32 - // ErrText is a detailed error message. - ErrText string - // WarnText contains warnings that may have been encountered while - // processing the message. - WarnText string -} diff --git a/daemonize.go b/daemonize.go deleted file mode 100644 index 6fdd1e4..0000000 --- a/daemonize.go +++ /dev/null @@ -1,106 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "os/signal" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// The child sends us USR1 if the mount was successful. Exit with error code -// 0 if we get it. -func exitOnUsr1() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGUSR1) - go func() { - <-c - os.Exit(0) - }() -} - -// forkChild - execute ourselves once again, this time with the "-fg" flag, and -// wait for SIGUSR1 or child exit. -// This is a workaround for the missing true fork function in Go. -func forkChild() int { - name := os.Args[0] - // Use the full path to our executable if we can get if from /proc. - buf := make([]byte, syscallcompat.PATH_MAX) - n, err := syscall.Readlink("/proc/self/exe", buf) - if err == nil { - name = string(buf[:n]) - tlog.Debug.Printf("forkChild: readlink worked: %q", name) - } - newArgs := []string{"-fg", fmt.Sprintf("-notifypid=%d", os.Getpid())} - newArgs = append(newArgs, os.Args[1:]...) - c := exec.Command(name, newArgs...) - c.Stdout = os.Stdout - c.Stderr = os.Stderr - c.Stdin = os.Stdin - exitOnUsr1() - err = c.Start() - if err != nil { - tlog.Fatal.Printf("forkChild: starting %s failed: %v", name, err) - return exitcodes.ForkChild - } - err = c.Wait() - if err != nil { - if exiterr, ok := err.(*exec.ExitError); ok { - if waitstat, ok := exiterr.Sys().(syscall.WaitStatus); ok { - os.Exit(waitstat.ExitStatus()) - } - } - tlog.Fatal.Printf("forkChild: wait returned an unknown error: %v", err) - return exitcodes.ForkChild - } - // The child exited with 0 - let's do the same. - return 0 -} - -// redirectStdFds redirects stderr and stdout to syslog; stdin to /dev/null -func redirectStdFds() { - // Create a pipe pair "pw" -> "pr" and start logger reading from "pr". - // We do it ourselves instead of using StdinPipe() because we need access - // to the fd numbers. - pr, pw, err := os.Pipe() - if err != nil { - tlog.Warn.Printf("redirectStdFds: could not create pipe: %v\n", err) - return - } - tag := fmt.Sprintf("gocryptfs-%d-logger", os.Getpid()) - cmd := exec.Command("logger", "-t", tag) - cmd.Stdin = pr - err = cmd.Start() - if err != nil { - tlog.Warn.Printf("redirectStdFds: could not start logger: %v\n", err) - return - } - // The logger now reads on "pr". We can close it. - pr.Close() - // Redirect stout and stderr to "pw". - err = syscallcompat.Dup3(int(pw.Fd()), 1, 0) - if err != nil { - tlog.Warn.Printf("redirectStdFds: stdout dup error: %v\n", err) - } - syscallcompat.Dup3(int(pw.Fd()), 2, 0) - if err != nil { - tlog.Warn.Printf("redirectStdFds: stderr dup error: %v\n", err) - } - // Our stout and stderr point to "pw". We can close the extra copy. - pw.Close() - // Redirect stdin to /dev/null - nullFd, err := os.Open("/dev/null") - if err != nil { - tlog.Warn.Printf("redirectStdFds: could not open /dev/null: %v\n", err) - return - } - err = syscallcompat.Dup3(int(nullFd.Fd()), 0, 0) - if err != nil { - tlog.Warn.Printf("redirectStdFds: stdin dup error: %v\n", err) - } - nullFd.Close() -} diff --git a/directory.go b/directory.go new file mode 100644 index 0000000..8ff2659 --- /dev/null +++ b/directory.go @@ -0,0 +1,242 @@ +package main + +import ( + "C" + "fmt" + "io" + "strings" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" + + "./allocator" + "./internal/configfile" + "./internal/cryptocore" + "./internal/nametransform" + "./internal/syscallcompat" +) + +func mkdirWithIv(dirfd int, cName string, mode uint32) error { + // Between the creation of the directory and the creation of gocryptfs.diriv + // the directory is inconsistent. Take the lock to prevent other readers + // from seeing it. + err := unix.Mkdirat(dirfd, cName, mode) + if err != nil { + return err + } + dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_DIRECTORY|syscall.O_NOFOLLOW|syscallcompat.O_PATH, 0) + if err == nil { + // Create gocryptfs.diriv + err = nametransform.WriteDirIVAt(dirfd2) + syscall.Close(dirfd2) + } + if err != nil { + // Delete inconsistent directory (missing gocryptfs.diriv!) + syscallcompat.Unlinkat(dirfd, cName, unix.AT_REMOVEDIR) + } + return err +} + +//export gcf_list_dir +func gcf_list_dir(sessionID int, dirName string) (*C.char, *C.int, C.int) { + volume := OpenedVolumes[sessionID] + parentDirFd, cDirName, err := volume.prepareAtSyscall(dirName) + if err != nil { + return nil, nil, 0 + } + defer syscall.Close(parentDirFd) + // Read ciphertext directory + fd, err := syscallcompat.Openat(parentDirFd, cDirName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) + if err != nil { + return nil, nil, 0 + } + defer syscall.Close(fd) + cipherEntries, err := syscallcompat.Getdents(fd) + if err != nil { + return nil, nil, 0 + } + // Get DirIV (stays nil if PlaintextNames is used) + var cachedIV []byte + if !OpenedVolumes[sessionID].plainTextNames { + // Read the DirIV from disk + cachedIV, err = nametransform.ReadDirIVAt(fd) + if err != nil { + return nil, nil, 0 + } + } + // Decrypted directory entries + var plain strings.Builder + var modes []uint32 + // Filter and decrypt filenames + for i := range cipherEntries { + cName := cipherEntries[i].Name + if dirName == "" && cName == configfile.ConfDefaultName { + // silently ignore "gocryptfs.conf" in the top level dir + continue + } + if OpenedVolumes[sessionID].plainTextNames { + plain.WriteString(cipherEntries[i].Name + "\x00") + modes = append(modes, cipherEntries[i].Mode) + continue + } + if cName == nametransform.DirIVFilename { + // silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled + continue + } + // Handle long file name + isLong := nametransform.NameType(cName) + if isLong == nametransform.LongNameContent { + cNameLong, err := nametransform.ReadLongNameAt(fd, cName) + if err != nil { + continue + } + cName = cNameLong + } else if isLong == nametransform.LongNameFilename { + // ignore "gocryptfs.longname.*.name" + continue + } + name, err := OpenedVolumes[sessionID].nameTransform.DecryptName(cName, cachedIV) + if err != nil { + continue + } + // Override the ciphertext name with the plaintext name but reuse the rest + // of the structure + cipherEntries[i].Name = name + plain.WriteString(cipherEntries[i].Name + "\x00") + modes = append(modes, cipherEntries[i].Mode) + } + p := allocator.Malloc(len(modes)) + for i := 0; i < len(modes); i++ { + offset := C.sizeof_int * uintptr(i) + *(*C.int)(unsafe.Pointer(uintptr(p) + offset)) = (C.int)(modes[i]) + } + return C.CString(plain.String()), (*C.int)(p), (C.int)(len(modes)) +} + +//export gcf_mkdir +func gcf_mkdir(sessionID int, path string, mode uint32) bool { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(path) + if err != nil { + return false + } + defer syscall.Close(dirfd) + + if volume.plainTextNames { + err = unix.Mkdirat(dirfd, cName, mode) + if err != nil { + return false + } + var ust unix.Stat_t + err = syscallcompat.Fstatat(dirfd, cName, &ust, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + return false + } + } else { + // We need write and execute permissions to create gocryptfs.diriv. + // Also, we need read permissions to open the directory (to avoid + // race-conditions between getting and setting the mode). + origMode := mode + mode := mode | 0700 + + // Handle long file name + if nametransform.IsLongContent(cName) { + // Create ".name" + err = OpenedVolumes[sessionID].nameTransform.WriteLongNameAt(dirfd, cName, path) + if err != nil { + return false + } + + // Create directory + err = mkdirWithIv(dirfd, cName, mode) + if err != nil { + nametransform.DeleteLongNameAt(dirfd, cName) + return false + } + } else { + err = mkdirWithIv(dirfd, cName, mode) + if err != nil { + return false + } + } + + fd, err := syscallcompat.Openat(dirfd, cName, + syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) + if err != nil { + return false + } + defer syscall.Close(fd) + + var st syscall.Stat_t + err = syscall.Fstat(fd, &st) + if err != nil { + return false + } + + // Fix permissions + if origMode != mode { + // Preserve SGID bit if it was set due to inheritance. + origMode = uint32(st.Mode&^0777) | origMode + syscall.Fchmod(fd, origMode) + } + } + + return true +} + +//export gcf_rmdir +func gcf_rmdir(sessionID int, relPath string) bool { + volume := OpenedVolumes[sessionID] + parentDirFd, cName, err := volume.openBackingDir(relPath) + if err != nil { + return false + } + defer syscall.Close(parentDirFd) + if volume.plainTextNames { + // Unlinkat with AT_REMOVEDIR is equivalent to Rmdir + err = unix.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) + return errToBool(err) + } + dirfd, err := syscallcompat.Openat(parentDirFd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) + if err != nil { + return false + } + defer syscall.Close(dirfd) + // Check directory contents + children, err := syscallcompat.Getdents(dirfd) + if err == io.EOF { + // The directory is empty + err = unix.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) + return errToBool(err) + } + if err != nil { + return false + } + // If the directory is not empty besides gocryptfs.diriv, do not even + // attempt the dance around gocryptfs.diriv. + if len(children) > 1 { + return false + } + // Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ" + tmpName := fmt.Sprintf("%s.rmdir.%d", nametransform.DirIVFilename, cryptocore.RandUint64()) + err = syscallcompat.Renameat(dirfd, nametransform.DirIVFilename, parentDirFd, tmpName) + if err != nil { + return false + } + // Actual Rmdir + err = syscallcompat.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) + if err != nil { + // This can happen if another file in the directory was created in the + // meantime, undo the rename + syscallcompat.Renameat(parentDirFd, tmpName, dirfd, nametransform.DirIVFilename) + return errToBool(err) + } + // Delete "gocryptfs.diriv.rmdir.XYZ" + syscallcompat.Unlinkat(parentDirFd, tmpName, 0) + // Delete .name file + if nametransform.IsLongContent(cName) { + nametransform.DeleteLongNameAt(parentDirFd, cName) + } + return true +} diff --git a/file.go b/file.go new file mode 100644 index 0000000..0e4a56b --- /dev/null +++ b/file.go @@ -0,0 +1,488 @@ +package main + +import ( + "C" + "bytes" + "io" + "math" + "os" + "syscall" + + "./internal/contentenc" + "./internal/nametransform" + "./internal/syscallcompat" +) + +// mangleOpenFlags is used by Create() and Open() to convert the open flags the user +// wants to the flags we internally use to open the backing file. +// The returned flags always contain O_NOFOLLOW. +func mangleOpenFlags(flags uint32) (newFlags int) { + newFlags = int(flags) + // Convert WRONLY to RDWR. We always need read access to do read-modify-write cycles. + if (newFlags & syscall.O_ACCMODE) == syscall.O_WRONLY { + newFlags = newFlags ^ os.O_WRONLY | os.O_RDWR + } + // We also cannot open the file in append mode, we need to seek back for RMW + newFlags = newFlags &^ os.O_APPEND + // O_DIRECT accesses must be aligned in both offset and length. Due to our + // crypto header, alignment will be off, even if userspace makes aligned + // accesses. Running xfstests generic/013 on ext4 used to trigger lots of + // EINVAL errors due to missing alignment. Just fall back to buffered IO. + newFlags = newFlags &^ syscallcompat.O_DIRECT + // Create and Open are two separate FUSE operations, so O_CREAT should not + // be part of the open flags. + newFlags = newFlags &^ syscall.O_CREAT + // We always want O_NOFOLLOW to be safe against symlink races + newFlags |= syscall.O_NOFOLLOW + return newFlags +} + +func (volume *Volume) registerFileHandle(file File) int { + handleID := -1 + c := 0 + for handleID == -1 { + _, ok := volume.file_handles[c] + if !ok { + handleID = c + } + c++ + } + volume.file_handles[handleID] = file + return handleID +} + +// readFileID loads the file header from disk and extracts the file ID. +// Returns io.EOF if the file is empty. +func readFileID(fd *os.File) ([]byte, error) { + // We read +1 byte to determine if the file has actual content + // and not only the header. A header-only file will be considered empty. + // This makes File ID poisoning more difficult. + readLen := contentenc.HeaderLen + 1 + buf := make([]byte, readLen) + _, err := fd.ReadAt(buf, 0) + if err != nil { + return nil, err + } + buf = buf[:contentenc.HeaderLen] + h, err := contentenc.ParseHeader(buf) + if err != nil { + return nil, err + } + return h.ID, nil +} + +// createHeader creates a new random header and writes it to disk. +// Returns the new file ID. +// The caller must hold fileIDLock.Lock(). +func createHeader(fd *os.File) (fileID []byte, err error) { + h := contentenc.RandomHeader() + buf := h.Pack() + // Prevent partially written (=corrupt) header by preallocating the space beforehand + err = syscallcompat.EnospcPrealloc(int(fd.Fd()), 0, contentenc.HeaderLen) + if err != nil { + return nil, err + } + // Actually write header + _, err = fd.WriteAt(buf, 0) + if err != nil { + return nil, err + } + return h.ID, err +} + +// doRead - read "length" plaintext bytes from plaintext offset "off" and append +// to "dst". +// Arguments "length" and "off" do not have to be block-aligned. +// +// doRead reads the corresponding ciphertext blocks from disk, decrypts them and +// returns the requested part of the plaintext. +// +// Called by Read() for normal reading, +// by Write() and Truncate() via doWrite() for Read-Modify-Write. +func (volume *Volume) doRead(handleID int, dst []byte, off uint64, length uint64) ([]byte, bool) { + f, ok := volume.file_handles[handleID] + if !ok { + return nil, false + } + fd := f.fd + // Get the file ID, either from the open file table, or from disk. + var fileID []byte + if volume.fileIDs[handleID] != nil { + // Use the cached value in the file table + fileID = volume.fileIDs[handleID] + } else { + // Not cached, we have to read it from disk. + var err error + fileID, err = readFileID(fd) + if err != nil { + return nil, false + } + // Save into the file table + volume.fileIDs[handleID] = fileID + } + + // Read the backing ciphertext in one go + blocks := volume.contentEnc.ExplodePlainRange(off, length) + alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks) + // f.fd.ReadAt takes an int64! + if alignedOffset > math.MaxInt64 { + return nil, false + } + skip := blocks[0].Skip + + ciphertext := volume.contentEnc.CReqPool.Get() + ciphertext = ciphertext[:int(alignedLength)] + n, err := fd.ReadAt(ciphertext, int64(alignedOffset)) + if err != nil && err != io.EOF { + return nil, false + } + // The ReadAt came back empty. We can skip all the decryption and return early. + if n == 0 { + volume.contentEnc.CReqPool.Put(ciphertext) + return dst, true + } + // Truncate ciphertext buffer down to actually read bytes + ciphertext = ciphertext[0:n] + + firstBlockNo := blocks[0].BlockNo + + // Decrypt it + plaintext, err := volume.contentEnc.DecryptBlocks(ciphertext, firstBlockNo, fileID) + volume.contentEnc.CReqPool.Put(ciphertext) + if err != nil { + return nil, false + } + + // Crop down to the relevant part + var out []byte + lenHave := len(plaintext) + lenWant := int(skip + length) + if lenHave > lenWant { + out = plaintext[skip:lenWant] + } else if lenHave > int(skip) { + out = plaintext[skip:lenHave] + } + // else: out stays empty, file was smaller than the requested offset + + out = append(dst, out...) + volume.contentEnc.PReqPool.Put(plaintext) + + return out, true +} + +// doWrite - encrypt "data" and write it to plaintext offset "off" +// +// Arguments do not have to be block-aligned, read-modify-write is +// performed internally as necessary +// +// Called by Write() for normal writing, +// and by Truncate() to rewrite the last file block. +// +// Empty writes do nothing and are allowed. +func (volume *Volume) doWrite(handleID int, data []byte, off uint64) (uint32, bool) { + fileWasEmpty := false + // Get the file ID, create a new one if it does not exist yet. + var fileID []byte + + f, ok := volume.file_handles[handleID] + if !ok { + return 0, false + } + fd := f.fd + // The caller has exclusively locked ContentLock, which blocks all other + // readers and writers. No need to take IDLock. + if volume.fileIDs[handleID] != nil { + fileID = volume.fileIDs[handleID] + } else { + // If the file ID is not cached, read it from disk + var err error + fileID, err = readFileID(fd) + // Write a new file header if the file is empty + if err == io.EOF { + fileID, err = createHeader(fd) + fileWasEmpty = true + } + if err != nil { + return 0, false + } + volume.fileIDs[handleID] = fileID + } + // Handle payload data + dataBuf := bytes.NewBuffer(data) + blocks := volume.contentEnc.ExplodePlainRange(off, uint64(len(data))) + toEncrypt := make([][]byte, len(blocks)) + for i, b := range blocks { + blockData := dataBuf.Next(int(b.Length)) + // Incomplete block -> Read-Modify-Write + if b.IsPartial() { + // Read + oldData, success := volume.doRead(handleID, nil, b.BlockPlainOff(), volume.contentEnc.PlainBS()) + if !success { + return 0, false + } + // Modify + blockData = volume.contentEnc.MergeBlocks(oldData, blockData, int(b.Skip)) + } + // Write into the to-encrypt list + toEncrypt[i] = blockData + } + // Encrypt all blocks + ciphertext := volume.contentEnc.EncryptBlocks(toEncrypt, blocks[0].BlockNo, fileID) + // Preallocate so we cannot run out of space in the middle of the write. + // This prevents partially written (=corrupt) blocks. + var err error + cOff := blocks[0].BlockCipherOff() + // f.fd.WriteAt & syscallcompat.EnospcPrealloc take int64 offsets! + if cOff > math.MaxInt64 { + return 0, false + } + err = syscallcompat.EnospcPrealloc(int(fd.Fd()), int64(cOff), int64(len(ciphertext))) + if err != nil { + if fileWasEmpty { + // Kill the file header again + syscall.Ftruncate(int(fd.Fd()), 0) + gcf_close_file(volume.volumeID, handleID) + } + return 0, false + } + // Write + _, err = f.fd.WriteAt(ciphertext, int64(cOff)) + // Return memory to CReqPool + volume.contentEnc.CReqPool.Put(ciphertext) + if err != nil { + return 0, false + } + return uint32(len(data)), true +} + +// Zero-pad the file of size plainSize to the next block boundary. This is a no-op +// if the file is already block-aligned. +func (volume *Volume) zeroPad(handleID int, plainSize uint64) bool { + lastBlockLen := plainSize % volume.contentEnc.PlainBS() + if lastBlockLen == 0 { + // Already block-aligned + return true + } + missing := volume.contentEnc.PlainBS() - lastBlockLen + pad := make([]byte, missing) + _, success := volume.doWrite(handleID, pad, plainSize) + return success +} + +// truncateGrowFile extends a file using seeking or ftruncate performing RMW on +// the first and last block as necessary. New blocks in the middle become +// file holes unless they have been fallocate()'d beforehand. +func (volume *Volume) truncateGrowFile(handleID int, oldPlainSz uint64, newPlainSz uint64) bool { + if newPlainSz <= oldPlainSz { + return false + } + newEOFOffset := newPlainSz - 1 + if oldPlainSz > 0 { + n1 := volume.contentEnc.PlainOffToBlockNo(oldPlainSz - 1) + n2 := volume.contentEnc.PlainOffToBlockNo(newEOFOffset) + // The file is grown within one block, no need to pad anything. + // Write a single zero to the last byte and let doWrite figure out the RMW. + if n1 == n2 { + buf := make([]byte, 1) + _, success := volume.doWrite(handleID, buf, newEOFOffset) + return success + } + } + // The truncate creates at least one new block. + // + // Make sure the old last block is padded to the block boundary. This call + // is a no-op if it is already block-aligned. + success := volume.zeroPad(handleID, oldPlainSz) + if !success { + return false + } + // The new size is block-aligned. In this case we can do everything ourselves + // and avoid the call to doWrite. + if newPlainSz%volume.contentEnc.PlainBS() == 0 { + // The file was empty, so it did not have a header. Create one. + if oldPlainSz == 0 { + id, err := createHeader(volume.file_handles[handleID].fd) + if err != nil { + return false + } + volume.fileIDs[handleID] = id + } + cSz := int64(volume.contentEnc.PlainSizeToCipherSize(newPlainSz)) + err := syscall.Ftruncate(int(volume.file_handles[handleID].fd.Fd()), cSz) + return errToBool(err) + } + // The new size is NOT aligned, so we need to write a partial block. + // Write a single zero to the last byte and let doWrite figure it out. + buf := make([]byte, 1) + _, success = volume.doWrite(handleID, buf, newEOFOffset) + return success +} + +func (volume *Volume) truncate(handleID int, newSize uint64) bool { + fileFD := int(volume.file_handles[handleID].fd.Fd()) + var err error + // Common case first: Truncate to zero + if newSize == 0 { + err = syscall.Ftruncate(fileFD, 0) + return err == nil + } + // We need the old file size to determine if we are growing or shrinking + // the file + oldSize, _, success := gcf_get_attrs(volume.volumeID, volume.file_handles[handleID].path) + if !success { + return false + } + + // File size stays the same - nothing to do + if newSize == oldSize { + return true + } + // File grows + if newSize > oldSize { + return volume.truncateGrowFile(handleID, oldSize, newSize) + } + + // File shrinks + blockNo := volume.contentEnc.PlainOffToBlockNo(newSize) + cipherOff := volume.contentEnc.BlockNoToCipherOff(blockNo) + plainOff := volume.contentEnc.BlockNoToPlainOff(blockNo) + lastBlockLen := newSize - plainOff + var data []byte + if lastBlockLen > 0 { + data, success = volume.doRead(handleID, nil, plainOff, lastBlockLen) + if !success { + return false + } + } + // Truncate down to the last complete block + err = syscall.Ftruncate(fileFD, int64(cipherOff)) + if err != nil { + return false + } + // Append partial block + if lastBlockLen > 0 { + _, success := volume.doWrite(handleID, data, plainOff) + return success + } + return true +} + +//export gcf_open_read_mode +func gcf_open_read_mode(sessionID int, path string) int { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(path) + if err != nil { + return -1 + } + defer syscall.Close(dirfd) + + // Open backing file + fd, err := syscallcompat.Openat(dirfd, cName, mangleOpenFlags(0), 0) + if err != nil { + return -1 + } + return volume.registerFileHandle(File{os.NewFile(uintptr(fd), cName), path}) +} + +//export gcf_open_write_mode +func gcf_open_write_mode(sessionID int, path string, mode uint32) int { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(path) + if err != nil { + return -1 + } + defer syscall.Close(dirfd) + + fd := -1 + newFlags := mangleOpenFlags(syscall.O_RDWR) + // Handle long file name + if !volume.plainTextNames && nametransform.IsLongContent(cName) { + // Create ".name" + err = volume.nameTransform.WriteLongNameAt(dirfd, cName, path) + if err != nil { + return -1 + } + // Create content + fd, err = syscallcompat.Openat(dirfd, cName, newFlags|syscall.O_CREAT, mode) + if err != nil { + nametransform.DeleteLongNameAt(dirfd, cName) + } + } else { + // Create content, normal (short) file name + fd, err = syscallcompat.Openat(dirfd, cName, newFlags|syscall.O_CREAT, mode) + } + if err != nil { + return -1 + } + return volume.registerFileHandle(File{os.NewFile(uintptr(fd), cName), path}) +} + +//export gcf_truncate +func gcf_truncate(sessionID int, handleID int, offset uint64) bool { + volume := OpenedVolumes[sessionID] + return volume.truncate(handleID, offset) +} + +//export gcf_read_file +func gcf_read_file(sessionID, handleID int, offset uint64, dst_buff []byte) uint32 { + length := len(dst_buff) + if length > contentenc.MAX_KERNEL_WRITE { + // This would crash us due to our fixed-size buffer pool + return 0 + } + + volume := OpenedVolumes[sessionID] + out, success := volume.doRead(handleID, dst_buff[:0], offset, uint64(length)) + if !success { + return 0 + } else { + return uint32(len(out)) + } +} + +//export gcf_write_file +func gcf_write_file(sessionID, handleID int, offset uint64, data []byte) uint32 { + length := len(data) + if length > contentenc.MAX_KERNEL_WRITE { + // This would crash us due to our fixed-size buffer pool + return 0 + } + + volume := OpenedVolumes[sessionID] + n, _ := volume.doWrite(handleID, data, offset) + return n +} + +//export gcf_close_file +func gcf_close_file(sessionID, handleID int) { + f, ok := OpenedVolumes[sessionID].file_handles[handleID] + if ok { + f.fd.Close() + delete(OpenedVolumes[sessionID].file_handles, handleID) + _, ok := OpenedVolumes[sessionID].fileIDs[handleID] + if ok { + delete(OpenedVolumes[sessionID].fileIDs, handleID) + } + } +} + +//export gcf_remove_file +func gcf_remove_file(sessionID int, path string) bool { + volume := OpenedVolumes[sessionID] + dirfd, cName, err := volume.prepareAtSyscall(path) + if err != nil { + return false + } + defer syscall.Close(dirfd) + + // Delete content + err = syscallcompat.Unlinkat(dirfd, cName, 0) + if err != nil { + return false + } + // Delete ".name" file + if !volume.plainTextNames && nametransform.IsLongContent(cName) { + err = nametransform.DeleteLongNameAt(dirfd, cName) + } + return errToBool(err) +} diff --git a/fsck.go b/fsck.go deleted file mode 100644 index 1f40514..0000000 --- a/fsck.go +++ /dev/null @@ -1,346 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/signal" - "path/filepath" - "strings" - "sync" - "syscall" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fusefrontend" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -type fsckObj struct { - rootNode *fusefrontend.RootNode - // mnt is the mountpoint of the temporary mount - mnt string - // List of corrupt files - corruptList []string - // List of skipped files - skippedList []string - // Protects corruptList - listLock sync.Mutex - // stop a running watchMitigatedCorruptions thread - watchDone chan struct{} - // Inode numbers of hard-linked files (Nlink > 1) that we have already checked - seenInodes map[uint64]struct{} - // abort the running fsck operation? Checked in a few long-running loops. - abort bool -} - -func runsAsRoot() bool { - return syscall.Geteuid() == 0 -} - -func (ck *fsckObj) markCorrupt(path string) { - ck.listLock.Lock() - ck.corruptList = append(ck.corruptList, path) - ck.listLock.Unlock() -} - -func (ck *fsckObj) markSkipped(path string) { - ck.listLock.Lock() - ck.skippedList = append(ck.skippedList, path) - ck.listLock.Unlock() -} - -func (ck *fsckObj) abs(relPath string) (absPath string) { - return filepath.Join(ck.mnt, relPath) -} - -// Watch for mitigated corruptions that occur during OpenDir() -func (ck *fsckObj) watchMitigatedCorruptionsOpenDir(path string) { - for { - select { - case item := <-ck.rootNode.MitigatedCorruptions: - fmt.Printf("fsck: corrupt entry in dir %q: %q\n", path, item) - ck.markCorrupt(filepath.Join(path, item)) - case <-ck.watchDone: - return - } - } -} - -// Recursively check dir for corruption -func (ck *fsckObj) dir(relPath string) { - tlog.Debug.Printf("ck.dir %q\n", relPath) - ck.xattrs(relPath) - // Run OpenDir and catch transparently mitigated corruptions - go ck.watchMitigatedCorruptionsOpenDir(relPath) - f, err := os.Open(ck.abs(relPath)) - ck.watchDone <- struct{}{} - if err != nil { - fmt.Printf("fsck: error opening dir %q: %v\n", relPath, err) - if err == os.ErrPermission && !runsAsRoot() { - ck.markSkipped(relPath) - } else { - ck.markCorrupt(relPath) - } - return - } - go ck.watchMitigatedCorruptionsOpenDir(relPath) - entries, err := f.Readdirnames(0) - ck.watchDone <- struct{}{} - if err != nil { - fmt.Printf("fsck: error reading dir %q: %v\n", relPath, err) - ck.markCorrupt(relPath) - return - } - for _, entry := range entries { - if ck.abort { - return - } - if entry == "." || entry == ".." { - continue - } - nextPath := filepath.Join(relPath, entry) - var st syscall.Stat_t - err := syscall.Lstat(ck.abs(nextPath), &st) - if err != nil { - ck.markCorrupt(filepath.Join(relPath, entry)) - continue - } - filetype := st.Mode & syscall.S_IFMT - //fmt.Printf(" %q %x\n", entry.Name, entry.Mode) - switch filetype { - case syscall.S_IFDIR: - ck.dir(nextPath) - case syscall.S_IFREG: - ck.file(nextPath) - case syscall.S_IFLNK: - ck.symlink(nextPath) - case syscall.S_IFIFO, syscall.S_IFSOCK, syscall.S_IFBLK, syscall.S_IFCHR: - // nothing to check - default: - fmt.Printf("fsck: unhandled file type %x\n", filetype) - } - } -} - -func (ck *fsckObj) symlink(relPath string) { - _, err := os.Readlink(ck.abs(relPath)) - if err != nil { - ck.markCorrupt(relPath) - fmt.Printf("fsck: error reading symlink %q: %v\n", relPath, err) - } -} - -// Watch for mitigated corruptions that occur during Read() -func (ck *fsckObj) watchMitigatedCorruptionsRead(path string) { - for { - select { - case item := <-ck.rootNode.MitigatedCorruptions: - fmt.Printf("fsck: corrupt file %q (inode %s)\n", path, item) - ck.markCorrupt(path) - case <-ck.watchDone: - return - } - } -} - -// Check file for corruption -func (ck *fsckObj) file(relPath string) { - tlog.Debug.Printf("ck.file %q\n", relPath) - var st syscall.Stat_t - err := syscall.Lstat(ck.abs(relPath), &st) - if err != nil { - ck.markCorrupt(relPath) - fmt.Printf("fsck: error stating file %q: %v\n", relPath, err) - return - } - if st.Nlink > 1 { - // Due to hard links, we may have already checked this file. - if _, ok := ck.seenInodes[st.Ino]; ok { - tlog.Debug.Printf("ck.file : skipping %q (inode number %d already seen)\n", relPath, st.Ino) - return - } - ck.seenInodes[st.Ino] = struct{}{} - } - ck.xattrs(relPath) - f, err := os.Open(ck.abs(relPath)) - if err != nil { - fmt.Printf("fsck: error opening file %q: %v\n", relPath, err) - if err == os.ErrPermission && !runsAsRoot() { - ck.markSkipped(relPath) - } else { - ck.markCorrupt(relPath) - } - return - } - defer f.Close() - // 128 kiB of zeros - allZero := make([]byte, fuse.MAX_KERNEL_WRITE) - buf := make([]byte, fuse.MAX_KERNEL_WRITE) - var off int64 - // Read() through the whole file and catch transparently mitigated corruptions - go ck.watchMitigatedCorruptionsRead(relPath) - defer func() { ck.watchDone <- struct{}{} }() - for { - if ck.abort { - return - } - tlog.Debug.Printf("ck.file: read %d bytes from offset %d\n", len(buf), off) - n, err := f.ReadAt(buf, off) - if err != nil && err != io.EOF { - ck.markCorrupt(relPath) - fmt.Printf("fsck: error reading file %q (inum %d): %v\n", relPath, inum(f), err) - return - } - // EOF - if err == io.EOF { - return - } - off += int64(n) - // If we seem to be in the middle of a file hole, try to skip to the next - // data section. - data := buf[:n] - if bytes.Equal(data, allZero) { - tlog.Debug.Printf("ck.file: trying to skip file hole\n") - const SEEK_DATA = 3 - nextOff, err := syscall.Seek(int(f.Fd()), off, SEEK_DATA) - if err == nil { - off = nextOff - } - } - } -} - -// Watch for mitigated corruptions that occur during ListXAttr() -func (ck *fsckObj) watchMitigatedCorruptionsListXAttr(path string) { - for { - select { - case item := <-ck.rootNode.MitigatedCorruptions: - fmt.Printf("fsck: corrupt xattr name on file %q: %q\n", path, item) - ck.markCorrupt(path + " xattr:" + item) - case <-ck.watchDone: - return - } - } -} - -// Check xattrs on file/dir at path -func (ck *fsckObj) xattrs(relPath string) { - // Run ListXAttr() and catch transparently mitigated corruptions - go ck.watchMitigatedCorruptionsListXAttr(relPath) - attrs, err := syscallcompat.Llistxattr(ck.abs(relPath)) - ck.watchDone <- struct{}{} - if err != nil { - fmt.Printf("fsck: error listing xattrs on %q: %v\n", relPath, err) - ck.markCorrupt(relPath) - return - } - // Try to read all xattr values - for _, a := range attrs { - _, err := syscallcompat.Lgetxattr(ck.abs(relPath), a) - if err != nil { - fmt.Printf("fsck: error reading xattr %q from %q: %v\n", a, relPath, err) - if err == syscall.EACCES && !runsAsRoot() { - ck.markSkipped(relPath) - } else { - ck.markCorrupt(relPath) - } - } - } -} - -// entrypoint from main() -func fsck(args *argContainer) (exitcode int) { - if args.reverse { - tlog.Fatal.Printf("Running -fsck with -reverse is not supported") - os.Exit(exitcodes.Usage) - } - args.allow_other = false - args.ro = true - var err error - args.mountpoint, err = ioutil.TempDir("", "gocryptfs.fsck.") - if err != nil { - tlog.Fatal.Printf("fsck: TmpDir: %v", err) - os.Exit(exitcodes.MountPoint) - } - pfs, wipeKeys := initFuseFrontend(args) - rn := pfs.(*fusefrontend.RootNode) - rn.MitigatedCorruptions = make(chan string) - ck := fsckObj{ - mnt: args.mountpoint, - rootNode: rn, - watchDone: make(chan struct{}), - seenInodes: make(map[uint64]struct{}), - } - if args.quiet { - // go-fuse throws a lot of these: - // writer: Write/Writev failed, err: 2=no such file or directory. opcode: INTERRUPT - // This is ugly and causes failures in xfstests. Hide them away in syslog. - tlog.SwitchLoggerToSyslog() - } - // Mount - srv := initGoFuse(pfs, args) - // Handle SIGINT & SIGTERM - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) - signal.Notify(ch, syscall.SIGTERM) - go func() { - <-ch - ck.abort = true - }() - defer func() { - err = srv.Unmount() - if err != nil { - tlog.Warn.Printf("failed to unmount %q: %v", ck.mnt, err) - } else { - if err := syscall.Rmdir(ck.mnt); err != nil { - tlog.Warn.Printf("cleaning up %q failed: %v", ck.mnt, err) - } - } - }() - // Recursively check the root dir - ck.dir("") - // Report results - wipeKeys() - if ck.abort { - tlog.Info.Printf("fsck: aborted") - return exitcodes.Other - } - if len(ck.corruptList) == 0 && len(ck.skippedList) == 0 { - tlog.Info.Printf("fsck summary: no problems found\n") - return 0 - } - if len(ck.skippedList) > 0 { - tlog.Warn.Printf("fsck: re-run this program as root to check all files!\n") - } - fmt.Printf("fsck summary: %d corrupt files, %d files skipped\n", len(ck.corruptList), len(ck.skippedList)) - return exitcodes.FsckErrors -} - -type sortableDirEntries []fuse.DirEntry - -func (s sortableDirEntries) Len() int { - return len(s) -} - -func (s sortableDirEntries) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s sortableDirEntries) Less(i, j int) bool { - return strings.Compare(s[i].Name, s[j].Name) < 0 -} - -func inum(f *os.File) uint64 { - var st syscall.Stat_t - err := syscall.Fstat(int(f.Fd()), &st) - if err != nil { - tlog.Warn.Printf("inum: fstat failed: %v", err) - return 0 - } - return st.Ino -} diff --git a/go.mod b/go.mod deleted file mode 100644 index e80a4bc..0000000 --- a/go.mod +++ /dev/null @@ -1,19 +0,0 @@ -module github.com/rfjakob/gocryptfs - -go 1.13 - -require ( - github.com/hanwen/go-fuse/v2 v2.1.1-0.20210508151621-62c5aa1919a7 - github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 - github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect - github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect - github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect - github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect - github.com/pkg/xattr v0.4.1 - github.com/rfjakob/eme v1.1.1 - github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 - github.com/stretchr/testify v1.5.1 // indirect - golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 - golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect - golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 -) diff --git a/go.sum b/go.sum deleted file mode 100644 index 8a59eb2..0000000 --- a/go.sum +++ /dev/null @@ -1,48 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc= -github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20210508151621-62c5aa1919a7 h1:9K/MBPvPptwwCYIw8gBi/Sup5Uw8UeYlyKBxxzl931Y= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20210508151621-62c5aa1919a7/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= -github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY= -github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU= -github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA= -github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd/go.mod h1:TlmyIZDpGmwRoTWiakdr+HA1Tukze6C6XbRVidYq02M= -github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff h1:2xRHTvkpJ5zJmglXLRqHiZQNjUoOkhUyhTAhEQvPAWw= -github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff/go.mod h1:gJWba/XXGl0UoOmBQKRWCJdHrr3nE0T65t6ioaj3mLI= -github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 h1:BMb8s3ENQLt5ulwVIHVDWFHp8eIXmbfSExkvdn9qMXI= -github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11/go.mod h1:+DBdDyfoO2McrOyDemRBq0q9CMEByef7sYl7JH5Q3BI= -github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb h1:uSWBjJdMf47kQlXMwWEfmc864bA1wAC+Kl3ApryuG9Y= -github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/pkg/xattr v0.4.1 h1:dhclzL6EqOXNaPDWqoeb9tIxATfBSmjqL0b4DpSjwRw= -github.com/pkg/xattr v0.4.1/go.mod h1:W2cGD0TBEus7MkUgv0tNZ9JutLtVO3cXu+IBRuHqnFs= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rfjakob/eme v1.1.1 h1:t+CgvcOn+eDvj2xdglxsSnkgg8LM8jwdxnV7OnsrTn0= -github.com/rfjakob/eme v1.1.1/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM= -github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0= -github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88= -golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181021155630-eda9bb28ed51/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/gocryptfs-xray/.gitignore b/gocryptfs-xray/.gitignore deleted file mode 100644 index bad094d..0000000 --- a/gocryptfs-xray/.gitignore +++ /dev/null @@ -1 +0,0 @@ -gocryptfs-xray diff --git a/gocryptfs-xray/paths_ctlsock.go b/gocryptfs-xray/paths_ctlsock.go deleted file mode 100644 index c489f0e..0000000 --- a/gocryptfs-xray/paths_ctlsock.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "os" - - "github.com/rfjakob/gocryptfs/ctlsock" -) - -func decryptPaths(socketPath string, sep0 bool) { - var req ctlsock.RequestStruct - transformPaths(socketPath, &req, &req.DecryptPath, sep0) -} - -func encryptPaths(socketPath string, sep0 bool) { - var req ctlsock.RequestStruct - transformPaths(socketPath, &req, &req.EncryptPath, sep0) -} - -func transformPaths(socketPath string, req *ctlsock.RequestStruct, in *string, sep0 bool) { - errorCount := 0 - c, err := ctlsock.New(socketPath) - if err != nil { - fmt.Printf("fatal: %v\n", err) - os.Exit(1) - } - line := 1 - var separator byte = '\n' - if sep0 { - separator = '\000' - } - r := bufio.NewReader(os.Stdin) - for eof := false; eof == false; line++ { - val, err := r.ReadBytes(separator) - if len(val) == 0 { - break - } - if err != nil { - // break the loop after we have processed the last val - eof = true - } else { - // drop trailing separator - val = val[:len(val)-1] - } - *in = string(val) - resp, err := c.Query(req) - if err != nil { - fmt.Fprintf(os.Stderr, "error at input line %d %q: %v\n", line, *in, err) - errorCount++ - continue - } - if resp.WarnText != "" { - fmt.Fprintf(os.Stderr, "warning at input line %d %q: %v\n", line, *in, resp.WarnText) - } - fmt.Printf("%s%c", resp.Result, separator) - } - if errorCount == 0 { - os.Exit(0) - } - os.Exit(1) -} diff --git a/gocryptfs-xray/xray_main.go b/gocryptfs-xray/xray_main.go deleted file mode 100644 index b99268b..0000000 --- a/gocryptfs-xray/xray_main.go +++ /dev/null @@ -1,205 +0,0 @@ -package main - -import ( - "encoding/hex" - "flag" - "fmt" - "io" - "os" - "runtime" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fido2" - "github.com/rfjakob/gocryptfs/internal/readpassword" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// GitVersion is the gocryptfs version according to git, set by build.bash -var GitVersion = "[GitVersion not set - please compile using ./build.bash]" - -// GitVersionFuse is the go-fuse library version, set by build.bash -var GitVersionFuse = "[GitVersionFuse not set - please compile using ./build.bash]" - -// BuildDate is a date string like "2017-09-06", set by build.bash -var BuildDate = "0000-00-00" - -const ( - ivLen = contentenc.DefaultIVBits / 8 - authTagLen = cryptocore.AuthTagLen - blockSize = contentenc.DefaultBS + ivLen + cryptocore.AuthTagLen - myName = "gocryptfs-xray" -) - -func errExit(err error) { - fmt.Println(err) - os.Exit(1) -} - -func prettyPrintHeader(h *contentenc.FileHeader, aessiv bool) { - id := hex.EncodeToString(h.ID) - msg := "Header: Version: %d, Id: %s" - if aessiv { - msg += ", assuming AES-SIV mode" - } else { - msg += ", assuming AES-GCM mode" - } - fmt.Printf(msg+"\n", h.Version, id) -} - -// printVersion prints a version string like this: -// gocryptfs v1.7-32-gcf99cfd; go-fuse v1.0.0-174-g22a9cb9; 2019-05-12 go1.12 linux/amd64 -func printVersion() { - built := fmt.Sprintf("%s %s", BuildDate, runtime.Version()) - fmt.Printf("%s %s; %s %s/%s\n", - myName, GitVersion, built, - runtime.GOOS, runtime.GOARCH) -} - -func usage() { - printVersion() - fmt.Printf("\n") - fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] FILE\n"+ - "\n"+ - "Options:\n", myName) - flag.PrintDefaults() - fmt.Fprintf(os.Stderr, "\n"+ - "Examples:\n"+ - " gocryptfs-xray myfs/mCXnISiv7nEmyc0glGuhTQ\n"+ - " gocryptfs-xray -dumpmasterkey myfs/gocryptfs.conf\n"+ - " gocryptfs-xray -encrypt-paths myfs.sock\n") -} - -// sum counts the number of true values -func sum(x ...*bool) (s int) { - for _, v := range x { - if *v { - s++ - } - } - return s -} - -func main() { - var args struct { - dumpmasterkey *bool - decryptPaths *bool - encryptPaths *bool - aessiv *bool - sep0 *bool - fido2 *string - version *bool - } - args.dumpmasterkey = flag.Bool("dumpmasterkey", false, "Decrypt and dump the master key") - args.decryptPaths = flag.Bool("decrypt-paths", false, "Decrypt file paths using gocryptfs control socket") - args.encryptPaths = flag.Bool("encrypt-paths", false, "Encrypt file paths using gocryptfs control socket") - args.sep0 = flag.Bool("0", false, "Use \\0 instead of \\n as separator") - args.aessiv = flag.Bool("aessiv", false, "Assume AES-SIV mode instead of AES-GCM") - args.fido2 = flag.String("fido2", "", "Protect the masterkey using a FIDO2 token instead of a password") - args.version = flag.Bool("version", false, "Print version information") - - flag.Usage = usage - flag.Parse() - - if *args.version { - printVersion() - os.Exit(0) - } - - s := sum(args.dumpmasterkey, args.decryptPaths, args.encryptPaths) - if s > 1 { - fmt.Printf("fatal: %d operations were requested\n", s) - os.Exit(1) - } - if flag.NArg() != 1 { - usage() - os.Exit(1) - } - fn := flag.Arg(0) - if *args.decryptPaths { - decryptPaths(fn, *args.sep0) - } - if *args.encryptPaths { - encryptPaths(fn, *args.sep0) - } - fd, err := os.Open(fn) - if err != nil { - errExit(err) - } - defer fd.Close() - if *args.dumpmasterkey { - dumpMasterKey(fn, *args.fido2) - } else { - inspectCiphertext(fd, *args.aessiv) - } -} - -func dumpMasterKey(fn string, fido2Path string) { - tlog.Info.Enabled = false - cf, err := configfile.Load(fn) - if err != nil { - fmt.Fprintln(os.Stderr, err) - exitcodes.Exit(err) - } - var pw []byte - if cf.IsFeatureFlagSet(configfile.FlagFIDO2) { - if fido2Path == "" { - tlog.Fatal.Printf("Masterkey encrypted using FIDO2 token; need to use the --fido2 option.") - os.Exit(exitcodes.Usage) - } - pw = fido2.Secret(fido2Path, cf.FIDO2.CredentialID, cf.FIDO2.HMACSalt) - } else { - pw = readpassword.Once(nil, nil, "") - } - masterkey, err := cf.DecryptMasterKey(pw) - fmt.Println(hex.EncodeToString(masterkey)) - for i := range pw { - pw[i] = 0 - } -} - -func inspectCiphertext(fd *os.File, aessiv bool) { - headerBytes := make([]byte, contentenc.HeaderLen) - n, err := fd.ReadAt(headerBytes, 0) - if err == io.EOF && n == 0 { - fmt.Println("empty file") - os.Exit(0) - } else if err == io.EOF { - fmt.Printf("incomplete file header: read %d bytes, want %d\n", n, contentenc.HeaderLen) - os.Exit(1) - } else if err != nil { - errExit(err) - } - header, err := contentenc.ParseHeader(headerBytes) - if err != nil { - errExit(err) - } - prettyPrintHeader(header, aessiv) - var i int64 - buf := make([]byte, blockSize) - for i = 0; ; i++ { - off := contentenc.HeaderLen + i*blockSize - n, err := fd.ReadAt(buf, off) - if err != nil && err != io.EOF { - errExit(err) - } - if n == 0 && err == io.EOF { - break - } - // A block contains at least the IV, the Auth Tag and 1 data byte - if n < ivLen+authTagLen+1 { - errExit(fmt.Errorf("corrupt block: truncated data, len=%d", n)) - } - data := buf[:n] - // Parse block data - iv := data[:ivLen] - tag := data[len(data)-authTagLen:] - if aessiv { - tag = data[ivLen : ivLen+authTagLen] - } - fmt.Printf("Block %2d: IV: %s, Tag: %s, Offset: %5d Len: %d\n", - i, hex.EncodeToString(iv), hex.EncodeToString(tag), off, len(data)) - } -} diff --git a/gocryptfs-xray/xray_tests/aesgcm_fs.masterkey.txt b/gocryptfs-xray/xray_tests/aesgcm_fs.masterkey.txt deleted file mode 100644 index 8c9cefb..0000000 --- a/gocryptfs-xray/xray_tests/aesgcm_fs.masterkey.txt +++ /dev/null @@ -1,4 +0,0 @@ -Your master key is: - - b4d8b25c-324dd6ea-a328c990-6e8a2a3c- - 6038552a-042ced43-26cfff21-0c62957a diff --git a/gocryptfs-xray/xray_tests/aesgcm_fs.xray.txt b/gocryptfs-xray/xray_tests/aesgcm_fs.xray.txt deleted file mode 100644 index c403b75..0000000 --- a/gocryptfs-xray/xray_tests/aesgcm_fs.xray.txt +++ /dev/null @@ -1,3 +0,0 @@ -Header: Version: 2, Id: 8932adf303fe0289679d47fa84d2b241, assuming AES-GCM mode -Block 0: IV: c8536b4bfd92f5dc3c1e2ac29f116d4a, Tag: 22b20422749b2f4bba67ec7d3bb1ac34, Offset: 18 Len: 4128 -Block 1: IV: 2de68f4965779bb137ef2b3c20453556, Tag: 3e8758d6872234b1fffab2504e623467, Offset: 4146 Len: 936 diff --git a/gocryptfs-xray/xray_tests/aesgcm_fs/VnvoeSetPaOFjZDaZAh0lA b/gocryptfs-xray/xray_tests/aesgcm_fs/VnvoeSetPaOFjZDaZAh0lA deleted file mode 100644 index 420c1c5..0000000 Binary files a/gocryptfs-xray/xray_tests/aesgcm_fs/VnvoeSetPaOFjZDaZAh0lA and /dev/null differ diff --git a/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.conf b/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.conf deleted file mode 100644 index f8f288b..0000000 --- a/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.conf +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Creator": "gocryptfs v1.7-beta1-11-g8d71f8f-dirty", - "EncryptedKey": "Rp0VYTJ9QK2imhJQH1miFIgAYZbsfv3t1tvPJvsOVy86ogBzKpUuMDFXD+PPawLvZM/TuYl0n3gx1RY5hzFfbg==", - "ScryptObject": { - "Salt": "mDPjzd+SZpScPYVv/M9AFjNzXcUy6fqKckXay53EQdQ=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64" - ] -} diff --git a/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.diriv b/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.diriv deleted file mode 100644 index c8d256f..0000000 --- a/gocryptfs-xray/xray_tests/aesgcm_fs/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -™˜:õjµ‹͉/î\W„ \ No newline at end of file diff --git a/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt b/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt deleted file mode 100644 index 42c5e23..0000000 --- a/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt +++ /dev/null @@ -1,4 +0,0 @@ -Your master key is: - - 83dfe2df-9f6ad754-179cb4d5-377a65dd- - bff54950-10e1b7b5-faf409e3-f7d8eeee diff --git a/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt b/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt deleted file mode 100644 index 37d6ebb..0000000 --- a/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt +++ /dev/null @@ -1,3 +0,0 @@ -Header: Version: 2, Id: d839806747918e345633fcdd0988e67c, assuming AES-SIV mode -Block 0: IV: 1d3ce2b13260f83766ccf9a670478a4b, Tag: 0b6f95bd523b4c93704e15ecc6bef8e7, Offset: 18 Len: 4128 -Block 1: IV: 7eb947d2adf18adf3bed39bbc8052968, Tag: 1a272903e5a987f53f07344840387c20, Offset: 4146 Len: 936 diff --git a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf deleted file mode 100644 index 31b565a..0000000 --- a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Creator": "gocryptfs v1.7-beta1-11-g8d71f8f-dirty", - "EncryptedKey": "YOxpZ+cImv4HirwuwIUpRmOMlyAFRvEqHOXdgpMcGvIlm70h4q+shSr3RZ19xomnbFZXGfIfKQ2APtVYWOAwuw==", - "ScryptObject": { - "Salt": "OzdcVESNmkD0403NHBWezQmq2SyDyLOY2/B4Aev2lHc=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64", - "AESSIV" - ] -} diff --git a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv deleted file mode 100644 index 18f75ca..0000000 --- a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -£_³5Òöªœpšº½… F \ No newline at end of file diff --git a/gocryptfs-xray/xray_tests/aessiv_fs/klepPXQJIaEDaIx-yurAqQ b/gocryptfs-xray/xray_tests/aessiv_fs/klepPXQJIaEDaIx-yurAqQ deleted file mode 100644 index b4674cc..0000000 Binary files a/gocryptfs-xray/xray_tests/aessiv_fs/klepPXQJIaEDaIx-yurAqQ and /dev/null differ diff --git a/gocryptfs-xray/xray_tests/xray_test.go b/gocryptfs-xray/xray_tests/xray_test.go deleted file mode 100644 index 790d2db..0000000 --- a/gocryptfs-xray/xray_tests/xray_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package xray_tests - -import ( - "bytes" - "fmt" - "io/ioutil" - "os/exec" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestAesgcmXray(t *testing.T) { - expected, err := ioutil.ReadFile("aesgcm_fs.xray.txt") - if err != nil { - t.Fatal(err) - } - cmd := exec.Command("../gocryptfs-xray", "aesgcm_fs/VnvoeSetPaOFjZDaZAh0lA") - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatal(err) - } - if bytes.Compare(out, expected) != 0 { - t.Errorf("Unexpected output") - fmt.Printf("expected:\n%s", string(expected)) - fmt.Printf("have:\n%s", string(out)) - } -} - -func TestAessivXray(t *testing.T) { - expected, err := ioutil.ReadFile("aessiv_fs.xray.txt") - if err != nil { - t.Fatal(err) - } - cmd := exec.Command("../gocryptfs-xray", "-aessiv", "aessiv_fs/klepPXQJIaEDaIx-yurAqQ") - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatal(err) - } - if bytes.Compare(out, expected) != 0 { - t.Errorf("Unexpected output") - fmt.Printf("expected:\n%s", string(expected)) - fmt.Printf("have:\n%s", string(out)) - } -} - -func TestDumpmasterkey(t *testing.T) { - expected := "b4d8b25c324dd6eaa328c9906e8a2a3c6038552a042ced4326cfff210c62957a\n" - cmd := exec.Command("../gocryptfs-xray", "-dumpmasterkey", "aesgcm_fs/gocryptfs.conf") - // Password = "test" - cmd.Stdin = bytes.NewBuffer([]byte("test")) - out1, err := cmd.CombinedOutput() - if err != nil { - t.Fatal(err) - } - out := string(out1) - if out != expected { - t.Errorf("Wrong output") - fmt.Printf("expected: %s\n", expected) - fmt.Printf("have: %s\n", out) - } -} - -func TestEncryptPaths(t *testing.T) { - cDir := test_helpers.InitFS(t) - pDir := cDir + ".mnt" - sock := cDir + ".sock" - test_helpers.MountOrFatal(t, cDir, pDir, "-ctlsock="+sock, "-extpass", "echo test") - defer test_helpers.UnmountPanic(pDir) - - testCases := []struct { - in []string - sep0 bool - }{ - { - []string{ - "test1", - "test1\n", - "test1\ntest2", - "test1\ntest2\n", - }, - false, - }, - { - []string{ - "test1", - "test1\000", - "test1\000test2", - "test1\000test2\000", - }, - true, - }, - } - - for _, tc := range testCases { - for _, in := range tc.in { - sepArg := "-0=false" - if tc.sep0 { - sepArg = "-0=true" - } - cmd := exec.Command("../gocryptfs-xray", "-encrypt-paths", sepArg, sock) - cmd.Stdin = bytes.NewBuffer([]byte(in)) - out, err := cmd.CombinedOutput() - t.Logf("%q", string(out)) - if err != nil { - t.Fatal(err) - } - } - } -} diff --git a/golint.bash b/golint.bash deleted file mode 100755 index d6fe729..0000000 --- a/golint.bash +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -u - -OUTPUT=$( - golint ./... | \ - grep -v "don't use an underscore in package name" | \ - grep -v "don't use ALL_CAPS in Go names; use CamelCase" | - grep -v "don't use underscores in Go names" -) - -# No output --> all good -if [[ -z $OUTPUT ]] ; then - exit 0 -fi - -echo "golint.bash:" -echo "$OUTPUT" -exit 1 diff --git a/help.go b/help.go deleted file mode 100644 index 5cd35ac..0000000 --- a/help.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -const tUsage = "" + - "Usage: " + tlog.ProgramName + " -init|-passwd|-info [OPTIONS] CIPHERDIR\n" + - " or " + tlog.ProgramName + " [OPTIONS] CIPHERDIR MOUNTPOINT\n" - -// helpShort is what gets displayed when passed "-h" or on syntax error. -func helpShort() { - printVersion() - fmt.Printf("\n") - fmt.Printf(tUsage) - fmt.Printf(` -Common Options (use -hh to show all): - -aessiv Use AES-SIV encryption (with -init) - -allow_other Allow other users to access the mount - -i, -idle Unmount automatically after specified idle duration - -config Custom path to config file - -ctlsock Create control socket at location - -extpass Call external program to prompt for the password - -fg Stay in the foreground - -fsck Check filesystem integrity - -fusedebug Debug FUSE calls - -h, -help This short help text - -hh Long help text with all options - -init Initialize encrypted directory - -info Display information about encrypted directory - -masterkey Mount with explicit master key instead of password - -nonempty Allow mounting over non-empty directory - -nosyslog Do not redirect log messages to syslog - -passfile Read password from plain text file(s) - -passwd Change password - -plaintextnames Do not encrypt file names (with -init) - -q, -quiet Silence informational messages - -reverse Enable reverse mode - -ro Mount read-only - -speed Run crypto speed test - -version Print version information - -- Stop option parsing -`) -} - -// helpLong gets only displayed on "-hh" -func helpLong() { - printVersion() - fmt.Printf("\n") - fmt.Printf(tUsage) - fmt.Printf("\nOptions:\n") - flagSet.PrintDefaults() - fmt.Printf(" --\n Stop option parsing\n") -} diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..3e1169b --- /dev/null +++ b/helpers.go @@ -0,0 +1,183 @@ +package main + +import ( + "path/filepath" + "strings" + "syscall" + + "./internal/configfile" + "./internal/nametransform" + "./internal/syscallcompat" +) + +// isFiltered - check if plaintext "path" should be forbidden +// +// Prevents name clashes with internal files when file names are not encrypted +func (volume *Volume) isFiltered(path string) bool { + if !volume.plainTextNames { + return false + } + // gocryptfs.conf in the root directory is forbidden + if path == configfile.ConfDefaultName { + return true + } + // Note: gocryptfs.diriv is NOT forbidden because diriv and plaintextnames + // are exclusive + return false +} + +func (volume *Volume) openBackingDir(relPath string) (dirfd int, cName string, err error) { + dirRelPath := nametransform.Dir(relPath) + // With PlaintextNames, we don't need to read DirIVs. Easy. + if volume.plainTextNames { + dirfd, err = syscallcompat.OpenDirNofollow(volume.rootCipherDir, dirRelPath) + if err != nil { + return -1, "", err + } + // If relPath is empty, cName is ".". + cName = filepath.Base(relPath) + return dirfd, cName, nil + } + // Open cipherdir (following symlinks) + dirfd, err = syscallcompat.Open(volume.rootCipherDir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) + if err != nil { + return -1, "", err + } + // If relPath is empty, cName is ".". + if relPath == "" { + return dirfd, ".", nil + } + // Walk the directory tree + parts := strings.Split(relPath, "/") + for i, name := range parts { + iv, err := nametransform.ReadDirIVAt(dirfd) + if err != nil { + syscall.Close(dirfd) + return -1, "", err + } + cName, err = volume.nameTransform.EncryptAndHashName(name, iv) + if err != nil { + syscall.Close(dirfd) + return -1, "", err + } + // Last part? We are done. + if i == len(parts)-1 { + break + } + // Not the last part? Descend into next directory. + dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) + syscall.Close(dirfd) + if err != nil { + return -1, "", err + } + dirfd = dirfd2 + } + return dirfd, cName, nil +} + +func (volume *Volume) prepareAtSyscall(path string) (dirfd int, cName string, err error) { + // root node itself is special + if path == "" { + return volume.openBackingDir(path) + } + + // Cache lookup + // TODO make it work for plaintextnames as well? + if !volume.plainTextNames { + directory, ok := volume.dirCache[path] + if ok { + if directory.fd > 0 { + cName, err := volume.nameTransform.EncryptAndHashName(filepath.Base(path), directory.iv) + if err != nil { + return -1, "", err + } + dirfd, err = syscall.Dup(directory.fd) + if err != nil { + return -1, "", err + } + return dirfd, cName, nil + } + } + } + + // Slowpath + if volume.isFiltered(path) { + return -1, "", syscall.EPERM + } + dirfd, cName, err = volume.openBackingDir(path) + if err != nil { + return -1, "", err + } + + // Cache store + if !volume.plainTextNames { + // TODO: openBackingDir already calls ReadDirIVAt(). Avoid duplicate work? + iv, err := nametransform.ReadDirIVAt(dirfd) + if err != nil { + syscall.Close(dirfd) + return -1, "", err + } + dirfdDup, err := syscall.Dup(dirfd) + if err == nil { + var pathCopy strings.Builder + pathCopy.WriteString(path) + volume.dirCache[pathCopy.String()] = Directory{dirfdDup, iv} + } + } + return +} + +// decryptSymlinkTarget: "cData64" is base64-decoded and decrypted +// like file contents (GCM). +// The empty string decrypts to the empty string. +// +// This function does not do any I/O and is hence symlink-safe. +func (volume *Volume) decryptSymlinkTarget(cData64 string) (string, error) { + if cData64 == "" { + return "", nil + } + cData, err := volume.nameTransform.B64DecodeString(cData64) + if err != nil { + return "", err + } + data, err := volume.contentEnc.DecryptBlock([]byte(cData), 0, nil) + if err != nil { + return "", err + } + return string(data), nil +} + +// readlink reads and decrypts a symlink. Used by Readlink, Getattr, Lookup. +func (volume *Volume) readlink(dirfd int, cName string) []byte { + cTarget, err := syscallcompat.Readlinkat(dirfd, cName) + if err != nil { + return nil + } + if volume.plainTextNames { + return []byte(cTarget) + } + // Symlinks are encrypted like file contents (GCM) and base64-encoded + target, err := volume.decryptSymlinkTarget(cTarget) + if err != nil { + return nil + } + return []byte(target) +} + +func isRegular(mode uint32) bool { return (mode & syscall.S_IFMT) == syscall.S_IFREG } + +func isSymlink(mode uint32) bool { return (mode & syscall.S_IFMT) == syscall.S_IFLNK } + +// translateSize translates the ciphertext size in `out` into plaintext size. +// Handles regular files & symlinks (and finds out what is what by looking at +// `out.Mode`). +func (volume *Volume) translateSize(dirfd int, cName string, st *syscall.Stat_t) uint64 { + var size uint64 + if isRegular(st.Mode) { + size = volume.contentEnc.CipherSizeToPlainSize(uint64(st.Size)) + } else if isSymlink(st.Mode) { + target := volume.readlink(dirfd, cName) + size = uint64(len(target)) + } + return size +} diff --git a/info.go b/info.go deleted file mode 100644 index bbc5a10..0000000 --- a/info.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "strings" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// info pretty-prints the contents of the config file at "filename" for human -// consumption, stripping out sensitive data. -// This is called when you pass the "-info" option. -func info(filename string) { - // Read from disk - js, err := ioutil.ReadFile(filename) - if err != nil { - tlog.Fatal.Printf("Reading config file failed: %v", err) - os.Exit(exitcodes.LoadConf) - } - // Unmarshal - var cf configfile.ConfFile - err = json.Unmarshal(js, &cf) - if err != nil { - tlog.Fatal.Printf("Failed to unmarshal config file") - os.Exit(exitcodes.LoadConf) - } - if cf.Version != contentenc.CurrentVersion { - tlog.Fatal.Printf("Unsupported on-disk format %d", cf.Version) - os.Exit(exitcodes.LoadConf) - } - // Pretty-print - fmt.Printf("Creator: %s\n", cf.Creator) - fmt.Printf("FeatureFlags: %s\n", strings.Join(cf.FeatureFlags, " ")) - fmt.Printf("EncryptedKey: %dB\n", len(cf.EncryptedKey)) - s := cf.ScryptObject - fmt.Printf("ScryptObject: Salt=%dB N=%d R=%d P=%d KeyLen=%d\n", - len(s.Salt), s.N, s.R, s.P, s.KeyLen) -} diff --git a/init_dir.go b/init_dir.go deleted file mode 100644 index 68268a0..0000000 --- a/init_dir.go +++ /dev/null @@ -1,134 +0,0 @@ -package main - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fido2" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/readpassword" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// isEmptyDir checks if "dir" exists and is an empty directory. -// Returns an *os.PathError if Stat() on the path fails. -func isEmptyDir(dir string) error { - err := isDir(dir) - if err != nil { - return err - } - entries, err := ioutil.ReadDir(dir) - if err != nil { - return err - } - if len(entries) == 0 { - return nil - } - return fmt.Errorf("directory %s not empty", dir) -} - -// isDir checks if "dir" exists and is a directory. -func isDir(dir string) error { - fi, err := os.Stat(dir) - if err != nil { - return err - } - if !fi.IsDir() { - return fmt.Errorf("%s is not a directory", dir) - } - return nil -} - -// initDir handles "gocryptfs -init". It prepares a directory for use as a -// gocryptfs storage directory. -// In forward mode, this means creating the gocryptfs.conf and gocryptfs.diriv -// files in an empty directory. -// In reverse mode, we create .gocryptfs.reverse.conf and the directory does -// not need to be empty. -func initDir(args *argContainer) { - var err error - if args.reverse { - _, err = os.Stat(args.config) - if err == nil { - tlog.Fatal.Printf("Config file %q already exists", args.config) - os.Exit(exitcodes.Init) - } - } else { - err = isEmptyDir(args.cipherdir) - if err != nil { - tlog.Fatal.Printf("Invalid cipherdir: %v", err) - os.Exit(exitcodes.CipherDir) - } - } - // Choose password for config file - if args.extpass.Empty() && args.fido2 == "" { - tlog.Info.Printf("Choose a password for protecting your files.") - } - { - var password []byte - var fido2CredentialID, fido2HmacSalt []byte - if args.fido2 != "" { - fido2CredentialID = fido2.Register(args.fido2, filepath.Base(args.cipherdir)) - fido2HmacSalt = cryptocore.RandBytes(32) - password = fido2.Secret(args.fido2, fido2CredentialID, fido2HmacSalt) - } else { - // normal password entry - password = readpassword.Twice([]string(args.extpass), []string(args.passfile)) - fido2CredentialID = nil - fido2HmacSalt = nil - } - creator := tlog.ProgramName + " " + GitVersion - err = configfile.Create(args.config, password, args.plaintextnames, - args.scryptn, creator, args.aessiv, args.devrandom, fido2CredentialID, fido2HmacSalt) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.WriteConf) - } - for i := range password { - password[i] = 0 - } - // password runs out of scope here - } - // Forward mode with filename encryption enabled needs a gocryptfs.diriv file - // in the root dir - if !args.plaintextnames && !args.reverse { - // Open cipherdir (following symlinks) - dirfd, err := syscall.Open(args.cipherdir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) - if err == nil { - err = nametransform.WriteDirIVAt(dirfd) - syscall.Close(dirfd) - } - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Init) - } - } - mountArgs := "" - fsName := "gocryptfs" - if args.reverse { - mountArgs = " -reverse" - fsName = "gocryptfs-reverse" - } - tlog.Info.Printf(tlog.ColorGreen+"The %s filesystem has been created successfully."+tlog.ColorReset, - fsName) - wd, _ := os.Getwd() - friendlyPath, _ := filepath.Rel(wd, args.cipherdir) - if strings.HasPrefix(friendlyPath, "../") { - // A relative path that starts with "../" is pretty unfriendly, just - // keep the absolute path. - friendlyPath = args.cipherdir - } - if strings.Contains(friendlyPath, " ") { - friendlyPath = "\"" + friendlyPath + "\"" - } - tlog.Info.Printf(tlog.ColorGrey+"You can now mount it using: %s%s %s MOUNTPOINT"+tlog.ColorReset, - tlog.ProgramName, mountArgs, friendlyPath) -} diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index e4921f7..089af07 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -12,10 +12,9 @@ import ( "os" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../contentenc" + "../cryptocore" + "../exitcodes" ) const ( @@ -113,11 +112,10 @@ func Create(filename string, password []byte, plaintextNames bool, } else { key = cryptocore.RandBytes(cryptocore.KeyLen) } - tlog.PrintMasterkeyReminder(key) // Encrypt it using the password // This sets ScryptObject and EncryptedKey // Note: this looks at the FeatureFlags, so call it AFTER setting them. - cf.EncryptKey(key, password, logN) + cf.EncryptKey(key, password, logN, false) for i := range key { key[i] = 0 } @@ -147,7 +145,7 @@ func LoadAndDecrypt(filename string, password []byte) ([]byte, *ConfFile, error) } // Decrypt the masterkey using the password - key, err := cf.DecryptMasterKey(password) + key, _, err := cf.DecryptMasterKey(password, false) if err != nil { return nil, nil, err } @@ -172,7 +170,6 @@ func Load(filename string) (*ConfFile, error) { // Unmarshal err = json.Unmarshal(js, &cf) if err != nil { - tlog.Warn.Printf("Failed to unmarshal config file") return nil, err } @@ -202,17 +199,6 @@ func Load(filename string) (*ConfFile, error) { } } if deprecatedFs { - fmt.Fprintf(os.Stderr, tlog.ColorYellow+` - The filesystem was created by gocryptfs v0.6 or earlier. This version of - gocryptfs can no longer mount the filesystem. - Please download gocryptfs v0.11 and upgrade your filesystem, - see https://github.com/rfjakob/gocryptfs/wiki/Upgrading for instructions. - - If you have trouble upgrading, join the discussion at - https://github.com/rfjakob/gocryptfs/issues/29 . - -`+tlog.ColorReset) - return nil, exitcodes.NewErr("Deprecated filesystem", exitcodes.DeprecatedFS) } @@ -222,38 +208,38 @@ func Load(filename string) (*ConfFile, error) { // DecryptMasterKey decrypts the masterkey stored in cf.EncryptedKey using // password. -func (cf *ConfFile) DecryptMasterKey(password []byte) (masterkey []byte, err error) { +func (cf *ConfFile) DecryptMasterKey(password []byte, giveHash bool) (masterkey, scryptHash []byte, err error) { // Generate derived key from password - scryptHash := cf.ScryptObject.DeriveKey(password) + scryptHash = cf.ScryptObject.DeriveKey(password) // Unlock master key using password-based key useHKDF := cf.IsFeatureFlagSet(FlagHKDF) ce := getKeyEncrypter(scryptHash, useHKDF) - tlog.Warn.Enabled = false // Silence DecryptBlock() error messages on incorrect password masterkey, err = ce.DecryptBlock(cf.EncryptedKey, 0, nil) - tlog.Warn.Enabled = true - // Purge scrypt-derived key - for i := range scryptHash { - scryptHash[i] = 0 + if !giveHash { + // Purge scrypt-derived key + for i := range scryptHash { + scryptHash[i] = 0 + } + scryptHash = nil } - scryptHash = nil ce.Wipe() ce = nil if err != nil { - tlog.Warn.Printf("failed to unlock master key: %s", err.Error()) - return nil, exitcodes.NewErr("Password incorrect.", exitcodes.PasswordIncorrect) + return nil, nil, exitcodes.NewErr("Password incorrect.", exitcodes.PasswordIncorrect) } - return masterkey, nil + + return masterkey, scryptHash, nil } // EncryptKey - encrypt "key" using an scrypt hash generated from "password" // and store it in cf.EncryptedKey. // Uses scrypt with cost parameter logN and stores the scrypt parameters in // cf.ScryptObject. -func (cf *ConfFile) EncryptKey(key []byte, password []byte, logN int) { +func (cf *ConfFile) EncryptKey(key []byte, password []byte, logN int, giveHash bool) []byte { // Generate scrypt-derived key from password cf.ScryptObject = NewScryptKDF(logN) scryptHash := cf.ScryptObject.DeriveKey(password) @@ -263,13 +249,45 @@ func (cf *ConfFile) EncryptKey(key []byte, password []byte, logN int) { ce := getKeyEncrypter(scryptHash, useHKDF) cf.EncryptedKey = ce.EncryptBlock(key, 0, nil) - // Purge scrypt-derived key - for i := range scryptHash { - scryptHash[i] = 0 + if !giveHash { + // Purge scrypt-derived key + for i := range scryptHash { + scryptHash[i] = 0 + } + scryptHash = nil } - scryptHash = nil ce.Wipe() ce = nil + + return scryptHash +} + +// DroidFS function to allow masterkey to be decrypted directely using the scrypt hash and return it if requested +func (cf *ConfFile) GetMasterkey(password, givenScryptHash, returnedScryptHashBuff []byte) []byte { + var masterkey []byte + var err error + var scryptHash []byte + if len(givenScryptHash) > 0 { //decrypt with hash + useHKDF := cf.IsFeatureFlagSet(FlagHKDF) + ce := getKeyEncrypter(givenScryptHash, useHKDF) + masterkey, err = ce.DecryptBlock(cf.EncryptedKey, 0, nil) + ce.Wipe() + ce = nil + if err == nil { + return masterkey + } + } else { //decrypt with password + masterkey, scryptHash, err = cf.DecryptMasterKey(password, len(returnedScryptHashBuff) > 0) + //copy and wipe scryptHash + for i := range scryptHash { + returnedScryptHashBuff[i] = scryptHash[i] + scryptHash[i] = 0 + } + if err == nil { + return masterkey + } + } + return nil } // WriteFile - write out config in JSON format to file "filename.tmp" @@ -296,7 +314,6 @@ func (cf *ConfFile) WriteFile() error { if err != nil { // This can happen on network drives: FRITZ.NAS mounted on MacOS returns // "operation not supported": https://github.com/rfjakob/gocryptfs/issues/390 - tlog.Warn.Printf("Warning: fsync failed: %v", err) // Try sync instead syscall.Sync() } diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go deleted file mode 100644 index ce35531..0000000 --- a/internal/configfile/config_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package configfile - -import ( - "fmt" - "testing" - "time" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -var testPw = []byte("test") - -func TestLoadV1(t *testing.T) { - _, _, err := LoadAndDecrypt("config_test/v1.conf", testPw) - if err == nil { - t.Errorf("Outdated v1 config file must fail to load but it didn't") - } else if testing.Verbose() { - fmt.Println(err) - } -} - -// Load a known-good config file and verify that it takes at least 100ms -// (brute-force protection) -func TestLoadV2(t *testing.T) { - t1 := time.Now() - - _, _, err := LoadAndDecrypt("config_test/v2.conf", testPw) - if err != nil { - t.Errorf("Could not load v2 config file: %v", err) - } - - elapsed := time.Since(t1) - if elapsed < 100*time.Millisecond { - t.Errorf("scrypt calculation runs too fast: %d ms", elapsed/time.Millisecond) - } -} - -func TestLoadV2PwdError(t *testing.T) { - if !testing.Verbose() { - tlog.Warn.Enabled = false - } - _, _, err := LoadAndDecrypt("config_test/v2.conf", []byte("wrongpassword")) - if err == nil { - t.Errorf("Loading with wrong password must fail but it didn't") - } -} - -func TestLoadV2Feature(t *testing.T) { - _, _, err := LoadAndDecrypt("config_test/PlaintextNames.conf", testPw) - if err != nil { - t.Errorf("Could not load v2 PlaintextNames config file: %v", err) - } -} - -func TestLoadV2StrangeFeature(t *testing.T) { - _, _, err := LoadAndDecrypt("config_test/StrangeFeature.conf", testPw) - if err == nil { - t.Errorf("Loading unknown feature must fail but it didn't") - } else if testing.Verbose() { - fmt.Println(err) - } -} - -func TestCreateConfDefault(t *testing.T) { - err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false, nil, nil) - if err != nil { - t.Fatal(err) - } - _, c, err := LoadAndDecrypt("config_test/tmp.conf", testPw) - if err != nil { - t.Fatal(err) - } - // Check that all expected feature flags are set - want := []flagIota{ - FlagGCMIV128, FlagDirIV, FlagEMENames, FlagLongNames, - FlagRaw64, FlagHKDF, - } - for _, f := range want { - if !c.IsFeatureFlagSet(f) { - t.Errorf("Feature flag %q should be set but is not", knownFlags[f]) - } - } -} - -func TestCreateConfDevRandom(t *testing.T) { - err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true, nil, nil) - if err != nil { - t.Fatal(err) - } -} - -func TestCreateConfPlaintextnames(t *testing.T) { - err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, nil, nil) - if err != nil { - t.Fatal(err) - } - _, c, err := LoadAndDecrypt("config_test/tmp.conf", testPw) - if err != nil { - t.Fatal(err) - } - // Check that all expected feature flags are set - want := []flagIota{ - FlagGCMIV128, FlagHKDF, - } - for _, f := range want { - if !c.IsFeatureFlagSet(f) { - t.Errorf("Feature flag %q should be set but is not", knownFlags[f]) - } - } -} - -// Reverse mode uses AESSIV -func TestCreateConfFileAESSIV(t *testing.T) { - err := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false, nil, nil) - if err != nil { - t.Fatal(err) - } - _, c, err := LoadAndDecrypt("config_test/tmp.conf", testPw) - if err != nil { - t.Fatal(err) - } - if !c.IsFeatureFlagSet(FlagAESSIV) { - t.Error("AESSIV flag should be set but is not") - } -} - -func TestIsFeatureFlagKnown(t *testing.T) { - // Test a few hardcoded values - testKnownFlags := []string{"DirIV", "PlaintextNames", "EMENames", "GCMIV128", "LongNames", "AESSIV"} - // And also everything in knownFlags (yes, it is likely that we end up with - // some duplicates. Does not matter.) - for _, f := range knownFlags { - testKnownFlags = append(testKnownFlags, f) - } - - var cf ConfFile - for _, f := range testKnownFlags { - if !cf.isFeatureFlagKnown(f) { - t.Errorf("flag %q should be known", f) - } - } - - f := "StrangeFeatureFlag" - if cf.isFeatureFlagKnown(f) { - t.Errorf("flag %q should be NOT known", f) - } -} diff --git a/internal/configfile/config_test/.gitignore b/internal/configfile/config_test/.gitignore deleted file mode 100644 index 0720169..0000000 --- a/internal/configfile/config_test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tmp.conf diff --git a/internal/configfile/config_test/PlaintextNames.conf b/internal/configfile/config_test/PlaintextNames.conf deleted file mode 100644 index 5b9f4f7..0000000 --- a/internal/configfile/config_test/PlaintextNames.conf +++ /dev/null @@ -1,16 +0,0 @@ -{ - "Creator": "gocryptfs v0.11-13-g96750a7-dirty", - "EncryptedKey": "pH6/kgPFrwkuFW/HDN/0UzwC8hLJCMm/upyEnsR1pVTfSJLL/JxfBaVCRyuZhc/S7h2PrxVSMO1xzLrk", - "ScryptObject": { - "Salt": "Hq0BqXXeMGVGfdYE1Y/qcW+pvxJBJymRAVgPUxQiZ8Y=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "PlaintextNames" - ] -} \ No newline at end of file diff --git a/internal/configfile/config_test/StrangeFeature.conf b/internal/configfile/config_test/StrangeFeature.conf deleted file mode 100644 index eadf168..0000000 --- a/internal/configfile/config_test/StrangeFeature.conf +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Creator": "gocryptfs v0.11-13-g96750a7-dirty", - "EncryptedKey": "mfN2FITcsLE+8QlpTb3r/D5rAAqEX5mJQuU655tcdwAotUwHkrIdYiKa2BjoocctQC0grwqPyuWxB7SH", - "ScryptObject": { - "Salt": "9G2knR016guT/AJqOKemjusYhqg+mI177Dz6a5RS7ts=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames", - "StrangeFeatureFlag" - ] -} diff --git a/internal/configfile/config_test/v1.conf b/internal/configfile/config_test/v1.conf deleted file mode 100644 index 588a25a..0000000 --- a/internal/configfile/config_test/v1.conf +++ /dev/null @@ -1,11 +0,0 @@ -{ - "EncryptedKey": "t6YAvFQJvbv46c93bHQ5IZnvNz80DA9cohGoSPL/2M257LuIigow6jbr8b9HhnbDqHTCcz7aKkMDzneF", - "ScryptObject": { - "Salt": "yT4yQmmRmVNx2P0tJrUswk5SQzZaL6Z8kUteAoNJkXM=", - "N": 65536, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 1 -} diff --git a/internal/configfile/config_test/v2.conf b/internal/configfile/config_test/v2.conf deleted file mode 100644 index d1ca609..0000000 --- a/internal/configfile/config_test/v2.conf +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Creator": "gocryptfs v0.11-13-g96750a7-dirty", - "EncryptedKey": "zY06x2JS0Fi7bkZ/3DppjmWZOI6xTjQ/Bf4Nru1rUzHml+stkAtvcoHT8PpHN4eKqL73ymQ86MmdYz+1", - "ScryptObject": { - "Salt": "U5MbvyTmwhEkLqe6XxlrONzPZEf2GLFZCAIixz2Kal0=", - "N": 65536, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames" - ] -} \ No newline at end of file diff --git a/internal/configfile/scrypt.go b/internal/configfile/scrypt.go index 54fe0c6..c1edf4b 100644 --- a/internal/configfile/scrypt.go +++ b/internal/configfile/scrypt.go @@ -7,9 +7,8 @@ import ( "golang.org/x/crypto/scrypt" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../cryptocore" + "../exitcodes" ) const ( @@ -84,23 +83,18 @@ func (s *ScryptKDF) LogN() int { func (s *ScryptKDF) validateParams() { minN := 1 << scryptMinLogN if s.N < minN { - tlog.Fatal.Println("Fatal: scryptn below 10 is too low to make sense") os.Exit(exitcodes.ScryptParams) } if s.R < scryptMinR { - tlog.Fatal.Printf("Fatal: scrypt parameter R below minimum: value=%d, min=%d", s.R, scryptMinR) os.Exit(exitcodes.ScryptParams) } if s.P < scryptMinP { - tlog.Fatal.Printf("Fatal: scrypt parameter P below minimum: value=%d, min=%d", s.P, scryptMinP) os.Exit(exitcodes.ScryptParams) } if len(s.Salt) < scryptMinSaltLen { - tlog.Fatal.Printf("Fatal: scrypt salt length below minimum: value=%d, min=%d", len(s.Salt), scryptMinSaltLen) os.Exit(exitcodes.ScryptParams) } if s.KeyLen < cryptocore.KeyLen { - tlog.Fatal.Printf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", s.KeyLen, cryptocore.KeyLen) os.Exit(exitcodes.ScryptParams) } } diff --git a/internal/configfile/scrypt_test.go b/internal/configfile/scrypt_test.go deleted file mode 100644 index 8f7a5c8..0000000 --- a/internal/configfile/scrypt_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package configfile - -import ( - "testing" -) - -/* -Results on a 2.7GHz Pentium G630: - -gocryptfs/cryptfs$ go test -bench=. -PASS -BenchmarkScrypt10-2 300 6021435 ns/op ... 6ms -BenchmarkScrypt11-2 100 11861460 ns/op -BenchmarkScrypt12-2 100 23420822 ns/op -BenchmarkScrypt13-2 30 47666518 ns/op -BenchmarkScrypt14-2 20 92561590 ns/op ... 92ms -BenchmarkScrypt15-2 10 183971593 ns/op -BenchmarkScrypt16-2 3 368506365 ns/op -BenchmarkScrypt17-2 2 755502608 ns/op ... 755ms -ok github.com/rfjakob/gocryptfs/cryptfs 18.772s -*/ - -func benchmarkScryptN(n int, b *testing.B) { - kdf := NewScryptKDF(n) - for i := 0; i < b.N; i++ { - kdf.DeriveKey(testPw) - } -} - -func BenchmarkScrypt10(b *testing.B) { - benchmarkScryptN(10, b) -} - -func BenchmarkScrypt11(b *testing.B) { - benchmarkScryptN(11, b) -} - -func BenchmarkScrypt12(b *testing.B) { - benchmarkScryptN(12, b) -} - -func BenchmarkScrypt13(b *testing.B) { - benchmarkScryptN(13, b) -} - -func BenchmarkScrypt14(b *testing.B) { - benchmarkScryptN(14, b) -} - -func BenchmarkScrypt15(b *testing.B) { - benchmarkScryptN(15, b) -} - -func BenchmarkScrypt16(b *testing.B) { - benchmarkScryptN(16, b) -} - -func BenchmarkScrypt17(b *testing.B) { - benchmarkScryptN(17, b) -} diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go index 747bb4c..c9b3c60 100644 --- a/internal/contentenc/content.go +++ b/internal/contentenc/content.go @@ -4,23 +4,22 @@ package contentenc import ( "bytes" "encoding/binary" - "encoding/hex" "errors" "log" "runtime" "sync" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../cryptocore" + "../stupidgcm" ) // NonceMode determines how nonces are created. type NonceMode int const ( + //value from FUSE doc + MAX_KERNEL_WRITE = 128 * 1024 + // DefaultBS is the default plaintext block size DefaultBS = 4096 // DefaultIVBits is the default length of IV, in bits. @@ -73,17 +72,17 @@ type ContentEnc struct { // New returns an initialized ContentEnc instance. func New(cc *cryptocore.CryptoCore, plainBS uint64, forceDecode bool) *ContentEnc { - if fuse.MAX_KERNEL_WRITE%plainBS != 0 { - log.Panicf("unaligned MAX_KERNEL_WRITE=%d", fuse.MAX_KERNEL_WRITE) + if MAX_KERNEL_WRITE%plainBS != 0 { + log.Panicf("unaligned MAX_KERNEL_WRITE=%d", MAX_KERNEL_WRITE) } cipherBS := plainBS + uint64(cc.IVLen) + cryptocore.AuthTagLen // Take IV and GHASH overhead into account. - cReqSize := int(fuse.MAX_KERNEL_WRITE / plainBS * cipherBS) + cReqSize := int(MAX_KERNEL_WRITE / plainBS * cipherBS) // Unaligned reads (happens during fsck, could also happen with O_DIRECT?) // touch one additional ciphertext and plaintext block. Reserve space for the // extra block. cReqSize += int(cipherBS) - pReqSize := fuse.MAX_KERNEL_WRITE + int(plainBS) + pReqSize := MAX_KERNEL_WRITE + int(plainBS) c := &ContentEnc{ cryptoCore: cc, plainBS: plainBS, @@ -120,9 +119,7 @@ func (be *ContentEnc) DecryptBlocks(ciphertext []byte, firstBlockNo uint64, file var pBlock []byte pBlock, err = be.DecryptBlock(cBlock, blockNo, fileID) if err != nil { - if be.forceDecode && err == stupidgcm.ErrAuth { - tlog.Warn.Printf("DecryptBlocks: authentication failure in block #%d, overridden by forcedecode", firstBlockNo) - } else { + if !(be.forceDecode && err == stupidgcm.ErrAuth) { break } } @@ -163,12 +160,10 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b // All-zero block? if bytes.Equal(ciphertext, be.allZeroBlock) { - tlog.Debug.Printf("DecryptBlock: file hole encountered") return make([]byte, be.plainBS), nil } if len(ciphertext) < be.cryptoCore.IVLen { - tlog.Warn.Printf("DecryptBlock: Block is too short: %d bytes", len(ciphertext)) return nil, errors.New("Block is too short") } @@ -180,7 +175,6 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b // http://www.spinics.net/lists/kernel/msg2370127.html return nil, errors.New("all-zero nonce") } - ciphertextOrig := ciphertext ciphertext = ciphertext[be.cryptoCore.IVLen:] // Decrypt @@ -190,8 +184,6 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b plaintext, err := be.cryptoCore.AEADCipher.Open(plaintext, nonce, ciphertext, aData) if err != nil { - tlog.Debug.Printf("DecryptBlock: %s, len=%d", err.Error(), len(ciphertextOrig)) - tlog.Debug.Println(hex.Dump(ciphertextOrig)) if be.forceDecode && err == stupidgcm.ErrAuth { return plaintext, err } diff --git a/internal/contentenc/content_test.go b/internal/contentenc/content_test.go deleted file mode 100644 index 998e9b8..0000000 --- a/internal/contentenc/content_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package contentenc - -import ( - "testing" - - "github.com/rfjakob/gocryptfs/internal/cryptocore" -) - -type testRange struct { - offset uint64 - length uint64 -} - -func TestSplitRange(t *testing.T) { - var ranges []testRange - - ranges = append(ranges, testRange{0, 70000}, - testRange{0, 10}, - testRange{234, 6511}, - testRange{65444, 54}, - testRange{0, 1024 * 1024}, - testRange{0, 65536}, - testRange{6654, 8945}) - - key := make([]byte, cryptocore.KeyLen) - cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true, false) - f := New(cc, DefaultBS, false) - - for _, r := range ranges { - parts := f.ExplodePlainRange(r.offset, r.length) - var lastBlockNo uint64 = 1 << 63 - for _, p := range parts { - if p.BlockNo == lastBlockNo { - t.Errorf("Duplicate block number %d", p.BlockNo) - } - lastBlockNo = p.BlockNo - if p.Length > DefaultBS || p.Skip >= DefaultBS { - t.Errorf("Test fail: n=%d, length=%d, offset=%d\n", p.BlockNo, p.Length, p.Skip) - } - } - } -} - -func TestCiphertextRange(t *testing.T) { - var ranges []testRange - - ranges = append(ranges, testRange{0, 70000}, - testRange{0, 10}, - testRange{234, 6511}, - testRange{65444, 54}, - testRange{6654, 8945}) - - key := make([]byte, cryptocore.KeyLen) - cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true, false) - f := New(cc, DefaultBS, false) - - for _, r := range ranges { - - blocks := f.ExplodePlainRange(r.offset, r.length) - alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks) - skipBytes := blocks[0].Skip - - if alignedLength < r.length { - t.Errorf("alignedLength=%d is smaller than length=%d", alignedLength, r.length) - } - if (alignedOffset-HeaderLen)%f.cipherBS != 0 { - t.Errorf("alignedOffset=%d is not aligned", alignedOffset) - } - if r.offset%f.plainBS != 0 && skipBytes == 0 { - t.Errorf("skipBytes=0") - } - } -} - -func TestBlockNo(t *testing.T) { - key := make([]byte, cryptocore.KeyLen) - cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true, false) - f := New(cc, DefaultBS, false) - - b := f.CipherOffToBlockNo(788) - if b != 0 { - t.Errorf("actual: %d", b) - } - b = f.CipherOffToBlockNo(HeaderLen + f.cipherBS) - if b != 1 { - t.Errorf("actual: %d", b) - } - b = f.PlainOffToBlockNo(788) - if b != 0 { - t.Errorf("actual: %d", b) - } - b = f.PlainOffToBlockNo(f.plainBS) - if b != 1 { - t.Errorf("actual: %d", b) - } -} diff --git a/internal/contentenc/file_header.go b/internal/contentenc/file_header.go index 6ce2e3b..921e835 100644 --- a/internal/contentenc/file_header.go +++ b/internal/contentenc/file_header.go @@ -11,7 +11,7 @@ import ( "fmt" "log" - "github.com/rfjakob/gocryptfs/internal/cryptocore" + "../cryptocore" ) const ( diff --git a/internal/contentenc/offsets.go b/internal/contentenc/offsets.go index 3a0abf3..1f0a70c 100644 --- a/internal/contentenc/offsets.go +++ b/internal/contentenc/offsets.go @@ -2,8 +2,6 @@ package contentenc import ( "log" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) // Contentenc methods that translate offsets between ciphertext and plaintext @@ -44,12 +42,10 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 { if cipherSize == HeaderLen { // This can happen between createHeader() and Write() and is harmless. - tlog.Debug.Printf("cipherSize %d == header size: interrupted write?\n", cipherSize) return 0 } if cipherSize < HeaderLen { - tlog.Warn.Printf("cipherSize %d < header size %d: corrupt file\n", cipherSize, HeaderLen) return 0 } @@ -58,7 +54,6 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 { lastBlockSize := (cipherSize - HeaderLen) % be.cipherBS if lastBlockSize > 0 && lastBlockSize <= be.BlockOverhead() { tmp := cipherSize - lastBlockSize + be.BlockOverhead() + 1 - tlog.Warn.Printf("cipherSize %d: incomplete last block (%d bytes), padding to %d bytes", cipherSize, lastBlockSize, tmp) cipherSize = tmp } @@ -69,7 +64,6 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 { overhead := be.BlockOverhead()*blockCount + HeaderLen if overhead > cipherSize { - tlog.Warn.Printf("cipherSize %d < overhead %d: corrupt file\n", cipherSize, overhead) return 0 } diff --git a/internal/contentenc/offsets_test.go b/internal/contentenc/offsets_test.go deleted file mode 100644 index c3b8fcd..0000000 --- a/internal/contentenc/offsets_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package contentenc - -import ( - "fmt" - "testing" - - "github.com/rfjakob/gocryptfs/internal/cryptocore" -) - -// TestSizeToSize tests CipherSizeToPlainSize and PlainSizeToCipherSize -func TestSizeToSize(t *testing.T) { - key := make([]byte, cryptocore.KeyLen) - cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true, false) - ce := New(cc, DefaultBS, false) - - const rangeMax = 10000 - - // y values in this order: - // 0 ... CipherSizeToPlainSize - // 1 ... PlainSizeToCipherSize - // 2 ... PlainOffToCipherOff - var yTable [rangeMax][3]uint64 - - // Calculate values - for x := range yTable { - yTable[x][0] = ce.CipherSizeToPlainSize(uint64(x)) - yTable[x][1] = ce.PlainSizeToCipherSize(uint64(x)) - yTable[x][2] = ce.PlainOffToCipherOff(uint64(x)) - } - - // Print data table - fmt.Print("x\tCipherSizeToPlainSize\tPlainSizeToCipherSize\tPlainOffToCipherOff\n") - for x := range yTable { - if x > 1 && x < rangeMax-1 { - // If the point before has value-1 and the point after has value+1, - // it is not interesting. Don't print it out. - interesting := false - for i := 0; i <= 2; i++ { - if yTable[x-1][i]+1 != yTable[x][i] && yTable[x][i]+1 != yTable[x+1][i]+1 { - interesting = true - } - // Monotonicity check - if yTable[x][i] < yTable[x-1][i] { - t.Errorf("column %d is non-monotonic!", i) - } - } - if !interesting { - continue - } - } - fmt.Printf("%d\t%d\t%d\t%d\n", x, yTable[x][0], yTable[x][1], yTable[x][2]) - } -} diff --git a/internal/cryptocore/cryptocore.go b/internal/cryptocore/cryptocore.go index d66f390..8ea11d4 100644 --- a/internal/cryptocore/cryptocore.go +++ b/internal/cryptocore/cryptocore.go @@ -12,9 +12,8 @@ import ( "github.com/rfjakob/eme" - "github.com/rfjakob/gocryptfs/internal/siv_aead" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../siv_aead" + "../stupidgcm" ) const ( @@ -157,13 +156,10 @@ type wiper interface { func (c *CryptoCore) Wipe() { be := c.AEADBackend if be == BackendOpenSSL || be == BackendAESSIV { - tlog.Debug.Printf("CryptoCore.Wipe: Wiping AEADBackend %d key", be) // We don't use "x, ok :=" because we *want* to crash loudly if the // type assertion fails. w := c.AEADCipher.(wiper) w.Wipe() - } else { - tlog.Debug.Printf("CryptoCore.Wipe: Only nil'ing stdlib refs") } // We have no access to the keys (or key-equivalents) stored inside the // Go stdlib. Best we can is to nil the references and force a GC. diff --git a/internal/cryptocore/cryptocore_test.go b/internal/cryptocore/cryptocore_test.go deleted file mode 100644 index e595ef6..0000000 --- a/internal/cryptocore/cryptocore_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package cryptocore - -import ( - "testing" - - "github.com/rfjakob/gocryptfs/internal/stupidgcm" -) - -// "New" should accept at least these param combinations -func TestCryptoCoreNew(t *testing.T) { - key := make([]byte, 32) - for _, useHKDF := range []bool{true, false} { - c := New(key, BackendGoGCM, 96, useHKDF, false) - if c.IVLen != 12 { - t.Fail() - } - c = New(key, BackendGoGCM, 128, useHKDF, false) - if c.IVLen != 16 { - t.Fail() - } - if stupidgcm.BuiltWithoutOpenssl { - continue - } - c = New(key, BackendOpenSSL, 128, useHKDF, false) - if c.IVLen != 16 { - t.Fail() - } - } -} - -// "New" should panic on any key not 32 bytes long -func TestNewPanic(t *testing.T) { - defer func() { - if r := recover(); r == nil { - t.Errorf("The code did not panic") - } - }() - - key := make([]byte, 16) - New(key, BackendOpenSSL, 128, true, false) -} diff --git a/internal/cryptocore/hkdf_test.go b/internal/cryptocore/hkdf_test.go deleted file mode 100644 index 96ee01f..0000000 --- a/internal/cryptocore/hkdf_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package cryptocore - -import ( - "bytes" - "encoding/hex" - "testing" -) - -type hkdfTestCase struct { - masterkey []byte - info string - out []byte -} - -// TestHkdfDerive verifies that we get the expected values from hkdfDerive. They -// must not change because this would change the on-disk format. -func TestHkdfDerive(t *testing.T) { - master0 := bytes.Repeat([]byte{0x00}, 32) - master1 := bytes.Repeat([]byte{0x01}, 32) - out1, _ := hex.DecodeString("9ba3cddd48c6339c6e56ebe85f0281d6e9051be4104176e65cb0f8a6f77ae6b4") - out2, _ := hex.DecodeString("e8a2499f48700b954f31de732efd04abce822f5c948e7fbc0896607be0d36d12") - out3, _ := hex.DecodeString("9137f2e67a842484137f3c458f357f204c30d7458f94f432fa989be96854a649") - out4, _ := hex.DecodeString("0bfa5da7d9724d4753269940d36898e2c0f3717c0fee86ada58b5fd6c08cc26c") - - testCases := []hkdfTestCase{ - {master0, "EME filename encryption", out1}, - {master0, hkdfInfoEMENames, out1}, - {master1, "EME filename encryption", out2}, - {master1, hkdfInfoEMENames, out2}, - {master1, "AES-GCM file content encryption", out3}, - {master1, hkdfInfoGCMContent, out3}, - {master1, "AES-SIV file content encryption", out4}, - {master1, hkdfInfoSIVContent, out4}, - } - - for i, v := range testCases { - out := hkdfDerive(v.masterkey, v.info, 32) - if !bytes.Equal(out, v.out) { - want := hex.EncodeToString(v.out) - have := hex.EncodeToString(out) - t.Errorf("testcase %d error:\n"+ - "want=%s\n"+ - "have=%s", i, want, have) - } - } -} diff --git a/internal/cryptocore/randprefetch_test.go b/internal/cryptocore/randprefetch_test.go deleted file mode 100644 index b263ef3..0000000 --- a/internal/cryptocore/randprefetch_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package cryptocore - -import ( - "bytes" - "compress/flate" - "runtime" - "sync" - "testing" -) - -// TestRandPrefetch hammers the randPrefetcher with 100 goroutines and verifies -// that the result is incompressible -func TestRandPrefetch(t *testing.T) { - runtime.GOMAXPROCS(10) - p := 100 - l := 200 - vec := make([][]byte, p) - var wg sync.WaitGroup - for i := 0; i < p; i++ { - wg.Add(1) - go func(i int) { - var tmp []byte - for x := 0; x < l; x++ { - tmp = append(tmp, randPrefetcher.read(l)...) - } - vec[i] = tmp - wg.Done() - }(i) - } - wg.Wait() - var b bytes.Buffer - fw, _ := flate.NewWriter(&b, flate.BestCompression) - for _, v := range vec { - fw.Write(v) - } - fw.Close() - if b.Len() < p*l*l { - t.Errorf("random data should be incompressible, but: in=%d compressed=%d\n", p*l*l, b.Len()) - } -} - -func BenchmarkRandPrefetch(b *testing.B) { - // 16-byte nonces are default since gocryptfs v0.7 - b.SetBytes(16) - for i := 0; i < b.N; i++ { - randPrefetcher.read(16) - } -} diff --git a/internal/cryptocore/randsize_test.go b/internal/cryptocore/randsize_test.go deleted file mode 100644 index 1db4745..0000000 --- a/internal/cryptocore/randsize_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build go1.7 - -// ^^^^^^^^^^^^ we use the "sub-benchmark" feature that was added in Go 1.7 - -package cryptocore - -import ( - "fmt" - "testing" -) - -/* -The troughput we get from /dev/urandom / getentropy depends a lot on the used -block size. Results on my Pentium G630 running Linux 4.11: - -BenchmarkRandSize/16-2 3000000 571 ns/op 27.98 MB/s -BenchmarkRandSize/32-2 3000000 585 ns/op 54.66 MB/s -BenchmarkRandSize/64-2 2000000 860 ns/op 74.36 MB/s -BenchmarkRandSize/128-2 1000000 1197 ns/op 106.90 MB/s -BenchmarkRandSize/256-2 1000000 1867 ns/op 137.06 MB/s -BenchmarkRandSize/512-2 500000 3187 ns/op 160.61 MB/s -BenchmarkRandSize/1024-2 200000 5888 ns/op 173.91 MB/s -BenchmarkRandSize/2048-2 100000 11554 ns/op 177.25 MB/s -BenchmarkRandSize/4096-2 100000 22523 ns/op 181.86 MB/s -BenchmarkRandSize/8192-2 30000 43111 ns/op 190.02 MB/s - -Results are similar when testing with dd, so this is not due to Go allocation -overhead: dd if=/dev/urandom bs=16 count=100000 of=/dev/null -*/ -func BenchmarkUrandomBlocksize(b *testing.B) { - for s := 16; s <= 8192; s *= 2 { - title := fmt.Sprintf("%d", s) - b.Run(title, func(b *testing.B) { - b.SetBytes(int64(s)) - for i := 0; i < b.N; i++ { - RandBytes(s) - } - }) - } -} diff --git a/internal/ctlsocksrv/ctlsock_serve.go b/internal/ctlsocksrv/ctlsock_serve.go deleted file mode 100644 index b63759e..0000000 --- a/internal/ctlsocksrv/ctlsock_serve.go +++ /dev/null @@ -1,163 +0,0 @@ -// Package ctlsocksrv implements the control socket interface that can be -// activated by passing "-ctlsock" on the command line. -package ctlsocksrv - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "net" - "os" - "syscall" - - "github.com/rfjakob/gocryptfs/ctlsock" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Interface should be implemented by fusefrontend[_reverse] -type Interface interface { - EncryptPath(string) (string, error) - DecryptPath(string) (string, error) -} - -type ctlSockHandler struct { - fs Interface - socket *net.UnixListener -} - -// Serve serves incoming connections on "sock". This call blocks so you -// probably want to run it in a new goroutine. -func Serve(sock net.Listener, fs Interface) { - handler := ctlSockHandler{ - fs: fs, - socket: sock.(*net.UnixListener), - } - handler.acceptLoop() -} - -func (ch *ctlSockHandler) acceptLoop() { - for { - conn, err := ch.socket.Accept() - if err != nil { - // This can trigger on program exit with "use of closed network connection". - // Special-casing this is hard due to https://github.com/golang/go/issues/4373 - // so just don't use tlog.Warn to not cause panics in the tests. - tlog.Info.Printf("ctlsock: Accept error: %v", err) - break - } - go ch.handleConnection(conn.(*net.UnixConn)) - } -} - -// ReadBufSize is the size of the request read buffer. -// The longest possible path is 4096 bytes on Linux and 1024 on Mac OS X so -// 5000 bytes should be enough to hold the whole JSON request. This -// assumes that the path does not contain too many characters that had to be -// be escaped in JSON (for example, a null byte blows up to "\u0000"). -// We abort the connection if the request is bigger than this. -const ReadBufSize = 5000 - -// handleConnection reads and parses JSON requests from "conn" -func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) { - buf := make([]byte, ReadBufSize) - for { - n, err := conn.Read(buf) - if err == io.EOF { - conn.Close() - return - } else if err != nil { - tlog.Warn.Printf("ctlsock: Read error: %#v", err) - conn.Close() - return - } - if n == ReadBufSize { - tlog.Warn.Printf("ctlsock: request too big (max = %d bytes)", ReadBufSize-1) - conn.Close() - return - } - data := buf[:n] - var in ctlsock.RequestStruct - err = json.Unmarshal(data, &in) - if err != nil { - tlog.Warn.Printf("ctlsock: JSON Unmarshal error: %#v", err) - err = errors.New("JSON Unmarshal error: " + err.Error()) - sendResponse(conn, err, "", "") - continue - } - ch.handleRequest(&in, conn) - } -} - -// handleRequest handles an already-unmarshaled JSON request -func (ch *ctlSockHandler) handleRequest(in *ctlsock.RequestStruct, conn *net.UnixConn) { - var err error - var inPath, outPath, clean, warnText string - // You cannot perform both decryption and encryption in one request - if in.DecryptPath != "" && in.EncryptPath != "" { - err = errors.New("Ambiguous") - sendResponse(conn, err, "", "") - return - } - // Neither encryption nor encryption has been requested, makes no sense - if in.DecryptPath == "" && in.EncryptPath == "" { - err = errors.New("Empty input") - sendResponse(conn, err, "", "") - return - } - // Canonicalize input path - if in.EncryptPath != "" { - inPath = in.EncryptPath - } else { - inPath = in.DecryptPath - } - clean = SanitizePath(inPath) - // Warn if a non-canonical path was passed - if inPath != clean { - warnText = fmt.Sprintf("Non-canonical input path '%s' has been interpreted as '%s'.", inPath, clean) - } - // Error out if the canonical path is now empty - if clean == "" { - err = errors.New("Empty input after canonicalization") - sendResponse(conn, err, "", warnText) - return - } - // Actual encrypt or decrypt operation - if in.EncryptPath != "" { - outPath, err = ch.fs.EncryptPath(clean) - } else { - outPath, err = ch.fs.DecryptPath(clean) - } - sendResponse(conn, err, outPath, warnText) -} - -// sendResponse sends a JSON response message -func sendResponse(conn *net.UnixConn, err error, result string, warnText string) { - msg := ctlsock.ResponseStruct{ - Result: result, - WarnText: warnText, - } - if err != nil { - msg.ErrText = err.Error() - msg.ErrNo = -1 - // Try to extract the actual error number - if pe, ok := err.(*os.PathError); ok { - if se, ok := pe.Err.(syscall.Errno); ok { - msg.ErrNo = int32(se) - } - } else if err == syscall.ENOENT { - msg.ErrNo = int32(syscall.ENOENT) - } - } - jsonMsg, err := json.Marshal(msg) - if err != nil { - tlog.Warn.Printf("ctlsock: Marshal failed: %v", err) - return - } - // For convenience for the user, add a newline at the end. - jsonMsg = append(jsonMsg, '\n') - _, err = conn.Write(jsonMsg) - if err != nil { - tlog.Warn.Printf("ctlsock: Write failed: %v", err) - } -} diff --git a/internal/ctlsocksrv/sanitize.go b/internal/ctlsocksrv/sanitize.go deleted file mode 100644 index 4333872..0000000 --- a/internal/ctlsocksrv/sanitize.go +++ /dev/null @@ -1,32 +0,0 @@ -package ctlsocksrv - -import ( - "path/filepath" - "strings" -) - -// SanitizePath adapts filepath.Clean for FUSE paths. -// 1) Leading slash(es) are dropped -// 2) It returns "" instead of "." -// 3) If the cleaned path points above CWD (start with ".."), an empty string -// is returned -// See the TestSanitizePath testcases for examples. -func SanitizePath(path string) string { - // (1) - for len(path) > 0 && path[0] == '/' { - path = path[1:] - } - if len(path) == 0 { - return "" - } - clean := filepath.Clean(path) - // (2) - if clean == "." { - return "" - } - // (3) - if clean == ".." || strings.HasPrefix(clean, "../") { - return "" - } - return clean -} diff --git a/internal/ctlsocksrv/sanitize_test.go b/internal/ctlsocksrv/sanitize_test.go deleted file mode 100644 index 2462d5d..0000000 --- a/internal/ctlsocksrv/sanitize_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package ctlsocksrv - -import ( - "testing" -) - -func TestSanitizePath(t *testing.T) { - testCases := [][]string{ - {"", ""}, - {".", ""}, - {"/", ""}, - {"foo", "foo"}, - {"/foo", "foo"}, - {"foo/", "foo"}, - {"/foo/", "foo"}, - {"/foo/./foo", "foo/foo"}, - {"./", ""}, - {"..", ""}, - {"foo/../..", ""}, - {"foo/../../aaaaaa", ""}, - {"/foo/../../aaaaaa", ""}, - {"/////", ""}, - } - for _, tc := range testCases { - res := SanitizePath(tc[0]) - if res != tc[1] { - t.Errorf("%q: got %q, want %q", tc[0], res, tc[1]) - } - } -} diff --git a/internal/ensurefds012/ensurefds012.go b/internal/ensurefds012/ensurefds012.go deleted file mode 100644 index 7872eb2..0000000 --- a/internal/ensurefds012/ensurefds012.go +++ /dev/null @@ -1,52 +0,0 @@ -package ensurefds012 - -// Package ensurefds012 ensures that file descriptors 0,1,2 are open. It opens -// multiple copies of /dev/null as required. -// The Go stdlib as well as the gocryptfs code rely on the fact that -// fds 0,1,2 are always open. -// -// Use like this: -// -// import _ "github.com/rfjakob/gocryptfs/internal/ensurefds012" -// -// The import line MUST be in the alphabitcally first source code file of -// package main! -// -// You can test if it works as expected by inserting a long sleep into main, -// startings gocryptfs with all fds closed like this, -// -// $ ./gocryptfs 0<&- 1>&- 2>&- -// -// and then checking the open fds. It should look like this: -// -// $ ls -l /proc/$(pgrep gocryptfs)/fd -// total 0 -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 0 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 1 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 2 -> /dev/null -// l-wx------. 1 jakob jakob 64 Jan 5 15:54 3 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 4 -> 'anon_inode:[eventpoll]' -// -// See https://github.com/rfjakob/gocryptfs/issues/320 for details. - -import ( - "os" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" -) - -func init() { - fd, err := syscall.Open("/dev/null", syscall.O_RDWR, 0) - if err != nil { - os.Exit(exitcodes.DevNull) - } - for fd <= 2 { - fd, err = syscall.Dup(fd) - if err != nil { - os.Exit(exitcodes.DevNull) - } - } - // Close excess fd (usually fd 3) - syscall.Close(fd) -} diff --git a/internal/fido2/fido2.go b/internal/fido2/fido2.go deleted file mode 100644 index cd63483..0000000 --- a/internal/fido2/fido2.go +++ /dev/null @@ -1,110 +0,0 @@ -package fido2 - -import ( - "bytes" - "encoding/base64" - "fmt" - "io" - "os" - "os/exec" - "strings" - - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -type fidoCommand int - -const ( - cred fidoCommand = iota - assert fidoCommand = iota - assertWithPIN fidoCommand = iota -) - -const relyingPartyID = "gocryptfs" - -func callFidoCommand(command fidoCommand, device string, stdin []string) ([]string, error) { - var cmd *exec.Cmd - switch command { - case cred: - cmd = exec.Command("fido2-cred", "-M", "-h", "-v", device) - case assert: - cmd = exec.Command("fido2-assert", "-G", "-h", device) - case assertWithPIN: - cmd = exec.Command("fido2-assert", "-G", "-h", "-v", device) - } - tlog.Debug.Printf("callFidoCommand: executing %q with args %q", cmd.Path, cmd.Args) - cmd.Stderr = os.Stderr - in, err := cmd.StdinPipe() - if err != nil { - return nil, err - } - for _, s := range stdin { - // This does not deadlock because the pipe buffer is big enough (64kiB on Linux) - io.WriteString(in, s+"\n") - } - in.Close() - out, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("%s failed with %v", cmd.Args[0], err) - } - return strings.Split(string(out), "\n"), nil -} - -// Register registers a credential using a FIDO2 token -func Register(device string, userName string) (credentialID []byte) { - tlog.Info.Printf("FIDO2 Register: interact with your device ...") - cdh := base64.StdEncoding.EncodeToString(cryptocore.RandBytes(32)) - userID := base64.StdEncoding.EncodeToString(cryptocore.RandBytes(32)) - stdin := []string{cdh, relyingPartyID, userName, userID} - out, err := callFidoCommand(cred, device, stdin) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.FIDO2Error) - } - credentialID, err = base64.StdEncoding.DecodeString(out[4]) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.FIDO2Error) - } - return credentialID -} - -// Secret generates a HMAC secret using a FIDO2 token -func Secret(device string, credentialID []byte, salt []byte) (secret []byte) { - tlog.Info.Printf("FIDO2 Secret: interact with your device ...") - cdh := base64.StdEncoding.EncodeToString(cryptocore.RandBytes(32)) - crid := base64.StdEncoding.EncodeToString(credentialID) - hmacsalt := base64.StdEncoding.EncodeToString(salt) - stdin := []string{cdh, relyingPartyID, crid, hmacsalt} - // try asserting without PIN first - out, err := callFidoCommand(assert, device, stdin) - if err != nil { - // if that fails, let's assert with PIN - out, err = callFidoCommand(assertWithPIN, device, stdin) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.FIDO2Error) - } - } - secret, err = base64.StdEncoding.DecodeString(out[4]) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.FIDO2Error) - } - - // sanity checks - secretLen := len(secret) - if secretLen < 32 { - tlog.Fatal.Printf("FIDO2 HMACSecret too short (%d)!\n", secretLen) - os.Exit(exitcodes.FIDO2Error) - } - zero := make([]byte, secretLen) - if bytes.Equal(zero, secret) { - tlog.Fatal.Printf("FIDO2 HMACSecret is all zero!") - os.Exit(exitcodes.FIDO2Error) - } - - return secret -} diff --git a/internal/fusefrontend/args.go b/internal/fusefrontend/args.go deleted file mode 100644 index ae1c30c..0000000 --- a/internal/fusefrontend/args.go +++ /dev/null @@ -1,52 +0,0 @@ -package fusefrontend - -import ( - "github.com/hanwen/go-fuse/v2/fuse" -) - -// Args is a container for arguments that are passed from main() to fusefrontend -type Args struct { - // Cipherdir is the backing storage directory (absolute path). - // For reverse mode, Cipherdir actually contains *plaintext* files. - Cipherdir string - PlaintextNames bool - LongNames bool - // Should we chown a file after it has been created? - // This only makes sense if (1) allow_other is set and (2) we run as root. - PreserveOwner bool - // Should we force ownership to be presented with a given user and group? - // This only makes sense if allow_other is set. In *most* cases, it also - // only makes sense with PreserveOwner set, but can also make sense without - // PreserveOwner if the underlying filesystem acting as backing store - // enforces ownership itself. - ForceOwner *fuse.Owner - // ConfigCustom is true when the user select a non-default config file - // location. If it is false, reverse mode maps ".gocryptfs.reverse.conf" - // to "gocryptfs.conf" in the plaintext dir. - ConfigCustom bool - // NoPrealloc disables automatic preallocation before writing - NoPrealloc bool - // Try to serialize read operations, "-serialize_reads" - SerializeReads bool - // Force decode even if integrity check fails (openSSL only) - ForceDecode bool - // Exclude is a list of paths to make inaccessible, starting match at - // the filesystem root - Exclude []string - // ExcludeWildcards is a list of paths to make inaccessible, matched - // anywhere, and supporting wildcards - ExcludeWildcard []string - // ExcludeFrom is a list of files from which to read exclusion patterns - // (with wildcard syntax) - ExcludeFrom []string - // Suid is true if the filesystem has been mounted with the "-suid" flag. - // If it is false, we can ignore the GETXATTR "security.capability" calls, - // which are a performance problem for writes. See - // https://github.com/rfjakob/gocryptfs/issues/515 for details. - Suid bool - // Enable the FUSE kernel_cache option - KernelCache bool - // SharedStorage disables caching & hard link tracking, - // enabled via cli flag "-sharedstorage" - SharedStorage bool -} diff --git a/internal/fusefrontend/ctlsock_interface.go b/internal/fusefrontend/ctlsock_interface.go deleted file mode 100644 index f34739a..0000000 --- a/internal/fusefrontend/ctlsock_interface.go +++ /dev/null @@ -1,105 +0,0 @@ -package fusefrontend - -import ( - "fmt" - "path" - "path/filepath" - "strings" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/ctlsocksrv" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -var _ ctlsocksrv.Interface = &RootNode{} // Verify that interface is implemented. - -// EncryptPath implements ctlsock.Backend -// -// Symlink-safe through openBackingDir(). -func (rn *RootNode) EncryptPath(plainPath string) (string, error) { - if plainPath == "" { - // Empty string gets encrypted as empty string - return plainPath, nil - } - if rn.args.PlaintextNames { - return plainPath, nil - } - // Encrypt path level by level using openBackingDir. Pretty inefficient, - // but does not matter here. - parts := strings.Split(plainPath, "/") - wd := "" - cPath := "" - for _, part := range parts { - wd = filepath.Join(wd, part) - dirfd, cName, err := rn.openBackingDir(wd) - if err != nil { - return "", err - } - syscall.Close(dirfd) - cPath = filepath.Join(cPath, cName) - } - tlog.Debug.Printf("encryptPath '%s' -> '%s'", plainPath, cPath) - return cPath, nil -} - -// DecryptPath implements ctlsock.Backend -// -// DecryptPath is symlink-safe because openBackingDir() and decryptPathAt() -// are symlink-safe. -func (rn *RootNode) DecryptPath(cipherPath string) (plainPath string, err error) { - dirfd, _, err := rn.openBackingDir("") - if err != nil { - return "", err - } - defer syscall.Close(dirfd) - return rn.decryptPathAt(dirfd, cipherPath) -} - -// decryptPathAt decrypts a ciphertext path relative to dirfd. -// -// Symlink-safe through ReadDirIVAt() and ReadLongNameAt(). -func (rn *RootNode) decryptPathAt(dirfd int, cipherPath string) (plainPath string, err error) { - if rn.args.PlaintextNames || cipherPath == "" { - return cipherPath, nil - } - parts := strings.Split(cipherPath, "/") - wd := dirfd - for i, part := range parts { - dirIV, err := nametransform.ReadDirIVAt(wd) - if err != nil { - fmt.Printf("ReadDirIV: %v\n", err) - return "", err - } - longPart := part - if nametransform.IsLongContent(part) { - longPart, err = nametransform.ReadLongNameAt(wd, part) - if err != nil { - fmt.Printf("ReadLongName: %v\n", err) - return "", err - } - } - name, err := rn.nameTransform.DecryptName(longPart, dirIV) - if err != nil { - fmt.Printf("DecryptName: %v\n", err) - return "", err - } - plainPath = path.Join(plainPath, name) - // Last path component? We are done. - if i == len(parts)-1 { - break - } - // Descend into next directory - wd, err = syscallcompat.Openat(wd, part, syscall.O_NOFOLLOW|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) - if err != nil { - return "", err - } - // Yes this is somewhat wasteful in terms of used file descriptors: - // we keep them all open until the function returns. But it is simple - // and reliable. - defer syscall.Close(wd) - } - - return plainPath, nil -} diff --git a/internal/fusefrontend/dircache.go b/internal/fusefrontend/dircache.go deleted file mode 100644 index 6732de1..0000000 --- a/internal/fusefrontend/dircache.go +++ /dev/null @@ -1,180 +0,0 @@ -package fusefrontend - -import ( - "fmt" - "log" - "sync" - "syscall" - "time" - - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -const ( - // Number of entries in the dirCache. - // 20 entries work well for "git stat" on a small git repo on sshfs. - // Keep in sync with test_helpers.maxCacheFds ! - // TODO: How to share this constant without causing an import cycle? - dirCacheSize = 20 - // Enable Lookup/Store/Clear debug messages - enableDebugMessages = false - // Enable hit rate statistics printing - enableStats = false -) - -type dirCacheEntry struct { - // pointer to the Node this entry belongs to - node *Node - // fd to the directory (opened with O_PATH!) - fd int - // content of gocryptfs.diriv in this directory - iv []byte -} - -func (e *dirCacheEntry) Clear() { - // An earlier clear may have already closed the fd, or the cache - // has never been filled (fd is 0 in that case). - // Note: package ensurefds012, imported from main, guarantees that dirCache - // can never get fds 0,1,2. - if e.fd > 0 { - err := syscall.Close(e.fd) - if err != nil { - tlog.Warn.Printf("dirCache.Clear: Close failed: %v", err) - } - } - e.fd = -1 - e.node = nil - e.iv = nil -} - -type dirCache struct { - sync.Mutex - // Cache entries - entries [dirCacheSize]dirCacheEntry - // Where to store the next entry (index into entries) - nextIndex int - // On the first Lookup(), the expire thread is started, and this flag is set - // to true. - expireThreadRunning bool - // Hit rate stats. Evaluated and reset by the expire thread. - lookups uint64 - hits uint64 -} - -// Clear clears the cache contents. -func (d *dirCache) Clear() { - d.dbg("Clear\n") - d.Lock() - defer d.Unlock() - for i := range d.entries { - d.entries[i].Clear() - } -} - -// Store the entry in the cache. The passed "fd" will be Dup()ed, and the caller -// can close their copy at will. -func (d *dirCache) Store(node *Node, fd int, iv []byte) { - // Note: package ensurefds012, imported from main, guarantees that dirCache - // can never get fds 0,1,2. - if fd <= 0 || len(iv) != nametransform.DirIVLen { - log.Panicf("Store sanity check failed: fd=%d len=%d", fd, len(iv)) - } - d.Lock() - defer d.Unlock() - e := &d.entries[d.nextIndex] - // Round-robin works well enough - d.nextIndex = (d.nextIndex + 1) % dirCacheSize - // Close the old fd - e.Clear() - fd2, err := syscall.Dup(fd) - if err != nil { - tlog.Warn.Printf("dirCache.Store: Dup failed: %v", err) - return - } - d.dbg("dirCache.Store %p fd=%d iv=%x\n", node, fd2, iv) - e.fd = fd2 - e.node = node - e.iv = iv - // expireThread is started on the first Lookup() - if !d.expireThreadRunning { - d.expireThreadRunning = true - go d.expireThread() - } -} - -// Lookup checks if relPath is in the cache, and returns an (fd, iv) pair. -// It returns (-1, nil) if not found. The fd is internally Dup()ed and the -// caller must close it when done. -func (d *dirCache) Lookup(node *Node) (fd int, iv []byte) { - d.Lock() - defer d.Unlock() - if enableStats { - d.lookups++ - } - var e *dirCacheEntry - for i := range d.entries { - e = &d.entries[i] - if e.fd <= 0 { - // Cache slot is empty - continue - } - if node != e.node { - // Not the right path - continue - } - var err error - fd, err = syscall.Dup(e.fd) - if err != nil { - tlog.Warn.Printf("dirCache.Lookup: Dup failed: %v", err) - return -1, nil - } - iv = e.iv - break - } - if fd == 0 { - d.dbg("dirCache.Lookup %p miss\n", node) - return -1, nil - } - if enableStats { - d.hits++ - } - if fd <= 0 || len(iv) != nametransform.DirIVLen { - log.Panicf("Lookup sanity check failed: fd=%d len=%d", fd, len(iv)) - } - d.dbg("dirCache.Lookup %p hit fd=%d dup=%d iv=%x\n", node, e.fd, fd, iv) - return fd, iv -} - -// expireThread is started on the first Lookup() -func (d *dirCache) expireThread() { - for { - time.Sleep(60 * time.Second) - d.Clear() - d.stats() - } -} - -// stats prints hit rate statistics and resets the counters. No-op if -// enableStats == false. -func (d *dirCache) stats() { - if !enableStats { - return - } - d.Lock() - lookups := d.lookups - hits := d.hits - d.lookups = 0 - d.hits = 0 - d.Unlock() - if lookups > 0 { - fmt.Printf("dirCache: hits=%3d lookups=%3d, rate=%3d%%\n", hits, lookups, (hits*100)/lookups) - } -} - -// dbg prints a debug message. Usually disabled. -func (d *dirCache) dbg(format string, a ...interface{}) { - if enableDebugMessages { - fmt.Printf(format, a...) - } -} diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go deleted file mode 100644 index cbf78e9..0000000 --- a/internal/fusefrontend/file.go +++ /dev/null @@ -1,457 +0,0 @@ -package fusefrontend - -// FUSE operations on file handles - -import ( - "bytes" - "context" - "encoding/hex" - "fmt" - "io" - "log" - "math" - "os" - "sync" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/inomap" - "github.com/rfjakob/gocryptfs/internal/openfiletable" - "github.com/rfjakob/gocryptfs/internal/serialize_reads" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// File implements the go-fuse v2 API (github.com/hanwen/go-fuse/v2/fs) -type File struct { - fd *os.File - // Has Release() already been called on this file? This also means that the - // wlock entry has been freed, so let's not crash trying to access it. - // Due to concurrency, Release can overtake other operations. These will - // return EBADF in that case. - released bool - // fdLock prevents the fd to be closed while we are in the middle of - // an operation. - // Every FUSE entrypoint should RLock(). The only user of Lock() is - // Release(), which closes the fd and sets "released" to true. - fdLock sync.RWMutex - // Content encryption helper - contentEnc *contentenc.ContentEnc - // Device and inode number uniquely identify the backing file - qIno inomap.QIno - // Entry in the open file table - fileTableEntry *openfiletable.Entry - // Store where the last byte was written - lastWrittenOffset int64 - // The opCount is used to judge whether "lastWrittenOffset" is still - // guaranteed to be correct. - lastOpCount uint64 - // Parent filesystem - rootNode *RootNode -} - -// NewFile returns a new go-fuse File instance based on an already-open file -// descriptor. NewFile internally calls Fstat() on the fd. The resulting Stat_t -// is returned because node.Create() needs it. -// -// `cName` is only used for error logging and may be left blank. -func NewFile(fd int, cName string, rn *RootNode) (f *File, st *syscall.Stat_t, errno syscall.Errno) { - // Need device number and inode number for openfiletable locking - st = &syscall.Stat_t{} - if err := syscall.Fstat(fd, st); err != nil { - errno = fs.ToErrno(err) - return - } - qi := inomap.QInoFromStat(st) - e := openfiletable.Register(qi) - - osFile := os.NewFile(uintptr(fd), cName) - - f = &File{ - fd: osFile, - contentEnc: rn.contentEnc, - qIno: qi, - fileTableEntry: e, - rootNode: rn, - } - return f, st, 0 -} - -// intFd - return the backing file descriptor as an integer. -func (f *File) intFd() int { - return int(f.fd.Fd()) -} - -// readFileID loads the file header from disk and extracts the file ID. -// Returns io.EOF if the file is empty. -func (f *File) readFileID() ([]byte, error) { - // We read +1 byte to determine if the file has actual content - // and not only the header. A header-only file will be considered empty. - // This makes File ID poisoning more difficult. - readLen := contentenc.HeaderLen + 1 - buf := make([]byte, readLen) - n, err := f.fd.ReadAt(buf, 0) - if err != nil { - if err == io.EOF && n != 0 { - tlog.Warn.Printf("readFileID %d: incomplete file, got %d instead of %d bytes", - f.qIno.Ino, n, readLen) - f.rootNode.reportMitigatedCorruption(fmt.Sprint(f.qIno.Ino)) - } - return nil, err - } - buf = buf[:contentenc.HeaderLen] - h, err := contentenc.ParseHeader(buf) - if err != nil { - return nil, err - } - return h.ID, nil -} - -// createHeader creates a new random header and writes it to disk. -// Returns the new file ID. -// The caller must hold fileIDLock.Lock(). -func (f *File) createHeader() (fileID []byte, err error) { - h := contentenc.RandomHeader() - buf := h.Pack() - // Prevent partially written (=corrupt) header by preallocating the space beforehand - if !f.rootNode.args.NoPrealloc { - err = syscallcompat.EnospcPrealloc(f.intFd(), 0, contentenc.HeaderLen) - if err != nil { - if !syscallcompat.IsENOSPC(err) { - tlog.Warn.Printf("ino%d: createHeader: prealloc failed: %s\n", f.qIno.Ino, err.Error()) - } - return nil, err - } - } - // Actually write header - _, err = f.fd.WriteAt(buf, 0) - if err != nil { - return nil, err - } - return h.ID, err -} - -// doRead - read "length" plaintext bytes from plaintext offset "off" and append -// to "dst". -// Arguments "length" and "off" do not have to be block-aligned. -// -// doRead reads the corresponding ciphertext blocks from disk, decrypts them and -// returns the requested part of the plaintext. -// -// Called by Read() for normal reading, -// by Write() and Truncate() via doWrite() for Read-Modify-Write. -func (f *File) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.Errno) { - // Get the file ID, either from the open file table, or from disk. - var fileID []byte - f.fileTableEntry.IDLock.Lock() - if f.fileTableEntry.ID != nil { - // Use the cached value in the file table - fileID = f.fileTableEntry.ID - } else { - // Not cached, we have to read it from disk. - var err error - fileID, err = f.readFileID() - if err != nil { - f.fileTableEntry.IDLock.Unlock() - if err == io.EOF { - // Empty file - return nil, 0 - } - buf := make([]byte, 100) - n, _ := f.fd.ReadAt(buf, 0) - buf = buf[:n] - hexdump := hex.EncodeToString(buf) - tlog.Warn.Printf("doRead %d: corrupt header: %v\nFile hexdump (%d bytes): %s", - f.qIno.Ino, err, n, hexdump) - return nil, syscall.EIO - } - // Save into the file table - f.fileTableEntry.ID = fileID - } - f.fileTableEntry.IDLock.Unlock() - if fileID == nil { - log.Panicf("fileID=%v", fileID) - } - // Read the backing ciphertext in one go - blocks := f.contentEnc.ExplodePlainRange(off, length) - alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks) - // f.fd.ReadAt takes an int64! - if alignedOffset > math.MaxInt64 { - return nil, syscall.EFBIG - } - skip := blocks[0].Skip - tlog.Debug.Printf("doRead: off=%d len=%d -> off=%d len=%d skip=%d\n", - off, length, alignedOffset, alignedLength, skip) - - ciphertext := f.rootNode.contentEnc.CReqPool.Get() - ciphertext = ciphertext[:int(alignedLength)] - n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset)) - if err != nil && err != io.EOF { - tlog.Warn.Printf("read: ReadAt: %s", err.Error()) - return nil, fs.ToErrno(err) - } - // The ReadAt came back empty. We can skip all the decryption and return early. - if n == 0 { - f.rootNode.contentEnc.CReqPool.Put(ciphertext) - return dst, 0 - } - // Truncate ciphertext buffer down to actually read bytes - ciphertext = ciphertext[0:n] - - firstBlockNo := blocks[0].BlockNo - tlog.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d", alignedOffset, firstBlockNo, alignedLength, n) - - // Decrypt it - plaintext, err := f.contentEnc.DecryptBlocks(ciphertext, firstBlockNo, fileID) - f.rootNode.contentEnc.CReqPool.Put(ciphertext) - if err != nil { - if f.rootNode.args.ForceDecode && err == stupidgcm.ErrAuth { - // We do not have the information which block was corrupt here anymore, - // but DecryptBlocks() has already logged it anyway. - tlog.Warn.Printf("doRead %d: off=%d len=%d: returning corrupt data due to forcedecode", - f.qIno.Ino, off, length) - } else { - curruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext))) - tlog.Warn.Printf("doRead %d: corrupt block #%d: %v", f.qIno.Ino, curruptBlockNo, err) - return nil, syscall.EIO - } - } - - // Crop down to the relevant part - var out []byte - lenHave := len(plaintext) - lenWant := int(skip + length) - if lenHave > lenWant { - out = plaintext[skip:lenWant] - } else if lenHave > int(skip) { - out = plaintext[skip:lenHave] - } - // else: out stays empty, file was smaller than the requested offset - - out = append(dst, out...) - f.rootNode.contentEnc.PReqPool.Put(plaintext) - - return out, 0 -} - -// Read - FUSE call -func (f *File) Read(ctx context.Context, buf []byte, off int64) (resultData fuse.ReadResult, errno syscall.Errno) { - if len(buf) > fuse.MAX_KERNEL_WRITE { - // This would crash us due to our fixed-size buffer pool - tlog.Warn.Printf("Read: rejecting oversized request with EMSGSIZE, len=%d", len(buf)) - return nil, syscall.EMSGSIZE - } - f.fdLock.RLock() - defer f.fdLock.RUnlock() - - f.fileTableEntry.ContentLock.RLock() - defer f.fileTableEntry.ContentLock.RUnlock() - - tlog.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d", f.qIno.Ino, off, len(buf)) - if f.rootNode.args.SerializeReads { - serialize_reads.Wait(off, len(buf)) - } - out, errno := f.doRead(buf[:0], uint64(off), uint64(len(buf))) - if f.rootNode.args.SerializeReads { - serialize_reads.Done() - } - if errno != 0 { - return nil, errno - } - tlog.Debug.Printf("ino%d: Read: errno=%d, returning %d bytes", f.qIno.Ino, errno, len(out)) - return fuse.ReadResultData(out), errno -} - -// doWrite - encrypt "data" and write it to plaintext offset "off" -// -// Arguments do not have to be block-aligned, read-modify-write is -// performed internally as necessary -// -// Called by Write() for normal writing, -// and by Truncate() to rewrite the last file block. -// -// Empty writes do nothing and are allowed. -func (f *File) doWrite(data []byte, off int64) (uint32, syscall.Errno) { - fileWasEmpty := false - // Get the file ID, create a new one if it does not exist yet. - var fileID []byte - // The caller has exclusively locked ContentLock, which blocks all other - // readers and writers. No need to take IDLock. - if f.fileTableEntry.ID != nil { - fileID = f.fileTableEntry.ID - } else { - // If the file ID is not cached, read it from disk - var err error - fileID, err = f.readFileID() - // Write a new file header if the file is empty - if err == io.EOF { - fileID, err = f.createHeader() - fileWasEmpty = true - } - if err != nil { - return 0, fs.ToErrno(err) - } - f.fileTableEntry.ID = fileID - } - // Handle payload data - dataBuf := bytes.NewBuffer(data) - blocks := f.contentEnc.ExplodePlainRange(uint64(off), uint64(len(data))) - toEncrypt := make([][]byte, len(blocks)) - for i, b := range blocks { - blockData := dataBuf.Next(int(b.Length)) - // Incomplete block -> Read-Modify-Write - if b.IsPartial() { - // Read - oldData, errno := f.doRead(nil, b.BlockPlainOff(), f.contentEnc.PlainBS()) - if errno != 0 { - tlog.Warn.Printf("ino%d fh%d: RMW read failed: errno=%d", f.qIno.Ino, f.intFd(), errno) - return 0, errno - } - // Modify - blockData = f.contentEnc.MergeBlocks(oldData, blockData, int(b.Skip)) - tlog.Debug.Printf("len(oldData)=%d len(blockData)=%d", len(oldData), len(blockData)) - } - tlog.Debug.Printf("ino%d: Writing %d bytes to block #%d", - f.qIno.Ino, len(blockData), b.BlockNo) - // Write into the to-encrypt list - toEncrypt[i] = blockData - } - // Encrypt all blocks - ciphertext := f.contentEnc.EncryptBlocks(toEncrypt, blocks[0].BlockNo, f.fileTableEntry.ID) - // Preallocate so we cannot run out of space in the middle of the write. - // This prevents partially written (=corrupt) blocks. - var err error - cOff := blocks[0].BlockCipherOff() - // f.fd.WriteAt & syscallcompat.EnospcPrealloc take int64 offsets! - if cOff > math.MaxInt64 { - return 0, syscall.EFBIG - } - if !f.rootNode.args.NoPrealloc { - err = syscallcompat.EnospcPrealloc(f.intFd(), int64(cOff), int64(len(ciphertext))) - if err != nil { - if !syscallcompat.IsENOSPC(err) { - tlog.Warn.Printf("ino%d fh%d: doWrite: prealloc failed: %v", f.qIno.Ino, f.intFd(), err) - } - if fileWasEmpty { - // Kill the file header again - f.fileTableEntry.ID = nil - err2 := syscall.Ftruncate(f.intFd(), 0) - if err2 != nil { - tlog.Warn.Printf("ino%d fh%d: doWrite: rollback failed: %v", f.qIno.Ino, f.intFd(), err2) - } - } - return 0, fs.ToErrno(err) - } - } - // Write - _, err = f.fd.WriteAt(ciphertext, int64(cOff)) - // Return memory to CReqPool - f.rootNode.contentEnc.CReqPool.Put(ciphertext) - if err != nil { - tlog.Warn.Printf("ino%d fh%d: doWrite: WriteAt off=%d len=%d failed: %v", - f.qIno.Ino, f.intFd(), cOff, len(ciphertext), err) - return 0, fs.ToErrno(err) - } - return uint32(len(data)), 0 -} - -// isConsecutiveWrite returns true if the current write -// directly (in time and space) follows the last write. -// This is an optimisation for streaming writes on NFS where a -// Stat() call is very expensive. -// The caller must "wlock.lock(f.devIno.ino)" otherwise this check would be racy. -func (f *File) isConsecutiveWrite(off int64) bool { - opCount := openfiletable.WriteOpCount() - return opCount == f.lastOpCount+1 && off == f.lastWrittenOffset+1 -} - -// Write - FUSE call -// -// If the write creates a hole, pads the file to the next block boundary. -func (f *File) Write(ctx context.Context, data []byte, off int64) (uint32, syscall.Errno) { - if len(data) > fuse.MAX_KERNEL_WRITE { - // This would crash us due to our fixed-size buffer pool - tlog.Warn.Printf("Write: rejecting oversized request with EMSGSIZE, len=%d", len(data)) - return 0, syscall.EMSGSIZE - } - f.fdLock.RLock() - defer f.fdLock.RUnlock() - if f.released { - // The file descriptor has been closed concurrently - tlog.Warn.Printf("ino%d fh%d: Write on released file", f.qIno.Ino, f.intFd()) - return 0, syscall.EBADF - } - f.fileTableEntry.ContentLock.Lock() - defer f.fileTableEntry.ContentLock.Unlock() - tlog.Debug.Printf("ino%d: FUSE Write: offset=%d length=%d", f.qIno.Ino, off, len(data)) - // If the write creates a file hole, we have to zero-pad the last block. - // But if the write directly follows an earlier write, it cannot create a - // hole, and we can save one Stat() call. - if !f.isConsecutiveWrite(off) { - errno := f.writePadHole(off) - if errno != 0 { - return 0, errno - } - } - n, errno := f.doWrite(data, off) - if errno != 0 { - f.lastOpCount = openfiletable.WriteOpCount() - f.lastWrittenOffset = off + int64(len(data)) - 1 - } - return n, errno -} - -// Release - FUSE call, close file -func (f *File) Release(ctx context.Context) syscall.Errno { - f.fdLock.Lock() - if f.released { - log.Panicf("ino%d fh%d: double release", f.qIno.Ino, f.intFd()) - } - f.released = true - openfiletable.Unregister(f.qIno) - err := f.fd.Close() - f.fdLock.Unlock() - return fs.ToErrno(err) -} - -// Flush - FUSE call -func (f *File) Flush(ctx context.Context) syscall.Errno { - f.fdLock.RLock() - defer f.fdLock.RUnlock() - - err := syscallcompat.Flush(f.intFd()) - return fs.ToErrno(err) -} - -// Fsync FUSE call -func (f *File) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) { - f.fdLock.RLock() - defer f.fdLock.RUnlock() - - return fs.ToErrno(syscall.Fsync(f.intFd())) -} - -// Getattr FUSE call (like stat) -func (f *File) Getattr(ctx context.Context, a *fuse.AttrOut) syscall.Errno { - f.fdLock.RLock() - defer f.fdLock.RUnlock() - - tlog.Debug.Printf("file.GetAttr()") - st := syscall.Stat_t{} - err := syscall.Fstat(f.intFd(), &st) - if err != nil { - return fs.ToErrno(err) - } - f.rootNode.inoMap.TranslateStat(&st) - a.FromStat(&st) - a.Size = f.contentEnc.CipherSizeToPlainSize(a.Size) - if f.rootNode.args.ForceOwner != nil { - a.Owner = *f.rootNode.args.ForceOwner - } - - return 0 -} diff --git a/internal/fusefrontend/file_allocate_truncate.go b/internal/fusefrontend/file_allocate_truncate.go deleted file mode 100644 index f4e6099..0000000 --- a/internal/fusefrontend/file_allocate_truncate.go +++ /dev/null @@ -1,218 +0,0 @@ -package fusefrontend - -// FUSE operations Truncate and Allocate on file handles -// i.e. ftruncate and fallocate - -import ( - "context" - "log" - "sync" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// FALLOC_DEFAULT is a "normal" fallocate operation -const FALLOC_DEFAULT = 0x00 - -// FALLOC_FL_KEEP_SIZE allocates disk space while not modifying the file size -const FALLOC_FL_KEEP_SIZE = 0x01 - -// Only warn once -var allocateWarnOnce sync.Once - -// Allocate - FUSE call for fallocate(2) -// -// mode=FALLOC_FL_KEEP_SIZE is implemented directly. -// -// mode=FALLOC_DEFAULT is implemented as a two-step process: -// -// (1) Allocate the space using FALLOC_FL_KEEP_SIZE -// (2) Set the file size using ftruncate (via truncateGrowFile) -// -// This allows us to reuse the file grow mechanics from Truncate as they are -// complicated and hard to get right. -// -// Other modes (hole punching, zeroing) are not supported. -func (f *File) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno { - if mode != FALLOC_DEFAULT && mode != FALLOC_FL_KEEP_SIZE { - f := func() { - tlog.Info.Printf("fallocate: only mode 0 (default) and 1 (keep size) are supported") - } - allocateWarnOnce.Do(f) - return syscall.EOPNOTSUPP - } - - f.fdLock.RLock() - defer f.fdLock.RUnlock() - if f.released { - return syscall.EBADF - } - f.fileTableEntry.ContentLock.Lock() - defer f.fileTableEntry.ContentLock.Unlock() - - blocks := f.contentEnc.ExplodePlainRange(off, sz) - firstBlock := blocks[0] - lastBlock := blocks[len(blocks)-1] - - // Step (1): Allocate the space the user wants using FALLOC_FL_KEEP_SIZE. - // This will fill file holes and/or allocate additional space past the end of - // the file. - cipherOff := firstBlock.BlockCipherOff() - cipherSz := lastBlock.BlockCipherOff() - cipherOff + - f.contentEnc.BlockOverhead() + lastBlock.Skip + lastBlock.Length - err := syscallcompat.Fallocate(f.intFd(), FALLOC_FL_KEEP_SIZE, int64(cipherOff), int64(cipherSz)) - tlog.Debug.Printf("Allocate off=%d sz=%d mode=%x cipherOff=%d cipherSz=%d\n", - off, sz, mode, cipherOff, cipherSz) - if err != nil { - return fs.ToErrno(err) - } - if mode == FALLOC_FL_KEEP_SIZE { - // The user did not want to change the apparent size. We are done. - return 0 - } - // Step (2): Grow the apparent file size - // We need the old file size to determine if we are growing the file at all. - newPlainSz := off + sz - oldPlainSz, err := f.statPlainSize() - if err != nil { - return fs.ToErrno(err) - } - if newPlainSz <= oldPlainSz { - // The new size is smaller (or equal). Fallocate with mode = 0 never - // truncates a file, so we are done. - return 0 - } - // The file grows. The space has already been allocated in (1), so what is - // left to do is to pad the first and last block and call truncate. - // truncateGrowFile does just that. - return f.truncateGrowFile(oldPlainSz, newPlainSz) -} - -// truncate - called from Setattr. -func (f *File) truncate(newSize uint64) (errno syscall.Errno) { - var err error - // Common case first: Truncate to zero - if newSize == 0 { - err = syscall.Ftruncate(int(f.fd.Fd()), 0) - if err != nil { - tlog.Warn.Printf("ino%d fh%d: Ftruncate(fd, 0) returned error: %v", f.qIno.Ino, f.intFd(), err) - return fs.ToErrno(err) - } - // Truncate to zero kills the file header - f.fileTableEntry.ID = nil - return 0 - } - // We need the old file size to determine if we are growing or shrinking - // the file - oldSize, err := f.statPlainSize() - if err != nil { - return fs.ToErrno(err) - } - - oldB := float32(oldSize) / float32(f.contentEnc.PlainBS()) - newB := float32(newSize) / float32(f.contentEnc.PlainBS()) - tlog.Debug.Printf("ino%d: FUSE Truncate from %.2f to %.2f blocks (%d to %d bytes)", f.qIno.Ino, oldB, newB, oldSize, newSize) - - // File size stays the same - nothing to do - if newSize == oldSize { - return 0 - } - // File grows - if newSize > oldSize { - return f.truncateGrowFile(oldSize, newSize) - } - - // File shrinks - blockNo := f.contentEnc.PlainOffToBlockNo(newSize) - cipherOff := f.contentEnc.BlockNoToCipherOff(blockNo) - plainOff := f.contentEnc.BlockNoToPlainOff(blockNo) - lastBlockLen := newSize - plainOff - var data []byte - if lastBlockLen > 0 { - data, errno = f.doRead(nil, plainOff, lastBlockLen) - if errno != 0 { - tlog.Warn.Printf("Truncate: shrink doRead returned error: %v", err) - return errno - } - } - // Truncate down to the last complete block - err = syscall.Ftruncate(int(f.fd.Fd()), int64(cipherOff)) - if err != nil { - tlog.Warn.Printf("Truncate: shrink Ftruncate returned error: %v", err) - return fs.ToErrno(err) - } - // Append partial block - if lastBlockLen > 0 { - _, status := f.doWrite(data, int64(plainOff)) - return status - } - return 0 -} - -// statPlainSize stats the file and returns the plaintext size -func (f *File) statPlainSize() (uint64, error) { - fi, err := f.fd.Stat() - if err != nil { - tlog.Warn.Printf("ino%d fh%d: statPlainSize: %v", f.qIno.Ino, f.intFd(), err) - return 0, err - } - cipherSz := uint64(fi.Size()) - plainSz := uint64(f.contentEnc.CipherSizeToPlainSize(cipherSz)) - return plainSz, nil -} - -// truncateGrowFile extends a file using seeking or ftruncate performing RMW on -// the first and last block as necessary. New blocks in the middle become -// file holes unless they have been fallocate()'d beforehand. -func (f *File) truncateGrowFile(oldPlainSz uint64, newPlainSz uint64) syscall.Errno { - if newPlainSz <= oldPlainSz { - log.Panicf("BUG: newSize=%d <= oldSize=%d", newPlainSz, oldPlainSz) - } - newEOFOffset := newPlainSz - 1 - if oldPlainSz > 0 { - n1 := f.contentEnc.PlainOffToBlockNo(oldPlainSz - 1) - n2 := f.contentEnc.PlainOffToBlockNo(newEOFOffset) - // The file is grown within one block, no need to pad anything. - // Write a single zero to the last byte and let doWrite figure out the RMW. - if n1 == n2 { - buf := make([]byte, 1) - _, errno := f.doWrite(buf, int64(newEOFOffset)) - return errno - } - } - // The truncate creates at least one new block. - // - // Make sure the old last block is padded to the block boundary. This call - // is a no-op if it is already block-aligned. - errno := f.zeroPad(oldPlainSz) - if errno != 0 { - return errno - } - // The new size is block-aligned. In this case we can do everything ourselves - // and avoid the call to doWrite. - if newPlainSz%f.contentEnc.PlainBS() == 0 { - // The file was empty, so it did not have a header. Create one. - if oldPlainSz == 0 { - id, err := f.createHeader() - if err != nil { - return fs.ToErrno(err) - } - f.fileTableEntry.ID = id - } - cSz := int64(f.contentEnc.PlainSizeToCipherSize(newPlainSz)) - err := syscall.Ftruncate(f.intFd(), cSz) - if err != nil { - tlog.Warn.Printf("Truncate: grow Ftruncate returned error: %v", err) - } - return fs.ToErrno(err) - } - // The new size is NOT aligned, so we need to write a partial block. - // Write a single zero to the last byte and let doWrite figure it out. - buf := make([]byte, 1) - _, errno = f.doWrite(buf, int64(newEOFOffset)) - return errno -} diff --git a/internal/fusefrontend/file_api_check.go b/internal/fusefrontend/file_api_check.go deleted file mode 100644 index 019e97f..0000000 --- a/internal/fusefrontend/file_api_check.go +++ /dev/null @@ -1,22 +0,0 @@ -package fusefrontend - -import ( - "github.com/hanwen/go-fuse/v2/fs" -) - -// Check that we have implemented the fs.File* interfaces -var _ = (fs.FileGetattrer)((*File)(nil)) -var _ = (fs.FileSetattrer)((*File)(nil)) -var _ = (fs.FileReleaser)((*File)(nil)) -var _ = (fs.FileReader)((*File)(nil)) -var _ = (fs.FileWriter)((*File)(nil)) -var _ = (fs.FileFsyncer)((*File)(nil)) -var _ = (fs.FileFlusher)((*File)(nil)) -var _ = (fs.FileAllocater)((*File)(nil)) -var _ = (fs.FileLseeker)((*File)(nil)) - -/* TODO -var _ = (fs.FileGetlker)((*File)(nil)) -var _ = (fs.FileSetlker)((*File)(nil)) -var _ = (fs.FileSetlkwer)((*File)(nil)) -*/ diff --git a/internal/fusefrontend/file_holes.go b/internal/fusefrontend/file_holes.go deleted file mode 100644 index cb44803..0000000 --- a/internal/fusefrontend/file_holes.go +++ /dev/null @@ -1,128 +0,0 @@ -package fusefrontend - -// Helper functions for sparse files (files with holes) - -import ( - "context" - "runtime" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Will a write to plaintext offset "targetOff" create a file hole in the -// ciphertext? If yes, zero-pad the last ciphertext block. -func (f *File) writePadHole(targetOff int64) syscall.Errno { - // Get the current file size. - fi, err := f.fd.Stat() - if err != nil { - tlog.Warn.Printf("checkAndPadHole: Fstat failed: %v", err) - return fs.ToErrno(err) - } - plainSize := f.contentEnc.CipherSizeToPlainSize(uint64(fi.Size())) - // Appending a single byte to the file (equivalent to writing to - // offset=plainSize) would write to "nextBlock". - nextBlock := f.contentEnc.PlainOffToBlockNo(plainSize) - // targetBlock is the block the user wants to write to. - targetBlock := f.contentEnc.PlainOffToBlockNo(uint64(targetOff)) - // The write goes into an existing block or (if the last block was full) - // starts a new one directly after the last block. Nothing to do. - if targetBlock <= nextBlock { - return 0 - } - // The write goes past the next block. nextBlock has - // to be zero-padded to the block boundary and (at least) nextBlock+1 - // will contain a file hole in the ciphertext. - errno := f.zeroPad(plainSize) - if errno != 0 { - return errno - } - return 0 -} - -// Zero-pad the file of size plainSize to the next block boundary. This is a no-op -// if the file is already block-aligned. -func (f *File) zeroPad(plainSize uint64) syscall.Errno { - lastBlockLen := plainSize % f.contentEnc.PlainBS() - if lastBlockLen == 0 { - // Already block-aligned - return 0 - } - missing := f.contentEnc.PlainBS() - lastBlockLen - pad := make([]byte, missing) - tlog.Debug.Printf("zeroPad: Writing %d bytes\n", missing) - _, errno := f.doWrite(pad, int64(plainSize)) - return errno -} - -// Lseek - FUSE call. -// -// Looking at -// fuse_file_llseek @ https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/fuse/file.c?h=v5.12.7#n2634 -// this function is only called for SEEK_HOLE & SEEK_DATA. -func (f *File) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) { - const ( - SEEK_DATA = 3 // find next data segment at or above `off` - SEEK_HOLE = 4 // find next hole at or above `off` - - // On error, we return -1 as the offset as per man lseek. - MinusOne = ^uint64(0) - ) - if whence != SEEK_DATA && whence != SEEK_HOLE { - tlog.Warn.Printf("BUG: Lseek was called with whence=%d. This is not supported!", whence) - return 0, syscall.EINVAL - } - if runtime.GOOS != "linux" { - // MacOS has broken (different?) SEEK_DATA / SEEK_HOLE semantics, see - // https://lists.gnu.org/archive/html/bug-gnulib/2018-09/msg00051.html - tlog.Warn.Printf("buggy on non-linux platforms, disabling SEEK_DATA & SEEK_HOLE") - return MinusOne, syscall.ENOSYS - } - - // We will need the file size - var st syscall.Stat_t - err := syscall.Fstat(f.intFd(), &st) - if err != nil { - return 0, fs.ToErrno(err) - } - fileSize := st.Size - // Better safe than sorry. The logic is only tested for 4k blocks. - if st.Blksize != 4096 { - tlog.Warn.Printf("unsupported block size of %d bytes, disabling SEEK_DATA & SEEK_HOLE", st.Blksize) - return MinusOne, syscall.ENOSYS - } - - // man lseek: offset beyond end of file -> ENXIO - if f.rootNode.contentEnc.PlainOffToCipherOff(off) >= uint64(fileSize) { - return MinusOne, syscall.ENXIO - } - - // Round down to start of block: - cipherOff := f.rootNode.contentEnc.BlockNoToCipherOff(f.rootNode.contentEnc.PlainOffToBlockNo(off)) - newCipherOff, err := syscall.Seek(f.intFd(), int64(cipherOff), int(whence)) - if err != nil { - return MinusOne, fs.ToErrno(err) - } - // already in data/hole => return original offset - if newCipherOff == int64(cipherOff) { - return off, 0 - } - // If there is no further hole, SEEK_HOLE returns the file size - // (SEEK_DATA returns ENXIO in this case). - if whence == SEEK_HOLE { - fi, err := f.fd.Stat() - if err != nil { - return MinusOne, fs.ToErrno(err) - } - if newCipherOff == fi.Size() { - return f.rootNode.contentEnc.CipherSizeToPlainSize(uint64(newCipherOff)), 0 - } - } - // syscall.Seek gave us the beginning of the next ext4 data/hole section. - // The next gocryptfs data/hole block starts at the next block boundary, - // so we have to round up: - newBlockNo := f.rootNode.contentEnc.CipherOffToBlockNo(uint64(newCipherOff) + f.rootNode.contentEnc.CipherBS() - 1) - return f.rootNode.contentEnc.BlockNoToPlainOff(newBlockNo), 0 -} diff --git a/internal/fusefrontend/file_setattr.go b/internal/fusefrontend/file_setattr.go deleted file mode 100644 index 0d6dc48..0000000 --- a/internal/fusefrontend/file_setattr.go +++ /dev/null @@ -1,85 +0,0 @@ -package fusefrontend - -import ( - "context" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -func (f *File) Setattr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { - errno = f.setAttr(ctx, in) - if errno != 0 { - return errno - } - return f.Getattr(ctx, out) -} - -func (f *File) setAttr(ctx context.Context, in *fuse.SetAttrIn) (errno syscall.Errno) { - f.fdLock.RLock() - defer f.fdLock.RUnlock() - if f.released { - tlog.Warn.Printf("ino%d fh%d: Truncate on released file", f.qIno.Ino, f.intFd()) - return syscall.EBADF - } - f.fileTableEntry.ContentLock.Lock() - defer f.fileTableEntry.ContentLock.Unlock() - - // fchmod(2) - if mode, ok := in.GetMode(); ok { - errno = fs.ToErrno(syscall.Fchmod(f.intFd(), mode)) - if errno != 0 { - return errno - } - } - - // fchown(2) - uid32, uOk := in.GetUID() - gid32, gOk := in.GetGID() - if uOk || gOk { - uid := -1 - gid := -1 - - if uOk { - uid = int(uid32) - } - if gOk { - gid = int(gid32) - } - errno = fs.ToErrno(syscall.Fchown(f.intFd(), uid, gid)) - if errno != 0 { - return errno - } - } - - // utimens(2) - mtime, mok := in.GetMTime() - atime, aok := in.GetATime() - if mok || aok { - ap := &atime - mp := &mtime - if !aok { - ap = nil - } - if !mok { - mp = nil - } - errno = fs.ToErrno(syscallcompat.FutimesNano(f.intFd(), ap, mp)) - if errno != 0 { - return errno - } - } - - // truncate(2) - if sz, ok := in.GetSize(); ok { - errno = syscall.Errno(f.truncate(sz)) - if errno != 0 { - return errno - } - } - return 0 -} diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go deleted file mode 100644 index 8370a22..0000000 --- a/internal/fusefrontend/node.go +++ /dev/null @@ -1,449 +0,0 @@ -package fusefrontend - -import ( - "context" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Node is a file or directory in the filesystem tree -// in a gocryptfs mount. -type Node struct { - fs.Inode -} - -// Lookup - FUSE call for discovering a file. -func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // Get device number and inode number into `st` - st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return nil, fs.ToErrno(err) - } - - // Create new inode and fill `out` - ch = n.newChild(ctx, st, out) - - // Translate ciphertext size in `out.Attr.Size` to plaintext size - n.translateSize(dirfd, cName, &out.Attr) - - return ch, 0 -} - -// GetAttr - FUSE call for stat()ing a file. -// -// GetAttr is symlink-safe through use of openBackingDir() and Fstatat(). -func (n *Node) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) (errno syscall.Errno) { - // If the kernel gives us a file handle, use it. - if f != nil { - return f.(fs.FileGetattrer).Getattr(ctx, out) - } - - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return fs.ToErrno(err) - } - - // Fix inode number - rn := n.rootNode() - rn.inoMap.TranslateStat(st) - out.Attr.FromStat(st) - - // Translate ciphertext size in `out.Attr.Size` to plaintext size - n.translateSize(dirfd, cName, &out.Attr) - - if rn.args.ForceOwner != nil { - out.Owner = *rn.args.ForceOwner - } - return 0 -} - -// Unlink - FUSE call. Delete a file. -// -// Symlink-safe through use of Unlinkat(). -func (n *Node) Unlink(ctx context.Context, name string) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // Delete content - err := syscallcompat.Unlinkat(dirfd, cName, 0) - if err != nil { - return fs.ToErrno(err) - } - // Delete ".name" file - if !n.rootNode().args.PlaintextNames && nametransform.IsLongContent(cName) { - err = nametransform.DeleteLongNameAt(dirfd, cName) - if err != nil { - tlog.Warn.Printf("Unlink: could not delete .name file: %v", err) - } - } - return fs.ToErrno(err) -} - -// Readlink - FUSE call. -// -// Symlink-safe through openBackingDir() + Readlinkat(). -func (n *Node) Readlink(ctx context.Context) (out []byte, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - return n.readlink(dirfd, cName) -} - -// Setattr - FUSE call. Called for chmod, truncate, utimens, ... -func (n *Node) Setattr(ctx context.Context, f fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) { - // Use the fd if the kernel gave us one - if f != nil { - f2 := f.(*File) - return f2.Setattr(ctx, in, out) - } - - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // chmod(2) - // - // gocryptfs.diriv & gocryptfs.longname.[sha256].name files do NOT get chmod'ed - // or chown'ed with their parent file/dir for simplicity. - // See nametransform/perms.go for details. - if mode, ok := in.GetMode(); ok { - errno = fs.ToErrno(syscallcompat.FchmodatNofollow(dirfd, cName, mode)) - if errno != 0 { - return errno - } - } - - // chown(2) - uid32, uOk := in.GetUID() - gid32, gOk := in.GetGID() - if uOk || gOk { - uid := -1 - gid := -1 - - if uOk { - uid = int(uid32) - } - if gOk { - gid = int(gid32) - } - errno = fs.ToErrno(syscallcompat.Fchownat(dirfd, cName, uid, gid, unix.AT_SYMLINK_NOFOLLOW)) - if errno != 0 { - return errno - } - } - - // utimens(2) - mtime, mok := in.GetMTime() - atime, aok := in.GetATime() - if mok || aok { - ap := &atime - mp := &mtime - if !aok { - ap = nil - } - if !mok { - mp = nil - } - errno = fs.ToErrno(syscallcompat.UtimesNanoAtNofollow(dirfd, cName, ap, mp)) - if errno != 0 { - return errno - } - } - - // For truncate, the user has to have write permissions. That means we can - // depend on opening a RDWR fd and letting the File handle truncate. - if sz, ok := in.GetSize(); ok { - f, _, errno := n.Open(ctx, syscall.O_RDWR) - if errno != 0 { - return errno - } - f2 := f.(*File) - defer f2.Release(ctx) - errno = syscall.Errno(f2.truncate(sz)) - if errno != 0 { - return errno - } - return f2.Getattr(ctx, out) - } - - return n.Getattr(ctx, nil, out) -} - -// StatFs - FUSE call. Returns information about the filesystem. -// -// Symlink-safe because the path is ignored. -func (n *Node) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { - p := n.rootNode().args.Cipherdir - var st syscall.Statfs_t - err := syscall.Statfs(p, &st) - if err != nil { - return fs.ToErrno(err) - } - out.FromStatfsT(&st) - return 0 -} - -// Mknod - FUSE call. Create a device file. -// -// Symlink-safe through use of Mknodat(). -func (n *Node) Mknod(ctx context.Context, name string, mode, rdev uint32, out *fuse.EntryOut) (inode *fs.Inode, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // Make sure context is nil if we don't want to preserve the owner - rn := n.rootNode() - if !rn.args.PreserveOwner { - ctx = nil - } - - // Create ".name" file to store long file name (except in PlaintextNames mode) - var err error - ctx2 := toFuseCtx(ctx) - if !rn.args.PlaintextNames && nametransform.IsLongContent(cName) { - err := rn.nameTransform.WriteLongNameAt(dirfd, cName, name) - if err != nil { - errno = fs.ToErrno(err) - return - } - // Create "gocryptfs.longfile." device node - err = syscallcompat.MknodatUser(dirfd, cName, mode, int(rdev), ctx2) - if err != nil { - nametransform.DeleteLongNameAt(dirfd, cName) - } - } else { - // Create regular device node - err = syscallcompat.MknodatUser(dirfd, cName, mode, int(rdev), ctx2) - } - if err != nil { - errno = fs.ToErrno(err) - return - } - - st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - errno = fs.ToErrno(err) - return - } - inode = n.newChild(ctx, st, out) - return inode, 0 -} - -// Link - FUSE call. Creates a hard link at "newPath" pointing to file -// "oldPath". -// -// Symlink-safe through use of Linkat(). -func (n *Node) Link(ctx context.Context, target fs.InodeEmbedder, name string, out *fuse.EntryOut) (inode *fs.Inode, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - n2 := toNode(target) - dirfd2, cName2, errno := n2.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd2) - - // Handle long file name (except in PlaintextNames mode) - rn := n.rootNode() - var err error - if !rn.args.PlaintextNames && nametransform.IsLongContent(cName) { - err = rn.nameTransform.WriteLongNameAt(dirfd, cName, name) - if err != nil { - errno = fs.ToErrno(err) - return - } - // Create "gocryptfs.longfile." link - err = unix.Linkat(dirfd2, cName2, dirfd, cName, 0) - if err != nil { - nametransform.DeleteLongNameAt(dirfd, cName) - } - } else { - // Create regular link - err = unix.Linkat(dirfd2, cName2, dirfd, cName, 0) - } - if err != nil { - errno = fs.ToErrno(err) - return - } - - st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - errno = fs.ToErrno(err) - return - } - inode = n.newChild(ctx, st, out) - return inode, 0 -} - -// Symlink - FUSE call. Create a symlink. -// -// Symlink-safe through use of Symlinkat. -func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.EntryOut) (inode *fs.Inode, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // Make sure context is nil if we don't want to preserve the owner - rn := n.rootNode() - if !rn.args.PreserveOwner { - ctx = nil - } - - cTarget := target - if !rn.args.PlaintextNames { - // Symlinks are encrypted like file contents (GCM) and base64-encoded - cTarget = rn.encryptSymlinkTarget(target) - } - // Create ".name" file to store long file name (except in PlaintextNames mode) - var err error - ctx2 := toFuseCtx(ctx) - if !rn.args.PlaintextNames && nametransform.IsLongContent(cName) { - err = rn.nameTransform.WriteLongNameAt(dirfd, cName, name) - if err != nil { - errno = fs.ToErrno(err) - return - } - // Create "gocryptfs.longfile." symlink - err = syscallcompat.SymlinkatUser(cTarget, dirfd, cName, ctx2) - if err != nil { - nametransform.DeleteLongNameAt(dirfd, cName) - } - } else { - // Create symlink - err = syscallcompat.SymlinkatUser(cTarget, dirfd, cName, ctx2) - } - - st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - errno = fs.ToErrno(err) - return - } - // Report the plaintext size, not the encrypted blob size - st.Size = int64(len(target)) - - inode = n.newChild(ctx, st, out) - return inode, 0 -} - -// xfstests generic/013 now also exercises RENAME_EXCHANGE and RENAME_WHITEOUT, -// uncovering lots of problems with longnames -// -// Reject those flags with syscall.EINVAL. -// If we can handle the flags, this function returns 0. -func rejectRenameFlags(flags uint32) syscall.Errno { - // Normal rename, we can handle that - if flags == 0 { - return 0 - } - // We also can handle RENAME_NOREPLACE - if flags == syscallcompat.RENAME_NOREPLACE { - return 0 - } - // We cannot handle RENAME_EXCHANGE and RENAME_WHITEOUT yet. - // Needs extra code for .name files. - return syscall.EINVAL -} - -// Rename - FUSE call. -// This function is called on the PARENT DIRECTORY of `name`. -// -// Symlink-safe through Renameat(). -func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) (errno syscall.Errno) { - if errno = rejectRenameFlags(flags); errno != 0 { - return errno - } - - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - n2 := toNode(newParent) - dirfd2, cName2, errno := n2.prepareAtSyscall(newName) - if errno != 0 { - return - } - defer syscall.Close(dirfd2) - - // Easy case. - rn := n.rootNode() - if rn.args.PlaintextNames { - return fs.ToErrno(syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, uint(flags))) - } - // Long destination file name: create .name file - nameFileAlreadyThere := false - var err error - if nametransform.IsLongContent(cName2) { - err = rn.nameTransform.WriteLongNameAt(dirfd2, cName2, newName) - // Failure to write the .name file is expected when the target path already - // exists. Since hashes are pretty unique, there is no need to modify the - // .name file in this case, and we ignore the error. - if err == syscall.EEXIST { - nameFileAlreadyThere = true - } else if err != nil { - return fs.ToErrno(err) - } - } - // Actual rename - tlog.Debug.Printf("Renameat %d/%s -> %d/%s\n", dirfd, cName, dirfd2, cName2) - err = syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, uint(flags)) - if (flags&syscallcompat.RENAME_NOREPLACE == 0) && (err == syscall.ENOTEMPTY || err == syscall.EEXIST) { - // If an empty directory is overwritten we will always get an error as - // the "empty" directory will still contain gocryptfs.diriv. - // Interestingly, ext4 returns ENOTEMPTY while xfs returns EEXIST. - // We handle that by trying to fs.Rmdir() the target directory and trying - // again. - tlog.Debug.Printf("Rename: Handling ENOTEMPTY") - if n2.Rmdir(ctx, newName) == 0 { - err = syscallcompat.Renameat2(dirfd, cName, dirfd2, cName2, uint(flags)) - } - } - if err != nil { - if nametransform.IsLongContent(cName2) && nameFileAlreadyThere == false { - // Roll back .name creation unless the .name file was already there - nametransform.DeleteLongNameAt(dirfd2, cName2) - } - return fs.ToErrno(err) - } - if nametransform.IsLongContent(cName) { - nametransform.DeleteLongNameAt(dirfd, cName) - } - return 0 -} diff --git a/internal/fusefrontend/node_api_check.go b/internal/fusefrontend/node_api_check.go deleted file mode 100644 index 0f60c74..0000000 --- a/internal/fusefrontend/node_api_check.go +++ /dev/null @@ -1,31 +0,0 @@ -package fusefrontend - -import ( - "github.com/hanwen/go-fuse/v2/fs" -) - -// Check that we have implemented the fs.Node* interfaces -var _ = (fs.NodeGetattrer)((*Node)(nil)) -var _ = (fs.NodeLookuper)((*Node)(nil)) -var _ = (fs.NodeReaddirer)((*Node)(nil)) -var _ = (fs.NodeCreater)((*Node)(nil)) -var _ = (fs.NodeMkdirer)((*Node)(nil)) -var _ = (fs.NodeRmdirer)((*Node)(nil)) -var _ = (fs.NodeUnlinker)((*Node)(nil)) -var _ = (fs.NodeReadlinker)((*Node)(nil)) -var _ = (fs.NodeOpener)((*Node)(nil)) -var _ = (fs.NodeOpendirer)((*Node)(nil)) -var _ = (fs.NodeSetattrer)((*Node)(nil)) -var _ = (fs.NodeStatfser)((*Node)(nil)) -var _ = (fs.NodeMknoder)((*Node)(nil)) -var _ = (fs.NodeLinker)((*Node)(nil)) -var _ = (fs.NodeSymlinker)((*Node)(nil)) -var _ = (fs.NodeRenamer)((*Node)(nil)) -var _ = (fs.NodeGetxattrer)((*Node)(nil)) -var _ = (fs.NodeSetxattrer)((*Node)(nil)) -var _ = (fs.NodeRemovexattrer)((*Node)(nil)) -var _ = (fs.NodeListxattrer)((*Node)(nil)) - -/* TODO -var _ = (fs.NodeCopyFileRanger)((*Node)(nil)) -*/ diff --git a/internal/fusefrontend/node_dir_ops.go b/internal/fusefrontend/node_dir_ops.go deleted file mode 100644 index 001c23a..0000000 --- a/internal/fusefrontend/node_dir_ops.go +++ /dev/null @@ -1,376 +0,0 @@ -package fusefrontend - -import ( - "context" - "fmt" - "io" - "path/filepath" - "runtime" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -const dsStoreName = ".DS_Store" - -// haveDsstore return true if one of the entries in "names" is ".DS_Store". -func haveDsstore(entries []fuse.DirEntry) bool { - for _, e := range entries { - if e.Name == dsStoreName { - return true - } - } - return false -} - -// mkdirWithIv - create a new directory and corresponding diriv file. dirfd -// should be a handle to the parent directory, cName is the name of the new -// directory and mode specifies the access permissions to use. -func (n *Node) mkdirWithIv(dirfd int, cName string, mode uint32, context *fuse.Context) error { - rn := n.rootNode() - // Between the creation of the directory and the creation of gocryptfs.diriv - // the directory is inconsistent. Take the lock to prevent other readers - // from seeing it. - rn.dirIVLock.Lock() - defer rn.dirIVLock.Unlock() - err := syscallcompat.MkdiratUser(dirfd, cName, mode, context) - if err != nil { - return err - } - dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_DIRECTORY|syscall.O_NOFOLLOW|syscallcompat.O_PATH, 0) - if err == nil { - // Create gocryptfs.diriv - err = nametransform.WriteDirIVAt(dirfd2) - syscall.Close(dirfd2) - } - if err != nil { - // Delete inconsistent directory (missing gocryptfs.diriv!) - err2 := syscallcompat.Unlinkat(dirfd, cName, unix.AT_REMOVEDIR) - if err2 != nil { - tlog.Warn.Printf("mkdirWithIv: rollback failed: %v", err2) - } - } - return err -} - -// Mkdir - FUSE call. Create a directory at "newPath" with permissions "mode". -// -// Symlink-safe through use of Mkdirat(). -func (n *Node) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return nil, errno - } - defer syscall.Close(dirfd) - - rn := n.rootNode() - var context *fuse.Context - if rn.args.PreserveOwner { - context = toFuseCtx(ctx) - } - - var st syscall.Stat_t - if rn.args.PlaintextNames { - err := syscallcompat.MkdiratUser(dirfd, cName, mode, context) - if err != nil { - return nil, fs.ToErrno(err) - } - var ust unix.Stat_t - err = syscallcompat.Fstatat(dirfd, cName, &ust, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return nil, fs.ToErrno(err) - } - st = syscallcompat.Unix2syscall(ust) - } else { - // We need write and execute permissions to create gocryptfs.diriv. - // Also, we need read permissions to open the directory (to avoid - // race-conditions between getting and setting the mode). - origMode := mode - mode = mode | 0700 - - // Handle long file name - if nametransform.IsLongContent(cName) { - // Create ".name" - err := rn.nameTransform.WriteLongNameAt(dirfd, cName, name) - if err != nil { - return nil, fs.ToErrno(err) - } - - // Create directory - err = rn.mkdirWithIv(dirfd, cName, mode, context) - if err != nil { - nametransform.DeleteLongNameAt(dirfd, cName) - return nil, fs.ToErrno(err) - } - } else { - err := rn.mkdirWithIv(dirfd, cName, mode, context) - if err != nil { - return nil, fs.ToErrno(err) - } - } - - fd, err := syscallcompat.Openat(dirfd, cName, - syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - tlog.Warn.Printf("Mkdir %q: Openat failed: %v", cName, err) - return nil, fs.ToErrno(err) - } - defer syscall.Close(fd) - - err = syscall.Fstat(fd, &st) - if err != nil { - tlog.Warn.Printf("Mkdir %q: Fstat failed: %v", cName, err) - return nil, fs.ToErrno(err) - } - - // Fix permissions - if origMode != mode { - // Preserve SGID bit if it was set due to inheritance. - origMode = uint32(st.Mode&^0777) | origMode - err = syscall.Fchmod(fd, origMode) - if err != nil { - tlog.Warn.Printf("Mkdir %q: Fchmod %#o -> %#o failed: %v", cName, mode, origMode, err) - } - } - } - - // Create child node - ch := n.newChild(ctx, &st, out) - - return ch, 0 -} - -// Readdir - FUSE call. -// -// This function is symlink-safe through use of openBackingDir() and -// ReadDirIVAt(). -func (n *Node) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { - parentDirFd, cDirName, errno := n.prepareAtSyscall("") - if errno != 0 { - return nil, errno - } - defer syscall.Close(parentDirFd) - - // Read ciphertext directory - fd, err := syscallcompat.Openat(parentDirFd, cDirName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - return nil, fs.ToErrno(err) - } - defer syscall.Close(fd) - cipherEntries, specialEntries, err := syscallcompat.GetdentsSpecial(fd) - if err != nil { - return nil, fs.ToErrno(err) - } - // Get DirIV (stays nil if PlaintextNames is used) - var cachedIV []byte - rn := n.rootNode() - if !rn.args.PlaintextNames { - // Read the DirIV from disk - cachedIV, err = nametransform.ReadDirIVAt(fd) - if err != nil { - tlog.Warn.Printf("OpenDir %q: could not read %s: %v", cDirName, nametransform.DirIVFilename, err) - return nil, syscall.EIO - } - } - // Decrypted directory entries - var plain []fuse.DirEntry - // Add "." and ".." - plain = append(plain, specialEntries...) - // Filter and decrypt filenames - for i := range cipherEntries { - cName := cipherEntries[i].Name - if n.IsRoot() && cName == configfile.ConfDefaultName { - // silently ignore "gocryptfs.conf" in the top level dir - continue - } - if rn.args.PlaintextNames { - plain = append(plain, cipherEntries[i]) - continue - } - if cName == nametransform.DirIVFilename { - // silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled - continue - } - // Handle long file name - isLong := nametransform.LongNameNone - if rn.args.LongNames { - isLong = nametransform.NameType(cName) - } - if isLong == nametransform.LongNameContent { - cNameLong, err := nametransform.ReadLongNameAt(fd, cName) - if err != nil { - tlog.Warn.Printf("OpenDir %q: invalid entry %q: Could not read .name: %v", - cDirName, cName, err) - rn.reportMitigatedCorruption(cName) - continue - } - cName = cNameLong - } else if isLong == nametransform.LongNameFilename { - // ignore "gocryptfs.longname.*.name" - continue - } - name, err := rn.nameTransform.DecryptName(cName, cachedIV) - if err != nil { - tlog.Warn.Printf("OpenDir %q: invalid entry %q: %v", - cDirName, cName, err) - rn.reportMitigatedCorruption(cName) - continue - } - // Override the ciphertext name with the plaintext name but reuse the rest - // of the structure - cipherEntries[i].Name = name - plain = append(plain, cipherEntries[i]) - } - - return fs.NewListDirStream(plain), 0 -} - -// Rmdir - FUSE call. -// -// Symlink-safe through Unlinkat() + AT_REMOVEDIR. -func (n *Node) Rmdir(ctx context.Context, name string) (code syscall.Errno) { - rn := n.rootNode() - p := filepath.Join(n.Path(), name) - parentDirFd, cName, err := rn.openBackingDir(p) - if err != nil { - return fs.ToErrno(err) - } - defer syscall.Close(parentDirFd) - if rn.args.PlaintextNames { - // Unlinkat with AT_REMOVEDIR is equivalent to Rmdir - err = unix.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) - return fs.ToErrno(err) - } - // Unless we are running as root, we need read, write and execute permissions - // to handle gocryptfs.diriv. - permWorkaround := false - var origMode uint32 - if !rn.args.PreserveOwner { - var st unix.Stat_t - err = syscallcompat.Fstatat(parentDirFd, cName, &st, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return fs.ToErrno(err) - } - if st.Mode&0700 != 0700 { - tlog.Debug.Printf("Rmdir: permWorkaround") - permWorkaround = true - // This cast is needed on Darwin, where st.Mode is uint16. - origMode = uint32(st.Mode) - err = syscallcompat.FchmodatNofollow(parentDirFd, cName, origMode|0700) - if err != nil { - tlog.Debug.Printf("Rmdir: permWorkaround: chmod failed: %v", err) - return fs.ToErrno(err) - } - } - } - dirfd, err := syscallcompat.Openat(parentDirFd, cName, - syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - tlog.Debug.Printf("Rmdir: Open: %v", err) - return fs.ToErrno(err) - } - defer syscall.Close(dirfd) - // Undo the chmod if removing the directory failed. This must run before - // closing dirfd, so defer it after (defer is LIFO). - if permWorkaround { - defer func() { - if code != 0 { - err = unix.Fchmod(dirfd, origMode) - if err != nil { - tlog.Warn.Printf("Rmdir: permWorkaround: rollback failed: %v", err) - } - } - }() - } -retry: - // Check directory contents - children, err := syscallcompat.Getdents(dirfd) - if err == io.EOF { - // The directory is empty - tlog.Warn.Printf("Rmdir: %q: %s is missing", cName, nametransform.DirIVFilename) - err = unix.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) - return fs.ToErrno(err) - } - if err != nil { - tlog.Warn.Printf("Rmdir: Getdents: %v", err) - return fs.ToErrno(err) - } - // MacOS sprinkles .DS_Store files everywhere. This is hard to avoid for - // users, so handle it transparently here. - if runtime.GOOS == "darwin" && len(children) <= 2 && haveDsstore(children) { - err = unix.Unlinkat(dirfd, dsStoreName, 0) - if err != nil { - tlog.Warn.Printf("Rmdir: failed to delete blocking file %q: %v", dsStoreName, err) - return fs.ToErrno(err) - } - tlog.Warn.Printf("Rmdir: had to delete blocking file %q", dsStoreName) - goto retry - } - // If the directory is not empty besides gocryptfs.diriv, do not even - // attempt the dance around gocryptfs.diriv. - if len(children) > 1 { - return fs.ToErrno(syscall.ENOTEMPTY) - } - // Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ" - tmpName := fmt.Sprintf("%s.rmdir.%d", nametransform.DirIVFilename, cryptocore.RandUint64()) - tlog.Debug.Printf("Rmdir: Renaming %s to %s", nametransform.DirIVFilename, tmpName) - // The directory is in an inconsistent state between rename and rmdir. - // Protect against concurrent readers. - rn.dirIVLock.Lock() - defer rn.dirIVLock.Unlock() - err = syscallcompat.Renameat(dirfd, nametransform.DirIVFilename, - parentDirFd, tmpName) - if err != nil { - tlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", - nametransform.DirIVFilename, tmpName, err) - return fs.ToErrno(err) - } - // Actual Rmdir - err = syscallcompat.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR) - if err != nil { - // This can happen if another file in the directory was created in the - // meantime, undo the rename - err2 := syscallcompat.Renameat(parentDirFd, tmpName, - dirfd, nametransform.DirIVFilename) - if err2 != nil { - tlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2) - } - return fs.ToErrno(err) - } - // Delete "gocryptfs.diriv.rmdir.XYZ" - err = syscallcompat.Unlinkat(parentDirFd, tmpName, 0) - if err != nil { - tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err) - } - // Delete .name file - if nametransform.IsLongContent(cName) { - nametransform.DeleteLongNameAt(parentDirFd, cName) - } - return 0 -} - -// Opendir is a FUSE call to check if the directory can be opened. -func (n *Node) Opendir(ctx context.Context) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // Open backing directory - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - return fs.ToErrno(err) - } - syscall.Close(fd) - return 0 -} diff --git a/internal/fusefrontend/node_helpers.go b/internal/fusefrontend/node_helpers.go deleted file mode 100644 index b2f1d4a..0000000 --- a/internal/fusefrontend/node_helpers.go +++ /dev/null @@ -1,177 +0,0 @@ -package fusefrontend - -import ( - "context" - "log" - "path/filepath" - "sync/atomic" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// toFuseCtx tries to extract a fuse.Context from a generic context.Context. -func toFuseCtx(ctx context.Context) (ctx2 *fuse.Context) { - if ctx == nil { - return nil - } - if caller, ok := fuse.FromContext(ctx); ok { - ctx2 = &fuse.Context{ - Caller: *caller, - } - } - return ctx2 -} - -// toNode casts a generic fs.InodeEmbedder into *Node. Also handles *RootNode -// by return rn.Node. -func toNode(op fs.InodeEmbedder) *Node { - if r, ok := op.(*RootNode); ok { - return &r.Node - } - return op.(*Node) -} - -// readlink reads and decrypts a symlink. Used by Readlink, Getattr, Lookup. -func (n *Node) readlink(dirfd int, cName string) (out []byte, errno syscall.Errno) { - cTarget, err := syscallcompat.Readlinkat(dirfd, cName) - if err != nil { - return nil, fs.ToErrno(err) - } - rn := n.rootNode() - if rn.args.PlaintextNames { - return []byte(cTarget), 0 - } - // Symlinks are encrypted like file contents (GCM) and base64-encoded - target, err := rn.decryptSymlinkTarget(cTarget) - if err != nil { - tlog.Warn.Printf("Readlink %q: decrypting target failed: %v", cName, err) - return nil, syscall.EIO - } - return []byte(target), 0 -} - -// translateSize translates the ciphertext size in `out` into plaintext size. -// Handles regular files & symlinks (and finds out what is what by looking at -// `out.Mode`). -func (n *Node) translateSize(dirfd int, cName string, out *fuse.Attr) { - if out.IsRegular() { - rn := n.rootNode() - out.Size = rn.contentEnc.CipherSizeToPlainSize(out.Size) - } else if out.IsSymlink() { - target, _ := n.readlink(dirfd, cName) - out.Size = uint64(len(target)) - } -} - -// Path returns the relative plaintext path of this node -func (n *Node) Path() string { - return n.Inode.Path(n.Root()) -} - -// rootNode returns the Root Node of the filesystem. -func (n *Node) rootNode() *RootNode { - return n.Root().Operations().(*RootNode) -} - -// prepareAtSyscall returns a (dirfd, cName) pair that can be used -// with the "___at" family of system calls (openat, fstatat, unlinkat...) to -// access the backing encrypted directory. -// -// If you pass a `child` file name, the (dirfd, cName) pair will refer to -// a child of this node. -// If `child` is empty, the (dirfd, cName) pair refers to this node itself. For -// the root node, that means (dirfd, "."). -func (n *Node) prepareAtSyscall(child string) (dirfd int, cName string, errno syscall.Errno) { - rn := n.rootNode() - // all filesystem operations go through prepareAtSyscall(), so this is a - // good place to reset the idle marker. - atomic.StoreUint32(&rn.IsIdle, 0) - - // root node itself is special - if child == "" && n.IsRoot() { - var err error - dirfd, cName, err = rn.openBackingDir("") - if err != nil { - errno = fs.ToErrno(err) - } - return - } - - // normal node itself can be converted to child of parent node - if child == "" { - name, p1 := n.Parent() - if p1 == nil || name == "" { - return -1, "", syscall.ENOENT - } - p2 := toNode(p1.Operations()) - return p2.prepareAtSyscall(name) - } - - // Cache lookup - // TODO make it work for plaintextnames as well? - cacheable := (!rn.args.PlaintextNames) - if cacheable { - var iv []byte - dirfd, iv = rn.dirCache.Lookup(n) - if dirfd > 0 { - cName, err := rn.nameTransform.EncryptAndHashName(child, iv) - if err != nil { - return -1, "", fs.ToErrno(err) - } - return dirfd, cName, 0 - } - } - - // Slowpath - if child == "" { - log.Panicf("BUG: child name is empty - this cannot happen") - } - p := filepath.Join(n.Path(), child) - if rn.isFiltered(p) { - errno = syscall.EPERM - return - } - dirfd, cName, err := rn.openBackingDir(p) - if err != nil { - errno = fs.ToErrno(err) - return - } - - // Cache store - if cacheable { - // TODO: openBackingDir already calls ReadDirIVAt(). Avoid duplicate work? - iv, err := nametransform.ReadDirIVAt(dirfd) - if err != nil { - syscall.Close(dirfd) - return -1, "", fs.ToErrno(err) - } - rn.dirCache.Store(n, dirfd, iv) - } - return -} - -// newChild attaches a new child inode to n. -// The passed-in `st` will be modified to get a unique inode number -// (or, in `-sharedstorage` mode, the inode number will be set to zero). -func (n *Node) newChild(ctx context.Context, st *syscall.Stat_t, out *fuse.EntryOut) *fs.Inode { - rn := n.rootNode() - // Get stable inode number based on underlying (device,ino) pair - // (or set to zero in case of `-sharestorage`) - rn.inoMap.TranslateStat(st) - out.Attr.FromStat(st) - // Create child node - id := fs.StableAttr{ - Mode: uint32(st.Mode), - Gen: 1, - Ino: st.Ino, - } - node := &Node{} - return n.NewInode(ctx, node, id) -} diff --git a/internal/fusefrontend/node_open_create.go b/internal/fusefrontend/node_open_create.go deleted file mode 100644 index 8b31932..0000000 --- a/internal/fusefrontend/node_open_create.go +++ /dev/null @@ -1,108 +0,0 @@ -package fusefrontend - -import ( - "context" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Open - FUSE call. Open already-existing file. -// -// Symlink-safe through Openat(). -func (n *Node) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - rn := n.rootNode() - newFlags := rn.mangleOpenFlags(flags) - // Taking this lock makes sure we don't race openWriteOnlyFile() - rn.openWriteOnlyLock.RLock() - defer rn.openWriteOnlyLock.RUnlock() - - if rn.args.KernelCache { - fuseFlags = fuse.FOPEN_KEEP_CACHE - } - - // Open backing file - fd, err := syscallcompat.Openat(dirfd, cName, newFlags, 0) - // Handle a few specific errors - if err != nil { - if err == syscall.EMFILE { - var lim syscall.Rlimit - syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim) - tlog.Warn.Printf("Open %q: too many open files. Current \"ulimit -n\": %d", cName, lim.Cur) - } - if err == syscall.EACCES && (int(flags)&syscall.O_ACCMODE) == syscall.O_WRONLY { - fd, err = rn.openWriteOnlyFile(dirfd, cName, newFlags) - } - } - // Could not handle the error? Bail out - if err != nil { - errno = fs.ToErrno(err) - return - } - fh, _, errno = NewFile(fd, cName, rn) - return fh, fuseFlags, errno -} - -// Create - FUSE call. Creates a new file. -// -// Symlink-safe through the use of Openat(). -func (n *Node) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (inode *fs.Inode, fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall(name) - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - var err error - fd := -1 - // Make sure context is nil if we don't want to preserve the owner - rn := n.rootNode() - if !rn.args.PreserveOwner { - ctx = nil - } - newFlags := rn.mangleOpenFlags(flags) - // Handle long file name - ctx2 := toFuseCtx(ctx) - if !rn.args.PlaintextNames && nametransform.IsLongContent(cName) { - // Create ".name" - err = rn.nameTransform.WriteLongNameAt(dirfd, cName, name) - if err != nil { - return nil, nil, 0, fs.ToErrno(err) - } - // Create content - fd, err = syscallcompat.OpenatUser(dirfd, cName, newFlags|syscall.O_CREAT|syscall.O_EXCL, mode, ctx2) - if err != nil { - nametransform.DeleteLongNameAt(dirfd, cName) - } - } else { - // Create content, normal (short) file name - fd, err = syscallcompat.OpenatUser(dirfd, cName, newFlags|syscall.O_CREAT|syscall.O_EXCL, mode, ctx2) - } - if err != nil { - // xfstests generic/488 triggers this - if err == syscall.EMFILE { - var lim syscall.Rlimit - syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim) - tlog.Warn.Printf("Create %q: too many open files. Current \"ulimit -n\": %d", cName, lim.Cur) - } - return nil, nil, 0, fs.ToErrno(err) - } - - fh, st, errno := NewFile(fd, cName, rn) - if errno != 0 { - return - } - inode = n.newChild(ctx, st, out) - return inode, fh, fuseFlags, errno -} diff --git a/internal/fusefrontend/node_xattr.go b/internal/fusefrontend/node_xattr.go deleted file mode 100644 index ceb10f1..0000000 --- a/internal/fusefrontend/node_xattr.go +++ /dev/null @@ -1,170 +0,0 @@ -// Package fusefrontend interfaces directly with the go-fuse library. -package fusefrontend - -import ( - "bytes" - "context" - "strings" - "syscall" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// -1 as uint32 -const minus1 = ^uint32(0) - -// xattr names are encrypted like file names, but with a fixed IV. -// Padded with "_xx" for length 16. -var xattrNameIV = []byte("xattr_name_iv_xx") - -// We store encrypted xattrs under this prefix plus the base64-encoded -// encrypted original name. -var xattrStorePrefix = "user.gocryptfs." - -// We get one read of this xattr for each write - -// see https://github.com/rfjakob/gocryptfs/issues/515 for details. -var xattrCapability = "security.capability" - -// isAcl returns true if the attribute name is for storing ACLs -// -// ACLs are passed through without encryption -func isAcl(attr string) bool { - return attr == "system.posix_acl_access" || attr == "system.posix_acl_default" -} - -// GetXAttr - FUSE call. Reads the value of extended attribute "attr". -// -// This function is symlink-safe through Fgetxattr. -func (n *Node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) { - rn := n.rootNode() - // If we are not mounted with -suid, reading the capability xattr does not - // make a lot of sense, so reject the request and gain a massive speedup. - // See https://github.com/rfjakob/gocryptfs/issues/515 . - if !rn.args.Suid && attr == xattrCapability { - // Returning EOPNOTSUPP is what we did till - // ca9e912a28b901387e1dbb85f6c531119f2d5ef2 "fusefrontend: drop xattr user namespace restriction" - // and it did not cause trouble. Seems cleaner than saying ENODATA. - return 0, syscall.EOPNOTSUPP - } - var data []byte - // ACLs are passed through without encryption - if isAcl(attr) { - var errno syscall.Errno - data, errno = n.getXAttr(attr) - if errno != 0 { - return minus1, errno - } - } else { - // encrypted user xattr - cAttr, err := rn.encryptXattrName(attr) - if err != nil { - return minus1, syscall.EIO - } - cData, errno := n.getXAttr(cAttr) - if errno != 0 { - return 0, errno - } - data, err = rn.decryptXattrValue(cData) - if err != nil { - tlog.Warn.Printf("GetXAttr: %v", err) - return minus1, syscall.EIO - } - } - // Caller passes size zero to find out how large their buffer should be - if len(dest) == 0 { - return uint32(len(data)), 0 - } - if len(dest) < len(data) { - return minus1, syscall.ERANGE - } - l := copy(dest, data) - return uint32(l), 0 -} - -// SetXAttr - FUSE call. Set extended attribute. -// -// This function is symlink-safe through Fsetxattr. -func (n *Node) Setxattr(ctx context.Context, attr string, data []byte, flags uint32) syscall.Errno { - rn := n.rootNode() - flags = uint32(filterXattrSetFlags(int(flags))) - - // ACLs are passed through without encryption - if isAcl(attr) { - // result of setting an acl depends on the user doing it - var context *fuse.Context - if rn.args.PreserveOwner { - context = toFuseCtx(ctx) - } - return n.setXAttr(context, attr, data, flags) - } - - cAttr, err := rn.encryptXattrName(attr) - if err != nil { - return syscall.EINVAL - } - cData := rn.encryptXattrValue(data) - return n.setXAttr(nil, cAttr, cData, flags) -} - -// RemoveXAttr - FUSE call. -// -// This function is symlink-safe through Fremovexattr. -func (n *Node) Removexattr(ctx context.Context, attr string) syscall.Errno { - rn := n.rootNode() - - // ACLs are passed through without encryption - if isAcl(attr) { - return n.removeXAttr(attr) - } - - cAttr, err := rn.encryptXattrName(attr) - if err != nil { - return syscall.EINVAL - } - return n.removeXAttr(cAttr) -} - -// ListXAttr - FUSE call. Lists extended attributes on the file at "relPath". -// -// This function is symlink-safe through Flistxattr. -func (n *Node) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errno) { - cNames, errno := n.listXAttr() - if errno != 0 { - return 0, errno - } - rn := n.rootNode() - var buf bytes.Buffer - for _, curName := range cNames { - // ACLs are passed through without encryption - if isAcl(curName) { - buf.WriteString(curName + "\000") - continue - } - if !strings.HasPrefix(curName, xattrStorePrefix) { - continue - } - name, err := rn.decryptXattrName(curName) - if err != nil { - tlog.Warn.Printf("ListXAttr: invalid xattr name %q: %v", curName, err) - rn.reportMitigatedCorruption(curName) - continue - } - // We *used to* encrypt ACLs, which caused a lot of problems. - if isAcl(name) { - tlog.Warn.Printf("ListXAttr: ignoring deprecated encrypted ACL %q = %q", curName, name) - rn.reportMitigatedCorruption(curName) - continue - } - buf.WriteString(name + "\000") - } - // Caller passes size zero to find out how large their buffer should be - if len(dest) == 0 { - return uint32(buf.Len()), 0 - } - if buf.Len() > len(dest) { - return minus1, syscall.ERANGE - } - return uint32(copy(dest, buf.Bytes())), 0 -} diff --git a/internal/fusefrontend/node_xattr_darwin.go b/internal/fusefrontend/node_xattr_darwin.go deleted file mode 100644 index 0f61a5d..0000000 --- a/internal/fusefrontend/node_xattr_darwin.go +++ /dev/null @@ -1,107 +0,0 @@ -package fusefrontend - -import ( - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" -) - -// On Darwin we have to unset XATTR_NOSECURITY 0x0008 -func filterXattrSetFlags(flags int) int { - // See https://opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/sys/xattr.h.auto.html - const XATTR_NOSECURITY = 0x0008 - - return flags &^ XATTR_NOSECURITY -} - -func (n *Node) getXAttr(cAttr string) (out []byte, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // O_NONBLOCK to not block on FIFOs. - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_NONBLOCK, 0) - if err != nil { - return nil, fs.ToErrno(err) - } - defer syscall.Close(fd) - - cData, err := syscallcompat.Fgetxattr(fd, cAttr) - if err != nil { - return nil, fs.ToErrno(err) - } - - return cData, 0 -} - -func (n *Node) setXAttr(context *fuse.Context, cAttr string, cData []byte, flags uint32) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // O_NONBLOCK to not block on FIFOs. - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NONBLOCK, 0) - // Directories cannot be opened read-write. Retry. - if err == syscall.EISDIR { - fd, err = syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK, 0) - } - if err != nil { - fs.ToErrno(err) - } - defer syscall.Close(fd) - - err = unix.Fsetxattr(fd, cAttr, cData, int(flags)) - return fs.ToErrno(err) -} - -func (n *Node) removeXAttr(cAttr string) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // O_NONBLOCK to not block on FIFOs. - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NONBLOCK, 0) - // Directories cannot be opened read-write. Retry. - if err == syscall.EISDIR { - fd, err = syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK, 0) - } - if err != nil { - return fs.ToErrno(err) - } - defer syscall.Close(fd) - - err = unix.Fremovexattr(fd, cAttr) - return fs.ToErrno(err) -} - -func (n *Node) listXAttr() (out []string, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - // O_NONBLOCK to not block on FIFOs. - fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_NONBLOCK, 0) - if err != nil { - return nil, fs.ToErrno(err) - } - defer syscall.Close(fd) - - cNames, err := syscallcompat.Flistxattr(fd) - if err != nil { - return nil, fs.ToErrno(err) - } - return cNames, 0 -} diff --git a/internal/fusefrontend/node_xattr_linux.go b/internal/fusefrontend/node_xattr_linux.go deleted file mode 100644 index 9698282..0000000 --- a/internal/fusefrontend/node_xattr_linux.go +++ /dev/null @@ -1,70 +0,0 @@ -package fusefrontend - -import ( - "fmt" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" -) - -func filterXattrSetFlags(flags int) int { - return flags -} - -func (n *Node) getXAttr(cAttr string) (out []byte, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) - cData, err := syscallcompat.Lgetxattr(procPath, cAttr) - if err != nil { - return nil, fs.ToErrno(err) - } - return cData, 0 -} - -func (n *Node) setXAttr(context *fuse.Context, cAttr string, cData []byte, flags uint32) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) - - return fs.ToErrno(syscallcompat.LsetxattrUser(procPath, cAttr, cData, int(flags), context)) -} - -func (n *Node) removeXAttr(cAttr string) (errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) - return fs.ToErrno(unix.Lremovexattr(procPath, cAttr)) -} - -func (n *Node) listXAttr() (out []string, errno syscall.Errno) { - dirfd, cName, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(dirfd) - - procPath := fmt.Sprintf("/proc/self/fd/%d/%s", dirfd, cName) - cNames, err := syscallcompat.Llistxattr(procPath) - if err != nil { - return nil, fs.ToErrno(err) - } - return cNames, 0 -} diff --git a/internal/fusefrontend/openbackingdir_test.go b/internal/fusefrontend/openbackingdir_test.go deleted file mode 100644 index ba4014f..0000000 --- a/internal/fusefrontend/openbackingdir_test.go +++ /dev/null @@ -1,170 +0,0 @@ -package fusefrontend - -import ( - "strings" - "syscall" - "testing" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestOpenBackingDir(t *testing.T) { - cipherdir := test_helpers.InitFS(t) - t.Logf("cipherdir = %q", cipherdir) - args := Args{ - Cipherdir: cipherdir, - } - rn := newTestFS(args) - out := &fuse.EntryOut{} - - child, errno := rn.Mkdir(nil, "dir1", 0700, out) - if errno != 0 { - t.Fatal(errno) - } - rn.AddChild("dir1", child, false) - dir1 := toNode(child.Operations()) - _, errno = dir1.Mkdir(nil, "dir2", 0700, out) - if errno != 0 { - t.Fatal(errno) - } - - dirfd, cName, err := rn.openBackingDir("") - if err != nil { - t.Fatal(err) - } - if cName != "." { - t.Fatal("cName should be .") - } - syscall.Close(dirfd) - - // Again, but populate the cache for "" by looking up a non-existing file - rn.Lookup(nil, "xyz1234", &fuse.EntryOut{}) - dirfd, cName, err = rn.openBackingDir("") - if err != nil { - t.Fatal(err) - } - if cName != "." { - t.Fatal("cName should be .") - } - - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Error(err) - } - err = syscallcompat.Faccessat(dirfd, ".", unix.R_OK) - if err != nil { - t.Error(err) - } - syscall.Close(dirfd) - - dirfd, cName, err = rn.openBackingDir("dir1") - if err != nil { - t.Fatal(err) - } - if cName == "" { - t.Fatal("cName should not be empty") - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Error(err) - } - syscall.Close(dirfd) - - dirfd, cName, err = rn.openBackingDir("dir1/dir2") - if err != nil { - t.Fatal(err) - } - if cName == "" { - t.Fatal("cName should not be empty") - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Errorf("Faccessat(%d, %q): %v", dirfd, cName, err) - } - syscall.Close(dirfd) - - n255 := strings.Repeat("n", 255) - dir1.Mkdir(nil, n255, 0700, out) - dirfd, cName, err = rn.openBackingDir("dir1/" + n255) - if err != nil { - t.Fatal(err) - } - if cName == "" { - t.Fatal("cName should not be empty") - } - if len(cName) >= 255 { - t.Fatalf("cName is too long: %q", cName) - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Errorf("Faccessat(%d, %q): %v", dirfd, cName, err) - } - syscall.Close(dirfd) -} - -func TestOpenBackingDirPlaintextNames(t *testing.T) { - cipherdir := test_helpers.InitFS(t, "-plaintextnames") - args := Args{ - Cipherdir: cipherdir, - PlaintextNames: true, - } - fs := newTestFS(args) - out := &fuse.EntryOut{} - - _, errno := fs.Mkdir(nil, "dir1", 0700, out) - if errno != 0 { - t.Fatal(errno) - } - _, errno = fs.Mkdir(nil, "dir1/dir2", 0700, out) - if errno != 0 { - t.Fatal(errno) - } - - dirfd, cName, err := fs.openBackingDir("") - if err != nil { - t.Fatal(err) - } - if cName != "." { - t.Fatal("cName should be .") - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Error(err) - } - err = syscallcompat.Faccessat(dirfd, ".", unix.R_OK) - if err != nil { - t.Error(err) - } - syscall.Close(dirfd) - - dirfd, cName, err = fs.openBackingDir("dir1") - if err != nil { - t.Fatal(err) - } - if cName != "dir1" { - t.Fatalf("wrong cName: %q", cName) - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Error(err) - } - syscall.Close(dirfd) - - dirfd, cName, err = fs.openBackingDir("dir1/dir2") - if err != nil { - t.Fatal(err) - } - if cName != "dir2" { - t.Fatalf("wrong cName: %q", cName) - } - err = syscallcompat.Faccessat(dirfd, cName, unix.R_OK) - if err != nil { - t.Error(err) - } - syscall.Close(dirfd) -} diff --git a/internal/fusefrontend/root_node.go b/internal/fusefrontend/root_node.go deleted file mode 100644 index a830cc4..0000000 --- a/internal/fusefrontend/root_node.go +++ /dev/null @@ -1,335 +0,0 @@ -package fusefrontend - -import ( - "os" - "path/filepath" - "strings" - "sync" - "syscall" - "time" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/inomap" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/serialize_reads" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// RootNode is the root of the filesystem tree of Nodes. -type RootNode struct { - Node - // args stores configuration arguments - args Args - // dirIVLock: Lock()ed if any "gocryptfs.diriv" file is modified - // Readers must RLock() it to prevent them from seeing intermediate - // states - dirIVLock sync.RWMutex - // Filename encryption helper - nameTransform nametransform.NameTransformer - // Content encryption helper - contentEnc *contentenc.ContentEnc - // This lock is used by openWriteOnlyFile() to block concurrent opens while - // it relaxes the permissions on a file. - openWriteOnlyLock sync.RWMutex - // MitigatedCorruptions is used to report data corruption that is internally - // mitigated by ignoring the corrupt item. For example, when OpenDir() finds - // a corrupt filename, we still return the other valid filenames. - // The corruption is logged to syslog to inform the user, and in addition, - // the corrupt filename is logged to this channel via - // reportMitigatedCorruption(). - // "gocryptfs -fsck" reads from the channel to also catch these transparently- - // mitigated corruptions. - MitigatedCorruptions chan string - // IsIdle flag is set to zero each time fs.isFiltered() is called - // (uint32 so that it can be reset with CompareAndSwapUint32). - // When -idle was used when mounting, idleMonitor() sets it to 1 - // periodically. - IsIdle uint32 - // dirCache caches directory fds - dirCache dirCache - // inoMap translates inode numbers from different devices to unique inode - // numbers. - inoMap inomap.TranslateStater -} - -func NewRootNode(args Args, c *contentenc.ContentEnc, n nametransform.NameTransformer) *RootNode { - if args.SerializeReads { - serialize_reads.InitSerializer() - } - if len(args.Exclude) > 0 { - tlog.Warn.Printf("Forward mode does not support -exclude") - } - rn := &RootNode{ - args: args, - nameTransform: n, - contentEnc: c, - inoMap: inomap.New(), - } - // In `-sharedstorage` mode we always set the inode number to zero. - // This makes go-fuse generate a new inode number for each lookup. - if args.SharedStorage { - rn.inoMap = &inomap.TranslateStatZero{} - } - return rn -} - -// main.doMount() calls this after unmount -func (rn *RootNode) AfterUnmount() { - // print stats before we exit - rn.dirCache.stats() -} - -// mangleOpenFlags is used by Create() and Open() to convert the open flags the user -// wants to the flags we internally use to open the backing file. -// The returned flags always contain O_NOFOLLOW. -func (rn *RootNode) mangleOpenFlags(flags uint32) (newFlags int) { - newFlags = int(flags) - // Convert WRONLY to RDWR. We always need read access to do read-modify-write cycles. - if (newFlags & syscall.O_ACCMODE) == syscall.O_WRONLY { - newFlags = newFlags ^ os.O_WRONLY | os.O_RDWR - } - // We also cannot open the file in append mode, we need to seek back for RMW - newFlags = newFlags &^ os.O_APPEND - // O_DIRECT accesses must be aligned in both offset and length. Due to our - // crypto header, alignment will be off, even if userspace makes aligned - // accesses. Running xfstests generic/013 on ext4 used to trigger lots of - // EINVAL errors due to missing alignment. Just fall back to buffered IO. - newFlags = newFlags &^ syscallcompat.O_DIRECT - // Create and Open are two separate FUSE operations, so O_CREAT should not - // be part of the open flags. - newFlags = newFlags &^ syscall.O_CREAT - // We always want O_NOFOLLOW to be safe against symlink races - newFlags |= syscall.O_NOFOLLOW - return newFlags -} - -// reportMitigatedCorruption is used to report a corruption that was transparently -// mitigated and did not return an error to the user. Pass the name of the corrupt -// item (filename for OpenDir(), xattr name for ListXAttr() etc). -// See the MitigatedCorruptions channel for more info. -func (rn *RootNode) reportMitigatedCorruption(item string) { - if rn.MitigatedCorruptions == nil { - return - } - select { - case rn.MitigatedCorruptions <- item: - case <-time.After(1 * time.Second): - tlog.Warn.Printf("BUG: reportCorruptItem: timeout") - //debug.PrintStack() - return - } -} - -// isFiltered - check if plaintext "path" should be forbidden -// -// Prevents name clashes with internal files when file names are not encrypted -func (rn *RootNode) isFiltered(path string) bool { - if !rn.args.PlaintextNames { - return false - } - // gocryptfs.conf in the root directory is forbidden - if path == configfile.ConfDefaultName { - tlog.Info.Printf("The name /%s is reserved when -plaintextnames is used\n", - configfile.ConfDefaultName) - return true - } - // Note: gocryptfs.diriv is NOT forbidden because diriv and plaintextnames - // are exclusive - return false -} - -// decryptSymlinkTarget: "cData64" is base64-decoded and decrypted -// like file contents (GCM). -// The empty string decrypts to the empty string. -// -// This function does not do any I/O and is hence symlink-safe. -func (rn *RootNode) decryptSymlinkTarget(cData64 string) (string, error) { - if cData64 == "" { - return "", nil - } - cData, err := rn.nameTransform.B64DecodeString(cData64) - if err != nil { - return "", err - } - data, err := rn.contentEnc.DecryptBlock([]byte(cData), 0, nil) - if err != nil { - return "", err - } - return string(data), nil -} - -// Due to RMW, we always need read permissions on the backing file. This is a -// problem if the file permissions do not allow reading (i.e. 0200 permissions). -// This function works around that problem by chmod'ing the file, obtaining a fd, -// and chmod'ing it back. -func (rn *RootNode) openWriteOnlyFile(dirfd int, cName string, newFlags int) (rwFd int, err error) { - woFd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NOFOLLOW, 0) - if err != nil { - return - } - defer syscall.Close(woFd) - var st syscall.Stat_t - err = syscall.Fstat(woFd, &st) - if err != nil { - return - } - // The cast to uint32 fixes a build failure on Darwin, where st.Mode is uint16. - perms := uint32(st.Mode) - // Verify that we don't have read permissions - if perms&0400 != 0 { - tlog.Warn.Printf("openWriteOnlyFile: unexpected permissions %#o, returning EPERM", perms) - err = syscall.EPERM - return - } - // Upgrade the lock to block other Open()s and downgrade again on return - rn.openWriteOnlyLock.RUnlock() - rn.openWriteOnlyLock.Lock() - defer func() { - rn.openWriteOnlyLock.Unlock() - rn.openWriteOnlyLock.RLock() - }() - // Relax permissions and revert on return - err = syscall.Fchmod(woFd, perms|0400) - if err != nil { - tlog.Warn.Printf("openWriteOnlyFile: changing permissions failed: %v", err) - return - } - defer func() { - err2 := syscall.Fchmod(woFd, perms) - if err2 != nil { - tlog.Warn.Printf("openWriteOnlyFile: reverting permissions failed: %v", err2) - } - }() - return syscallcompat.Openat(dirfd, cName, newFlags, 0) -} - -// openBackingDir opens the parent ciphertext directory of plaintext path -// "relPath". It returns the dirfd (opened with O_PATH) and the encrypted -// basename. -// -// The caller should then use Openat(dirfd, cName, ...) and friends. -// For convenience, if relPath is "", cName is going to be ".". -// -// openBackingDir is secure against symlink races by using Openat and -// ReadDirIVAt. -// -// Retries on EINTR. -func (rn *RootNode) openBackingDir(relPath string) (dirfd int, cName string, err error) { - dirRelPath := nametransform.Dir(relPath) - // With PlaintextNames, we don't need to read DirIVs. Easy. - if rn.args.PlaintextNames { - dirfd, err = syscallcompat.OpenDirNofollow(rn.args.Cipherdir, dirRelPath) - if err != nil { - return -1, "", err - } - // If relPath is empty, cName is ".". - cName = filepath.Base(relPath) - return dirfd, cName, nil - } - // Open cipherdir (following symlinks) - dirfd, err = syscallcompat.Open(rn.args.Cipherdir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) - if err != nil { - return -1, "", err - } - // If relPath is empty, cName is ".". - if relPath == "" { - return dirfd, ".", nil - } - // Walk the directory tree - parts := strings.Split(relPath, "/") - for i, name := range parts { - iv, err := nametransform.ReadDirIVAt(dirfd) - if err != nil { - syscall.Close(dirfd) - return -1, "", err - } - cName, err = rn.nameTransform.EncryptAndHashName(name, iv) - if err != nil { - syscall.Close(dirfd) - return -1, "", err - } - // Last part? We are done. - if i == len(parts)-1 { - break - } - // Not the last part? Descend into next directory. - dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) - syscall.Close(dirfd) - if err != nil { - return -1, "", err - } - dirfd = dirfd2 - } - return dirfd, cName, nil -} - -// encryptSymlinkTarget: "data" is encrypted like file contents (GCM) -// and base64-encoded. -// The empty string encrypts to the empty string. -// -// Symlink-safe because it does not do any I/O. -func (rn *RootNode) encryptSymlinkTarget(data string) (cData64 string) { - if data == "" { - return "" - } - cData := rn.contentEnc.EncryptBlock([]byte(data), 0, nil) - cData64 = rn.nameTransform.B64EncodeToString(cData) - return cData64 -} - -// encryptXattrValue encrypts the xattr value "data". -// The data is encrypted like a file content block, but without binding it to -// a file location (block number and file id are set to zero). -// Special case: an empty value is encrypted to an empty value. -func (rn *RootNode) encryptXattrValue(data []byte) (cData []byte) { - if len(data) == 0 { - return []byte{} - } - return rn.contentEnc.EncryptBlock(data, 0, nil) -} - -// decryptXattrValue decrypts the xattr value "cData". -func (rn *RootNode) decryptXattrValue(cData []byte) (data []byte, err error) { - if len(cData) == 0 { - return []byte{}, nil - } - data, err1 := rn.contentEnc.DecryptBlock([]byte(cData), 0, nil) - if err1 == nil { - return data, nil - } - // This backward compatibility is needed to support old - // file systems having xattr values base64-encoded. - cData, err2 := rn.nameTransform.B64DecodeString(string(cData)) - if err2 != nil { - // Looks like the value was not base64-encoded, but just corrupt. - // Return the original decryption error: err1 - return nil, err1 - } - return rn.contentEnc.DecryptBlock([]byte(cData), 0, nil) -} - -// encryptXattrName transforms "user.foo" to "user.gocryptfs.a5sAd4XAa47f5as6dAf" -func (rn *RootNode) encryptXattrName(attr string) (string, error) { - // xattr names are encrypted like file names, but with a fixed IV. - cAttr, err := rn.nameTransform.EncryptName(attr, xattrNameIV) - if err != nil { - return "", err - } - return xattrStorePrefix + cAttr, nil -} - -func (rn *RootNode) decryptXattrName(cAttr string) (attr string, err error) { - // Reject anything that does not start with "user.gocryptfs." - if !strings.HasPrefix(cAttr, xattrStorePrefix) { - return "", syscall.EINVAL - } - // Strip "user.gocryptfs." prefix - cAttr = cAttr[len(xattrStorePrefix):] - attr, err = rn.nameTransform.DecryptName(cAttr, xattrNameIV) - if err != nil { - return "", err - } - return attr, nil -} diff --git a/internal/fusefrontend/xattr_unit_test.go b/internal/fusefrontend/xattr_unit_test.go deleted file mode 100644 index a0cf4c8..0000000 --- a/internal/fusefrontend/xattr_unit_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package fusefrontend - -// This file is named "xattr_unit_test.go" because there is also a -// "xattr_integration_test.go" in the test/xattr package. - -import ( - "testing" - "time" - - "github.com/hanwen/go-fuse/v2/fs" - - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/nametransform" -) - -func newTestFS(args Args) *RootNode { - // Init crypto backend - key := make([]byte, cryptocore.KeyLen) - cCore := cryptocore.New(key, cryptocore.BackendGoGCM, contentenc.DefaultIVBits, true, false) - cEnc := contentenc.New(cCore, contentenc.DefaultBS, false) - n := nametransform.New(cCore.EMECipher, true, true) - rn := NewRootNode(args, cEnc, n) - oneSec := time.Second - options := &fs.Options{ - EntryTimeout: &oneSec, - AttrTimeout: &oneSec, - } - fs.NewNodeFS(rn, options) - return rn -} - -func TestEncryptDecryptXattrName(t *testing.T) { - fs := newTestFS(Args{}) - attr1 := "user.foo123456789" - cAttr, err := fs.encryptXattrName(attr1) - if err != nil { - t.Fatal(err) - } - t.Logf("cAttr=%v", cAttr) - attr2, err := fs.decryptXattrName(cAttr) - if attr1 != attr2 || err != nil { - t.Fatalf("Decrypt mismatch: %v != %v", attr1, attr2) - } -} diff --git a/internal/fusefrontend_reverse/ctlsock_interface.go b/internal/fusefrontend_reverse/ctlsock_interface.go deleted file mode 100644 index 2157044..0000000 --- a/internal/fusefrontend_reverse/ctlsock_interface.go +++ /dev/null @@ -1,42 +0,0 @@ -package fusefrontend_reverse - -import ( - "path/filepath" - "strings" - - "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/internal/ctlsocksrv" - "github.com/rfjakob/gocryptfs/internal/pathiv" -) - -// Verify that the interface is implemented. -var _ ctlsocksrv.Interface = &RootNode{} - -// EncryptPath implements ctlsock.Backend. -// This is used for the control socket and for the "-exclude" logic. -func (rn *RootNode) EncryptPath(plainPath string) (string, error) { - if rn.args.PlaintextNames || plainPath == "" { - return plainPath, nil - } - cipherPath := "" - parts := strings.Split(plainPath, "/") - for _, part := range parts { - dirIV := pathiv.Derive(cipherPath, pathiv.PurposeDirIV) - encryptedPart, err := rn.nameTransform.EncryptName(part, dirIV) - if err != nil { - return "", err - } - if rn.args.LongNames && len(encryptedPart) > unix.NAME_MAX { - encryptedPart = rn.nameTransform.HashLongName(encryptedPart) - } - cipherPath = filepath.Join(cipherPath, encryptedPart) - } - return cipherPath, nil -} - -// DecryptPath implements ctlsock.Backend -func (rn *RootNode) DecryptPath(cipherPath string) (string, error) { - p, err := rn.decryptPath(cipherPath) - return p, err -} diff --git a/internal/fusefrontend_reverse/excluder.go b/internal/fusefrontend_reverse/excluder.go deleted file mode 100644 index 8a13fa7..0000000 --- a/internal/fusefrontend_reverse/excluder.go +++ /dev/null @@ -1,63 +0,0 @@ -package fusefrontend_reverse - -import ( - "io/ioutil" - "log" - "os" - "strings" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fusefrontend" - "github.com/rfjakob/gocryptfs/internal/tlog" - - "github.com/sabhiram/go-gitignore" -) - -// prepareExcluder creates an object to check if paths are excluded -// based on the patterns specified in the command line. -func prepareExcluder(args fusefrontend.Args) *ignore.GitIgnore { - patterns := getExclusionPatterns(args) - if len(patterns) == 0 { - log.Panic(patterns) - } - excluder, err := ignore.CompileIgnoreLines(patterns...) - if err != nil { - tlog.Fatal.Printf("Error compiling exclusion rules: %v", err) - os.Exit(exitcodes.ExcludeError) - } - return excluder -} - -// getExclusionPatters prepares a list of patterns to be excluded. -// Patterns passed in the -exclude command line option are prefixed -// with a leading '/' to preserve backwards compatibility (before -// wildcard matching was implemented, exclusions always were matched -// against the full path). -func getExclusionPatterns(args fusefrontend.Args) []string { - patterns := make([]string, len(args.Exclude)+len(args.ExcludeWildcard)) - // add -exclude - for i, p := range args.Exclude { - patterns[i] = "/" + p - } - // add -exclude-wildcard - copy(patterns[len(args.Exclude):], args.ExcludeWildcard) - // add -exclude-from - for _, file := range args.ExcludeFrom { - lines, err := getLines(file) - if err != nil { - tlog.Fatal.Printf("Error reading exclusion patterns: %q", err) - os.Exit(exitcodes.ExcludeError) - } - patterns = append(patterns, lines...) - } - return patterns -} - -// getLines reads a file and splits it into lines -func getLines(file string) ([]string, error) { - buffer, err := ioutil.ReadFile(file) - if err != nil { - return nil, err - } - return strings.Split(string(buffer), "\n"), nil -} diff --git a/internal/fusefrontend_reverse/excluder_test.go b/internal/fusefrontend_reverse/excluder_test.go deleted file mode 100644 index d6cfef3..0000000 --- a/internal/fusefrontend_reverse/excluder_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package fusefrontend_reverse - -import ( - "io/ioutil" - "os" - "reflect" - "testing" - - "github.com/rfjakob/gocryptfs/internal/fusefrontend" -) - -func TestShouldPrefixExcludeValuesWithSlash(t *testing.T) { - var args fusefrontend.Args - args.Exclude = []string{"file1", "dir1/file2.txt"} - args.ExcludeWildcard = []string{"*~", "build/*.o"} - - expected := []string{"/file1", "/dir1/file2.txt", "*~", "build/*.o"} - - patterns := getExclusionPatterns(args) - if !reflect.DeepEqual(patterns, expected) { - t.Errorf("expected %q, got %q", expected, patterns) - } -} - -func TestShouldReadExcludePatternsFromFiles(t *testing.T) { - tmpfile1, err := ioutil.TempFile("", "excludetest") - if err != nil { - t.Fatal(err) - } - exclude1 := tmpfile1.Name() - defer os.Remove(exclude1) - defer tmpfile1.Close() - - tmpfile2, err := ioutil.TempFile("", "excludetest") - if err != nil { - t.Fatal(err) - } - exclude2 := tmpfile2.Name() - defer os.Remove(exclude2) - defer tmpfile2.Close() - - tmpfile1.WriteString("file1.1\n") - tmpfile1.WriteString("file1.2\n") - tmpfile2.WriteString("file2.1\n") - tmpfile2.WriteString("file2.2\n") - - var args fusefrontend.Args - args.ExcludeWildcard = []string{"cmdline1"} - args.ExcludeFrom = []string{exclude1, exclude2} - - // An empty string is returned for the last empty line - // It's ignored when the patterns are actually compiled - expected := []string{"cmdline1", "file1.1", "file1.2", "", "file2.1", "file2.2", ""} - - patterns := getExclusionPatterns(args) - if !reflect.DeepEqual(patterns, expected) { - t.Errorf("expected %q, got %q", expected, patterns) - } -} - -func TestShouldReturnFalseIfThereAreNoExclusions(t *testing.T) { - var rfs RootNode - if rfs.isExcludedPlain("any/path") { - t.Error("Should not exclude any path if no exclusions were specified") - } -} - -func TestShouldCallIgnoreParserToCheckExclusion(t *testing.T) { - rfs, ignorerMock := createRFSWithMocks() - - rfs.isExcludedPlain("some/path") - if ignorerMock.calledWith != "some/path" { - t.Error("Failed to call IgnoreParser") - } -} diff --git a/internal/fusefrontend_reverse/file.go b/internal/fusefrontend_reverse/file.go deleted file mode 100644 index 294872f..0000000 --- a/internal/fusefrontend_reverse/file.go +++ /dev/null @@ -1,81 +0,0 @@ -package fusefrontend_reverse - -import ( - "bytes" - "context" - "os" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/contentenc" -) - -type File struct { - // Backing FD - fd *os.File - // File header (contains the IV) - header contentenc.FileHeader - // IV for block 0 - block0IV []byte - // Content encryption helper - contentEnc *contentenc.ContentEnc -} - -// Read - FUSE call -func (f *File) Read(ctx context.Context, buf []byte, ioff int64) (resultData fuse.ReadResult, errno syscall.Errno) { - length := uint64(len(buf)) - off := uint64(ioff) - out := bytes.NewBuffer(buf[:0]) - var header []byte - - // Synthesize file header - if off < contentenc.HeaderLen { - header = f.header.Pack() - // Truncate to requested part - end := int(off) + len(buf) - if end > len(header) { - end = len(header) - } - header = header[off:end] - // Write into output buffer and adjust offsets - out.Write(header) - hLen := uint64(len(header)) - off += hLen - length -= hLen - } - - // Read actual file data - if length > 0 { - fileData, err := f.readBackingFile(off, length) - if err != nil { - return nil, fs.ToErrno(err) - } - if len(fileData) == 0 { - // If we could not read any actual data, we also don't want to - // return the file header. An empty file stays empty in encrypted - // form. - return nil, 0 - } - out.Write(fileData) - } - - return fuse.ReadResultData(out.Bytes()), 0 -} - -// Release - FUSE call, close file -func (f *File) Release(context.Context) syscall.Errno { - return fs.ToErrno(f.fd.Close()) -} - -// Lseek - FUSE call. -func (f *File) Lseek(ctx context.Context, off uint64, whence uint32) (uint64, syscall.Errno) { - plainOff := f.contentEnc.CipherSizeToPlainSize(off) - newPlainOff, err := syscall.Seek(int(f.fd.Fd()), int64(plainOff), int(whence)) - if err != nil { - return 0, fs.ToErrno(err) - } - newOff := f.contentEnc.PlainSizeToCipherSize(uint64(newPlainOff)) - return newOff, 0 -} diff --git a/internal/fusefrontend_reverse/file_api_check.go b/internal/fusefrontend_reverse/file_api_check.go deleted file mode 100644 index b7e59d4..0000000 --- a/internal/fusefrontend_reverse/file_api_check.go +++ /dev/null @@ -1,25 +0,0 @@ -package fusefrontend_reverse - -import ( - "github.com/hanwen/go-fuse/v2/fs" -) - -// Check that we have implemented the fs.File* interfaces -var _ = (fs.FileReader)((*File)(nil)) -var _ = (fs.FileReleaser)((*File)(nil)) -var _ = (fs.FileLseeker)((*File)(nil)) - -/* Not needed -var _ = (fs.FileGetattrer)((*File)(nil)) -var _ = (fs.FileGetlker)((*File)(nil)) -var _ = (fs.FileSetlker)((*File)(nil)) -var _ = (fs.FileSetlkwer)((*File)(nil)) -*/ - -/* Will not implement these - reverse mode is read-only! -var _ = (fs.FileSetattrer)((*File)(nil)) -var _ = (fs.FileWriter)((*File)(nil)) -var _ = (fs.FileFsyncer)((*File)(nil)) -var _ = (fs.FileFlusher)((*File)(nil)) -var _ = (fs.FileAllocater)((*File)(nil)) -*/ diff --git a/internal/fusefrontend_reverse/file_helpers.go b/internal/fusefrontend_reverse/file_helpers.go deleted file mode 100644 index f024e69..0000000 --- a/internal/fusefrontend_reverse/file_helpers.go +++ /dev/null @@ -1,62 +0,0 @@ -package fusefrontend_reverse - -import ( - "bytes" - "io" - "sync" - - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/pathiv" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -var inodeTable sync.Map - -// encryptBlocks - encrypt "plaintext" into a number of ciphertext blocks. -// "plaintext" must already be block-aligned. -func (rf *File) encryptBlocks(plaintext []byte, firstBlockNo uint64, fileID []byte, block0IV []byte) []byte { - inBuf := bytes.NewBuffer(plaintext) - var outBuf bytes.Buffer - bs := int(rf.contentEnc.PlainBS()) - for blockNo := firstBlockNo; inBuf.Len() > 0; blockNo++ { - inBlock := inBuf.Next(bs) - iv := pathiv.BlockIV(block0IV, blockNo) - outBlock := rf.contentEnc.EncryptBlockNonce(inBlock, blockNo, fileID, iv) - outBuf.Write(outBlock) - } - return outBuf.Bytes() -} - -// readBackingFile: read from the backing plaintext file, encrypt it, return the -// ciphertext. -// "off" ... ciphertext offset (must be >= HEADER_LEN) -// "length" ... ciphertext length -func (f *File) readBackingFile(off uint64, length uint64) (out []byte, err error) { - blocks := f.contentEnc.ExplodeCipherRange(off, length) - - // Read the backing plaintext in one go - alignedOffset, alignedLength := contentenc.JointPlaintextRange(blocks) - plaintext := make([]byte, int(alignedLength)) - n, err := f.fd.ReadAt(plaintext, int64(alignedOffset)) - if err != nil && err != io.EOF { - tlog.Warn.Printf("readBackingFile: ReadAt: %s", err.Error()) - return nil, err - } - // Truncate buffer down to actually read bytes - plaintext = plaintext[0:n] - - // Encrypt blocks - ciphertext := f.encryptBlocks(plaintext, blocks[0].BlockNo, f.header.ID, f.block0IV) - - // Crop down to the relevant part - lenHave := len(ciphertext) - skip := blocks[0].Skip - endWant := int(skip + length) - if lenHave > endWant { - out = ciphertext[skip:endWant] - } else if lenHave > int(skip) { - out = ciphertext[skip:lenHave] - } // else: out stays empty, file was smaller than the requested offset - - return out, nil -} diff --git a/internal/fusefrontend_reverse/mocks_test.go b/internal/fusefrontend_reverse/mocks_test.go deleted file mode 100644 index 2d14c1d..0000000 --- a/internal/fusefrontend_reverse/mocks_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package fusefrontend_reverse - -import ( - "github.com/rfjakob/gocryptfs/internal/nametransform" -) - -type IgnoreParserMock struct { - toExclude string - calledWith string -} - -func (parser *IgnoreParserMock) MatchesPath(f string) bool { - parser.calledWith = f - return f == parser.toExclude -} - -type NameTransformMock struct { - nametransform.NameTransform -} - -func (n *NameTransformMock) DecryptName(cipherName string, iv []byte) (string, error) { - return "mockdecrypt_" + cipherName, nil -} - -func createRFSWithMocks() (*RootNode, *IgnoreParserMock) { - ignorerMock := &IgnoreParserMock{} - nameTransformMock := &NameTransformMock{} - var rfs RootNode - rfs.excluder = ignorerMock - rfs.nameTransform = nameTransformMock - return &rfs, ignorerMock -} diff --git a/internal/fusefrontend_reverse/node.go b/internal/fusefrontend_reverse/node.go deleted file mode 100644 index 787b99b..0000000 --- a/internal/fusefrontend_reverse/node.go +++ /dev/null @@ -1,188 +0,0 @@ -package fusefrontend_reverse - -import ( - "context" - "fmt" - "os" - "path/filepath" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/pathiv" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Node is a file or directory in the filesystem tree -// in a `gocryptfs -reverse` mount. -type Node struct { - fs.Inode -} - -// Lookup - FUSE call for discovering a file. -func (n *Node) Lookup(ctx context.Context, cName string, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - var d *dirfdPlus - t := n.lookupFileType(cName) - if t == typeDiriv { - // gocryptfs.diriv - return n.lookupDiriv(ctx, out) - } else if t == typeName { - // gocryptfs.longname.*.name - return n.lookupLongnameName(ctx, cName, out) - } else if t == typeConfig { - // gocryptfs.conf - return n.lookupConf(ctx, out) - } else if t == typeReal { - // real file - d, errno = n.prepareAtSyscall(cName) - //fmt.Printf("Lookup: prepareAtSyscall -> d=%#v, errno=%d\n", d, errno) - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - } - // Get device number and inode number into `st` - st, err := syscallcompat.Fstatat2(d.dirfd, d.pName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return nil, fs.ToErrno(err) - } - // Create new inode and fill `out` - ch = n.newChild(ctx, st, out) - // Translate ciphertext size in `out.Attr.Size` to plaintext size - if t == typeReal { - n.translateSize(d.dirfd, cName, d.pName, &out.Attr) - } - return ch, 0 -} - -// GetAttr - FUSE call for stat()ing a file. -// -// GetAttr is symlink-safe through use of openBackingDir() and Fstatat(). -func (n *Node) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) (errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - - st, err := syscallcompat.Fstatat2(d.dirfd, d.pName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return fs.ToErrno(err) - } - - // Fix inode number - rn := n.rootNode() - rn.inoMap.TranslateStat(st) - out.Attr.FromStat(st) - - // Translate ciphertext size in `out.Attr.Size` to plaintext size - cName := filepath.Base(n.Path()) - n.translateSize(d.dirfd, cName, d.pName, &out.Attr) - - if rn.args.ForceOwner != nil { - out.Owner = *rn.args.ForceOwner - } - return 0 -} - -// Readlink - FUSE call. -// -// Symlink-safe through openBackingDir() + Readlinkat(). -func (n *Node) Readlink(ctx context.Context) (out []byte, errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - - return n.readlink(d.dirfd, d.cName, d.pName) -} - -// Open - FUSE call. Open already-existing file. -// -// Symlink-safe through Openat(). -func (n *Node) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - - fd, err := syscallcompat.Openat(d.dirfd, d.pName, syscall.O_RDONLY|syscall.O_NOFOLLOW, 0) - if err != nil { - errno = fs.ToErrno(err) - return - } - - // Reject access if the file descriptor does not refer to a regular file. - var st syscall.Stat_t - err = syscall.Fstat(fd, &st) - if err != nil { - tlog.Warn.Printf("Open: Fstat error: %v", err) - syscall.Close(fd) - errno = fs.ToErrno(err) - return - } - var a fuse.Attr - a.FromStat(&st) - if !a.IsRegular() { - tlog.Warn.Printf("ino%d: newFile: not a regular file", st.Ino) - syscall.Close(fd) - errno = syscall.EACCES - return - } - // See if we have that inode number already in the table - // (even if Nlink has dropped to 1) - var derivedIVs pathiv.FileIVs - v, found := inodeTable.Load(st.Ino) - if found { - tlog.Debug.Printf("ino%d: newFile: found in the inode table", st.Ino) - derivedIVs = v.(pathiv.FileIVs) - } else { - p := n.Path() - derivedIVs = pathiv.DeriveFile(p) - // Nlink > 1 means there is more than one path to this file. - // Store the derived values so we always return the same data, - // regardless of the path that is used to access the file. - // This means that the first path wins. - if st.Nlink > 1 { - v, found = inodeTable.LoadOrStore(st.Ino, derivedIVs) - if found { - // Another thread has stored a different value before we could. - derivedIVs = v.(pathiv.FileIVs) - } else { - tlog.Debug.Printf("ino%d: newFile: Nlink=%d, stored in the inode table", st.Ino, st.Nlink) - } - } - } - header := contentenc.FileHeader{ - Version: contentenc.CurrentVersion, - ID: derivedIVs.ID, - } - fh = &File{ - fd: os.NewFile(uintptr(fd), fmt.Sprintf("fd%d", fd)), - header: header, - block0IV: derivedIVs.Block0IV, - contentEnc: n.rootNode().contentEnc, - } - return -} - -// StatFs - FUSE call. Returns information about the filesystem. -// -// Symlink-safe because the path is ignored. -func (n *Node) Statfs(ctx context.Context, out *fuse.StatfsOut) syscall.Errno { - p := n.rootNode().args.Cipherdir - var st syscall.Statfs_t - err := syscall.Statfs(p, &st) - if err != nil { - return fs.ToErrno(err) - } - out.FromStatfsT(&st) - return 0 -} diff --git a/internal/fusefrontend_reverse/node_api_check.go b/internal/fusefrontend_reverse/node_api_check.go deleted file mode 100644 index f8ec9ce..0000000 --- a/internal/fusefrontend_reverse/node_api_check.go +++ /dev/null @@ -1,40 +0,0 @@ -package fusefrontend_reverse - -import ( - "github.com/hanwen/go-fuse/v2/fs" -) - -// Check that we have implemented the fs.Node* interfaces -var _ = (fs.NodeGetattrer)((*Node)(nil)) -var _ = (fs.NodeLookuper)((*Node)(nil)) -var _ = (fs.NodeReaddirer)((*Node)(nil)) -var _ = (fs.NodeReadlinker)((*Node)(nil)) -var _ = (fs.NodeOpener)((*Node)(nil)) -var _ = (fs.NodeStatfser)((*Node)(nil)) - -/* -TODO but low prio. reverse mode in gocryptfs v1 did not have xattr support -either. - -var _ = (fs.NodeGetxattrer)((*Node)(nil)) -var _ = (fs.NodeListxattrer)((*Node)(nil)) -*/ - -/* Not needed -var _ = (fs.NodeOpendirer)((*Node)(nil)) -*/ - -/* Will not implement these - reverse mode is read-only! -var _ = (fs.NodeMknoder)((*Node)(nil)) -var _ = (fs.NodeCreater)((*Node)(nil)) -var _ = (fs.NodeMkdirer)((*Node)(nil)) -var _ = (fs.NodeRmdirer)((*Node)(nil)) -var _ = (fs.NodeUnlinker)((*Node)(nil)) -var _ = (fs.NodeSetattrer)((*Node)(nil)) -var _ = (fs.NodeLinker)((*Node)(nil)) -var _ = (fs.NodeSymlinker)((*Node)(nil)) -var _ = (fs.NodeRenamer)((*Node)(nil)) -var _ = (fs.NodeSetxattrer)((*Node)(nil)) -var _ = (fs.NodeRemovexattrer)((*Node)(nil)) -var _ = (fs.NodeCopyFileRanger)((*Node)(nil)) -*/ diff --git a/internal/fusefrontend_reverse/node_dir_ops.go b/internal/fusefrontend_reverse/node_dir_ops.go deleted file mode 100644 index c287284..0000000 --- a/internal/fusefrontend_reverse/node_dir_ops.go +++ /dev/null @@ -1,114 +0,0 @@ -package fusefrontend_reverse - -import ( - "context" - "fmt" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/pathiv" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Readdir - FUSE call. -// -// This function is symlink-safe through use of openBackingDir() and -// ReadDirIVAt(). -func (n *Node) Readdir(ctx context.Context) (stream fs.DirStream, errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - - // Read plaintext directory - var entries []fuse.DirEntry - fd, err := syscallcompat.Openat(d.dirfd, d.pName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - return nil, fs.ToErrno(err) - } - defer syscall.Close(fd) - entries, err = syscallcompat.Getdents(fd) - if err != nil { - return nil, fs.ToErrno(err) - } - - rn := n.rootNode() - - // Filter out excluded entries - entries = rn.excludeDirEntries(d, entries) - - if rn.args.PlaintextNames { - return n.readdirPlaintextnames(entries) - } - - // Virtual files: at least one gocryptfs.diriv file - virtualFiles := []fuse.DirEntry{ - {Mode: virtualFileMode, Name: nametransform.DirIVFilename}, - } - - dirIV := pathiv.Derive(d.cPath, pathiv.PurposeDirIV) - // Encrypt names - for i := range entries { - var cName string - // ".gocryptfs.reverse.conf" in the root directory is mapped to "gocryptfs.conf" - if n.isRoot() && entries[i].Name == configfile.ConfReverseName && - !rn.args.ConfigCustom { - cName = configfile.ConfDefaultName - } else { - cName, err = rn.nameTransform.EncryptName(entries[i].Name, dirIV) - if err != nil { - entries[i].Name = "___GOCRYPTFS_INVALID_NAME___" - continue - } - if len(cName) > unix.NAME_MAX { - cName = rn.nameTransform.HashLongName(cName) - dotNameFile := fuse.DirEntry{ - Mode: virtualFileMode, - Name: cName + nametransform.LongNameSuffix, - } - virtualFiles = append(virtualFiles, dotNameFile) - } - } - entries[i].Name = cName - } - - // Add virtual files - entries = append(entries, virtualFiles...) - return fs.NewListDirStream(entries), 0 -} - -func (n *Node) readdirPlaintextnames(entries []fuse.DirEntry) (stream fs.DirStream, errno syscall.Errno) { - rn := n.rootNode() - // If we are not the root dir or a custom config path was used, we don't - // need to map anything - if !n.isRoot() || rn.args.ConfigCustom { - return fs.NewListDirStream(entries), 0 - } - // We are in the root dir and the default config file name - // ".gocryptfs.reverse.conf" is used. We map it to "gocryptfs.conf". - dupe := -1 - for i := range entries { - if entries[i].Name == configfile.ConfReverseName { - entries[i].Name = configfile.ConfDefaultName - } else if entries[i].Name == configfile.ConfDefaultName { - dupe = i - } - } - if dupe >= 0 { - // Warn the user loudly: The gocryptfs.conf_NAME_COLLISION file will - // throw ENOENT errors that are hard to miss. - tlog.Warn.Printf("The file %q is mapped to %q and shadows another file. Please rename %q in directory %q.", - configfile.ConfReverseName, configfile.ConfDefaultName, configfile.ConfDefaultName, rn.args.Cipherdir) - entries[dupe].Name = "gocryptfs.conf_NAME_COLLISION_" + fmt.Sprintf("%d", cryptocore.RandUint64()) - } - return fs.NewListDirStream(entries), 0 -} diff --git a/internal/fusefrontend_reverse/node_helpers.go b/internal/fusefrontend_reverse/node_helpers.go deleted file mode 100644 index 92f6a87..0000000 --- a/internal/fusefrontend_reverse/node_helpers.go +++ /dev/null @@ -1,231 +0,0 @@ -package fusefrontend_reverse - -import ( - "context" - "path/filepath" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/pathiv" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" -) - -const ( - // File names are padded to 16-byte multiples, encrypted and - // base64-encoded. We can encode at most 176 bytes to stay below the 255 - // bytes limit: - // * base64(176 bytes) = 235 bytes - // * base64(192 bytes) = 256 bytes (over 255!) - // But the PKCS#7 padding is at least one byte. This means we can only use - // 175 bytes for the file name. - shortNameMax = 175 -) - -// translateSize translates the ciphertext size in `out` into plaintext size. -func (n *Node) translateSize(dirfd int, cName string, pName string, out *fuse.Attr) { - if out.IsRegular() { - rn := n.rootNode() - out.Size = rn.contentEnc.PlainSizeToCipherSize(out.Size) - } else if out.IsSymlink() { - cLink, _ := n.readlink(dirfd, cName, pName) - out.Size = uint64(len(cLink)) - } -} - -// Path returns the relative plaintext path of this node -func (n *Node) Path() string { - return n.Inode.Path(n.Root()) -} - -// rootNode returns the Root Node of the filesystem. -func (n *Node) rootNode() *RootNode { - return n.Root().Operations().(*RootNode) -} - -// dirfdPlus gets filled out as we gather information about a node -type dirfdPlus struct { - // fd to the directory, opened with O_DIRECTORY|O_PATH - dirfd int - // Relative plaintext path - pPath string - // Plaintext basename: filepath.Base(pPath) - pName string - // Relative ciphertext path - cPath string - // Ciphertext basename: filepath.Base(cPath) - cName string -} - -// prepareAtSyscall returns a (dirfd, cName) pair that can be used -// with the "___at" family of system calls (openat, fstatat, unlinkat...) to -// access the backing encrypted directory. -// -// If you pass a `child` file name, the (dirfd, cName) pair will refer to -// a child of this node. -// If `child` is empty, the (dirfd, cName) pair refers to this node itself. -func (n *Node) prepareAtSyscall(child string) (d *dirfdPlus, errno syscall.Errno) { - cPath := n.Path() - if child != "" { - cPath = filepath.Join(cPath, child) - } - rn := n.rootNode() - dirfd, pPath, err := rn.openBackingDir(cPath) - if err != nil { - errno = fs.ToErrno(err) - } - d = &dirfdPlus{ - dirfd: dirfd, - pPath: pPath, - pName: filepath.Base(pPath), - cPath: cPath, - cName: filepath.Base(cPath), - } - return -} - -// newChild attaches a new child inode to n. -// The passed-in `st` will be modified to get a unique inode number. -func (n *Node) newChild(ctx context.Context, st *syscall.Stat_t, out *fuse.EntryOut) *fs.Inode { - // Get unique inode number - rn := n.rootNode() - rn.inoMap.TranslateStat(st) - out.Attr.FromStat(st) - // Create child node - id := fs.StableAttr{ - Mode: uint32(st.Mode), - Gen: 1, - Ino: st.Ino, - } - node := &Node{} - return n.NewInode(ctx, node, id) -} - -// isRoot returns true if this node is the root node -func (n *Node) isRoot() bool { - rn := n.rootNode() - return &rn.Node == n -} - -func (n *Node) lookupLongnameName(ctx context.Context, nameFile string, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - - // Find the file the gocryptfs.longname.XYZ.name file belongs to in the - // directory listing - fd, err := syscallcompat.Openat(d.dirfd, d.pName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - errno = fs.ToErrno(err) - return - } - defer syscall.Close(fd) - diriv := pathiv.Derive(d.cPath, pathiv.PurposeDirIV) - rn := n.rootNode() - pName, cFullname, errno := rn.findLongnameParent(fd, diriv, nameFile) - if errno != 0 { - return - } - if rn.isExcludedPlain(filepath.Join(d.cPath, pName)) { - errno = syscall.EPERM - return - } - // Get attrs from parent file - st, err := syscallcompat.Fstatat2(fd, pName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - errno = fs.ToErrno(err) - return - } - var vf *VirtualMemNode - vf, errno = n.newVirtualMemNode([]byte(cFullname), st, inoTagNameFile) - if errno != 0 { - return nil, errno - } - out.Attr = vf.attr - // Create child node - id := fs.StableAttr{Mode: uint32(vf.attr.Mode), Gen: 1, Ino: vf.attr.Ino} - ch = n.NewInode(ctx, vf, id) - return - -} - -// lookupDiriv returns a new Inode for a gocryptfs.diriv file inside `n`. -func (n *Node) lookupDiriv(ctx context.Context, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - d, errno := n.prepareAtSyscall("") - if errno != 0 { - return - } - defer syscall.Close(d.dirfd) - st, err := syscallcompat.Fstatat2(d.dirfd, d.pName, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - errno = fs.ToErrno(err) - return - } - content := pathiv.Derive(d.cPath, pathiv.PurposeDirIV) - var vf *VirtualMemNode - vf, errno = n.newVirtualMemNode(content, st, inoTagDirIV) - if errno != 0 { - return nil, errno - } - out.Attr = vf.attr - // Create child node - id := fs.StableAttr{Mode: uint32(vf.attr.Mode), Gen: 1, Ino: vf.attr.Ino} - ch = n.NewInode(ctx, vf, id) - return -} - -// lookupConf returns a new Inode for the gocryptfs.conf file -func (n *Node) lookupConf(ctx context.Context, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { - rn := n.rootNode() - p := filepath.Join(rn.args.Cipherdir, configfile.ConfReverseName) - var st syscall.Stat_t - err := syscall.Stat(p, &st) - if err != nil { - errno = fs.ToErrno(err) - return - } - // Get unique inode number - rn.inoMap.TranslateStat(&st) - out.Attr.FromStat(&st) - // Create child node - id := fs.StableAttr{ - Mode: uint32(st.Mode), - Gen: 1, - Ino: st.Ino, - } - node := &VirtualConfNode{path: p} - ch = n.NewInode(ctx, node, id) - return -} - -// readlink reads and encrypts a symlink. Used by Readlink, Getattr, Lookup. -func (n *Node) readlink(dirfd int, cName string, pName string) (out []byte, errno syscall.Errno) { - plainTarget, err := syscallcompat.Readlinkat(dirfd, pName) - if err != nil { - errno = fs.ToErrno(err) - return - } - rn := n.rootNode() - if rn.args.PlaintextNames { - return []byte(plainTarget), 0 - } - // Nonce is derived from the relative *ciphertext* path - p := filepath.Join(n.Path(), cName) - nonce := pathiv.Derive(p, pathiv.PurposeSymlinkIV) - // Symlinks are encrypted like file contents and base64-encoded - cBinTarget := rn.contentEnc.EncryptBlockNonce([]byte(plainTarget), 0, nil, nonce) - cTarget := rn.nameTransform.B64EncodeToString(cBinTarget) - // The kernel will reject a symlink target above 4096 chars and return - // and I/O error to the user. Better emit the proper error ourselves. - if len(cTarget) > syscallcompat.PATH_MAX { - errno = syscall.ENAMETOOLONG - return - } - return []byte(cTarget), 0 -} diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go deleted file mode 100644 index 10b0d69..0000000 --- a/internal/fusefrontend_reverse/root_node.go +++ /dev/null @@ -1,120 +0,0 @@ -package fusefrontend_reverse - -import ( - "log" - "path/filepath" - "strings" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/tlog" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/fusefrontend" - "github.com/rfjakob/gocryptfs/internal/inomap" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - - "github.com/sabhiram/go-gitignore" -) - -// RootNode is the root directory in a `gocryptfs -reverse` mount -type RootNode struct { - Node - // Stores configuration arguments - args fusefrontend.Args - // Filename encryption helper - nameTransform nametransform.NameTransformer - // Content encryption helper - contentEnc *contentenc.ContentEnc - // Tests whether a path is excluded (hidden) from the user. Used by -exclude. - excluder ignore.IgnoreParser - // inoMap translates inode numbers from different devices to unique inode - // numbers. - inoMap *inomap.InoMap -} - -// NewRootNode returns an encrypted FUSE overlay filesystem. -// In this case (reverse mode) the backing directory is plain-text and -// ReverseFS provides an encrypted view. -func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n nametransform.NameTransformer) *RootNode { - rn := &RootNode{ - args: args, - nameTransform: n, - contentEnc: c, - inoMap: inomap.New(), - } - if len(args.Exclude) > 0 || len(args.ExcludeWildcard) > 0 || len(args.ExcludeFrom) > 0 { - rn.excluder = prepareExcluder(args) - } - return rn -} - -// You can pass either gocryptfs.longname.XYZ.name or gocryptfs.longname.XYZ. -func (rn *RootNode) findLongnameParent(fd int, diriv []byte, longname string) (pName string, cFullName string, errno syscall.Errno) { - defer func() { - tlog.Debug.Printf("findLongnameParent: %d %x %q -> %q %q %d\n", fd, diriv, longname, pName, cFullName, errno) - }() - if strings.HasSuffix(longname, nametransform.LongNameSuffix) { - longname = nametransform.RemoveLongNameSuffix(longname) - } - entries, err := syscallcompat.Getdents(fd) - if err != nil { - errno = fs.ToErrno(err) - return - } - for _, entry := range entries { - if len(entry.Name) <= shortNameMax { - continue - } - cFullName, err = rn.nameTransform.EncryptName(entry.Name, diriv) - if err != nil { - continue - } - if len(cFullName) <= unix.NAME_MAX { - // Entry should have been skipped by the shortNameMax check above - log.Panic("logic error or wrong shortNameMax constant?") - } - hName := rn.nameTransform.HashLongName(cFullName) - if longname == hName { - pName = entry.Name - break - } - } - if pName == "" { - errno = syscall.ENOENT - return - } - return -} - -// isExcludedPlain finds out if the plaintext path "pPath" is -// excluded (used when -exclude is passed by the user). -func (rn *RootNode) isExcludedPlain(pPath string) bool { - return rn.excluder != nil && rn.excluder.MatchesPath(pPath) -} - -// excludeDirEntries filters out directory entries that are "-exclude"d. -// pDir is the relative plaintext path to the directory these entries are -// from. The entries should be plaintext files. -func (rn *RootNode) excludeDirEntries(d *dirfdPlus, entries []fuse.DirEntry) (filtered []fuse.DirEntry) { - if rn.excluder == nil { - return entries - } - filtered = make([]fuse.DirEntry, 0, len(entries)) - for _, entry := range entries { - // filepath.Join handles the case of pDir="" correctly: - // Join("", "foo") -> "foo". This does not: pDir + "/" + name" - p := filepath.Join(d.pPath, entry.Name) - if rn.isExcludedPlain(p) { - // Skip file - continue - } - filtered = append(filtered, entry) - } - return filtered -} diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go deleted file mode 100644 index f29bbf5..0000000 --- a/internal/fusefrontend_reverse/rpath.go +++ /dev/null @@ -1,123 +0,0 @@ -package fusefrontend_reverse - -import ( - "encoding/base64" - "path/filepath" - "strings" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/pathiv" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// abs basically returns storage dir + "/" + relPath. -// It takes an error parameter so it can directly wrap decryptPath like this: -// a, err := rfs.abs(rfs.decryptPath(relPath)) -// abs never generates an error on its own. In other words, abs(p, nil) never -// fails. -func (rfs *RootNode) abs(relPath string, err error) (string, error) { - if err != nil { - return "", err - } - return filepath.Join(rfs.args.Cipherdir, relPath), nil -} - -// rDecryptName decrypts the ciphertext name "cName", given the dirIV of the -// directory "cName" lies in. The relative plaintext path to the directory -// "pDir" is used if a "gocryptfs.longname.XYZ.name" must be resolved. -func (rfs *RootNode) rDecryptName(cName string, dirIV []byte, pDir string) (pName string, err error) { - nameType := nametransform.NameType(cName) - if nameType == nametransform.LongNameNone { - pName, err = rfs.nameTransform.DecryptName(cName, dirIV) - if err != nil { - // We get lots of decrypt requests for names like ".Trash" that - // are invalid base64. Convert them to ENOENT so the correct - // error gets returned to the user. - if _, ok := err.(base64.CorruptInputError); ok { - return "", syscall.ENOENT - } - // Stat attempts on the link target of encrypted symlinks. - // These are always valid base64 but the length is not a - // multiple of 16. - if err == syscall.EBADMSG { - return "", syscall.ENOENT - } - return "", err - } - } else if nameType == nametransform.LongNameContent { - dirfd, err := syscallcompat.OpenDirNofollow(rfs.args.Cipherdir, filepath.Dir(pDir)) - if err != nil { - return "", err - } - defer syscall.Close(dirfd) - fd, err := syscallcompat.Openat(dirfd, filepath.Base(pDir), syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0) - if err != nil { - return "", err - } - defer syscall.Close(fd) - var errno syscall.Errno - pName, _, errno = rfs.findLongnameParent(fd, dirIV, cName) - if errno != 0 { - return "", errno - } - } else { - // It makes no sense to decrypt a ".name" file. This is a virtual file - // that has no representation in the plaintext filesystem. ".name" - // files should have already been handled in virtualfile.go. - tlog.Warn.Printf("rDecryptName: cannot decrypt virtual file %q", cName) - return "", syscall.EINVAL - } - return pName, nil -} - -// decryptPath decrypts a relative ciphertext path to a relative plaintext -// path. -func (rn *RootNode) decryptPath(cPath string) (string, error) { - if rn.args.PlaintextNames || cPath == "" { - return cPath, nil - } - parts := strings.Split(cPath, "/") - var transformedParts []string - for i := range parts { - // Start at the top and recurse - currentCipherDir := filepath.Join(parts[:i]...) - currentPlainDir := filepath.Join(transformedParts[:i]...) - dirIV := pathiv.Derive(currentCipherDir, pathiv.PurposeDirIV) - transformedPart, err := rn.rDecryptName(parts[i], dirIV, currentPlainDir) - if err != nil { - return "", err - } - transformedParts = append(transformedParts, transformedPart) - } - pRelPath := filepath.Join(transformedParts...) - return pRelPath, nil -} - -// openBackingDir receives an already decrypted relative path -// "pRelPath", opens the directory that contains the target file/dir -// and returns the fd to the directory and the decrypted name of the -// target file. The fd/name pair is intended for use with fchownat and -// friends. -func (rn *RootNode) openBackingDir(cPath string) (dirfd int, pPath string, err error) { - defer func() { - tlog.Debug.Printf("openBackingDir %q -> %d %q %v\n", cPath, dirfd, pPath, err) - }() - dirfd = -1 - pPath, err = rn.decryptPath(cPath) - if err != nil { - return - } - if rn.isExcludedPlain(pPath) { - err = syscall.EPERM - return - } - // Open directory, safe against symlink races - pDir := filepath.Dir(pPath) - dirfd, err = syscallcompat.OpenDirNofollow(rn.args.Cipherdir, pDir) - if err != nil { - return - } - return dirfd, pPath, nil -} diff --git a/internal/fusefrontend_reverse/virtualconf.go b/internal/fusefrontend_reverse/virtualconf.go deleted file mode 100644 index 8620f6d..0000000 --- a/internal/fusefrontend_reverse/virtualconf.go +++ /dev/null @@ -1,55 +0,0 @@ -package fusefrontend_reverse - -import ( - "context" - "sync" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" -) - -var _ = (fs.NodeOpener)((*VirtualConfNode)(nil)) - -type VirtualConfNode struct { - fs.Inode - - path string -} - -func (n *VirtualConfNode) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - fd, err := syscall.Open(n.path, syscall.O_RDONLY, 0) - if err != nil { - errno = fs.ToErrno(err) - return - } - fh = &VirtualConfFile{fd: fd} - return -} - -// Check that we have implemented the fs.File* interfaces -var _ = (fs.FileReader)((*VirtualConfFile)(nil)) -var _ = (fs.FileReleaser)((*VirtualConfFile)(nil)) - -type VirtualConfFile struct { - mu sync.Mutex - fd int -} - -func (f *VirtualConfFile) Read(ctx context.Context, buf []byte, off int64) (res fuse.ReadResult, errno syscall.Errno) { - f.mu.Lock() - defer f.mu.Unlock() - res = fuse.ReadResultFd(uintptr(f.fd), off, len(buf)) - return -} - -func (f *VirtualConfFile) Release(ctx context.Context) syscall.Errno { - f.mu.Lock() - defer f.mu.Unlock() - if f.fd != -1 { - err := syscall.Close(f.fd) - f.fd = -1 - return fs.ToErrno(err) - } - return syscall.EBADF -} diff --git a/internal/fusefrontend_reverse/virtualnode.go b/internal/fusefrontend_reverse/virtualnode.go deleted file mode 100644 index 2ee9548..0000000 --- a/internal/fusefrontend_reverse/virtualnode.go +++ /dev/null @@ -1,117 +0,0 @@ -package fusefrontend_reverse - -import ( - "context" - "log" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/inomap" - "github.com/rfjakob/gocryptfs/internal/nametransform" -) - -const ( - // virtualFileMode is the mode to use for virtual files (gocryptfs.diriv and - // *.name). They are always readable, as stated in func Access - virtualFileMode = syscall.S_IFREG | 0444 - // We use inomap's `Tag` feature to generate unique inode numbers for - // virtual files. These are the tags we use. - inoTagDirIV = 1 - inoTagNameFile = 2 -) - -type fileType int - -// Values returned by lookupFileType -const ( - // A real file/directory/symlink in the backing plaintext directory - typeReal fileType = iota - // A DirIV (gocryptfs.diriv) file - typeDiriv - // A gocryptfs.longname.*.name file for a file with a long name - typeName - // The config file gocryptfs.conf - typeConfig -) - -// lookupFileType returns the type of child file name -// (one of the fileType constants above). Called from Lookup(). -func (n *Node) lookupFileType(cName string) fileType { - rn := n.rootNode() - // In -plaintextname mode, neither diriv nor longname files exist. - if !rn.args.PlaintextNames { - // Is it a gocryptfs.diriv file? - if cName == nametransform.DirIVFilename { - return typeDiriv - } - // Is it a gocryptfs.longname.*.name file? - if t := nametransform.NameType(cName); t == nametransform.LongNameFilename { - return typeName - } - } - // gocryptfs.conf in the root directory. This is passed through to - // .gocryptfs.reverse.conf in the backing plaintext directory. - if n.isRoot() && !rn.args.ConfigCustom && cName == configfile.ConfDefaultName { - return typeConfig - } - return typeReal -} - -// VirtualMemNode is an in-memory node that does not have a representation -// on disk. -type VirtualMemNode struct { - fs.Inode - - // file content - content []byte - // attributes for Getattr() - attr fuse.Attr -} - -// newVirtualMemNode creates a new in-memory file that does not have a representation -// on disk. "content" is the file content. Timestamps and file owner are copied -// from "parentFile" (file descriptor). -// For a "gocryptfs.diriv" file, you would use the parent directory as -// "parentFile". -func (n *Node) newVirtualMemNode(content []byte, parentStat *syscall.Stat_t, inoTag uint8) (vf *VirtualMemNode, errno syscall.Errno) { - if inoTag == 0 { - log.Panicf("BUG: inoTag for virtual file is zero - this will cause ino collisions!") - } - - // Adjust inode number and size - rn := n.rootNode() - st := parentStat - q := inomap.NewQIno(uint64(st.Dev), inoTag, uint64(st.Ino)) - st.Ino = rn.inoMap.Translate(q) - st.Size = int64(len(content)) - st.Mode = virtualFileMode - st.Nlink = 1 - var a fuse.Attr - a.FromStat(st) - - vf = &VirtualMemNode{content: content, attr: a} - return -} - -// Open - FUSE call -func (f *VirtualMemNode) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - return nil, fuse.FOPEN_KEEP_CACHE, 0 -} - -// GetAttr - FUSE call -func (f *VirtualMemNode) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno { - out.Attr = f.attr - return 0 -} - -// Read - FUSE call -func (f *VirtualMemNode) Read(ctx context.Context, fh fs.FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { - end := int(off) + len(dest) - if end > len(f.content) { - end = len(f.content) - } - return fuse.ReadResultData(f.content[off:end]), 0 -} diff --git a/internal/inomap/inomap.go b/internal/inomap/inomap.go deleted file mode 100644 index 0977a46..0000000 --- a/internal/inomap/inomap.go +++ /dev/null @@ -1,117 +0,0 @@ -// inomap translates (Dev, Flags, Ino) tuples to unique uint64 -// inode numbers. -// -// Format of the returned inode numbers: -// -// [spill bit = 0][15 bit namespace id][48 bit passthru inode number] -// [spill bit = 1][63 bit spill inode number ] -// -// Each (Dev, Flags) tuple gets a namespace id assigned. The original inode -// number is then passed through in the lower 48 bits. -// -// If namespace ids are exhaused, or the original id is larger than 48 bits, -// the whole (Dev, Flags, Ino) tuple gets mapped in the spill map, and the -// spill bit is set to 1. -package inomap - -import ( - "log" - "sync" - "syscall" -) - -const ( - // max value of 15 bit namespace id - maxNamespaceId = 1<<15 - 1 - // max value of 48 bit passthru inode number - maxPassthruIno = 1<<48 - 1 - // max value of 63 bit spill inode number - maxSpillIno = 1<<63 - 1 - // bit 63 is used as the spill bit - spillBit = 1 << 63 -) - -// InoMap stores the maps using for inode number translation. -// See package comment for details. -type InoMap struct { - sync.Mutex - // namespaceMap keeps the mapping of (Dev,Flags) tuples to - // 15-bit identifiers (stored in an uint16 with the high bit always zero) - namespaceMap map[namespaceData]uint16 - // spillNext is the next free namespace number in the namespaces map - namespaceNext uint16 - // spill is used once the namespaces map is full - spillMap map[QIno]uint64 - // spillNext is the next free inode number in the spill map - spillNext uint64 -} - -// New returns a new InoMap. -func New() *InoMap { - return &InoMap{ - namespaceMap: make(map[namespaceData]uint16), - namespaceNext: 0, - spillMap: make(map[QIno]uint64), - spillNext: 0, - } -} - -func (m *InoMap) spill(in QIno) (out uint64) { - out, found := m.spillMap[in] - if found { - return out | spillBit - } - if m.spillNext >= maxSpillIno { - log.Panicf("spillMap overflow: spillNext = 0x%x", m.spillNext) - } - out = m.spillNext - m.spillNext++ - m.spillMap[in] = out - return out | spillBit -} - -// Translate maps the passed-in (device, inode) pair to a unique inode number. -func (m *InoMap) Translate(in QIno) (out uint64) { - m.Lock() - defer m.Unlock() - - if in.Ino > maxPassthruIno { - out = m.spill(in) - return out - } - ns, found := m.namespaceMap[in.namespaceData] - // Use existing namespace - if found { - out = uint64(ns)<<48 | in.Ino - return out - } - // No free namespace slots? - if m.namespaceNext >= maxNamespaceId { - out = m.spill(in) - return out - } - ns = m.namespaceNext - m.namespaceNext++ - m.namespaceMap[in.namespaceData] = ns - out = uint64(ns)<<48 | in.Ino - return out -} - -// TranslateStat translates (device, ino) pair contained in "st" into a unique -// inode number and overwrites the ino in "st" with it. -// Convience wrapper around Translate(). -func (m *InoMap) TranslateStat(st *syscall.Stat_t) { - in := QInoFromStat(st) - st.Ino = m.Translate(in) -} - -type TranslateStater interface { - TranslateStat(st *syscall.Stat_t) -} - -// TranslateStatZero always sets st.Ino to zero. Used for `-sharedstorage`. -type TranslateStatZero struct{} - -func (z TranslateStatZero) TranslateStat(st *syscall.Stat_t) { - st.Ino = 0 -} diff --git a/internal/inomap/inomap_test.go b/internal/inomap/inomap_test.go deleted file mode 100644 index 6fbb4ef..0000000 --- a/internal/inomap/inomap_test.go +++ /dev/null @@ -1,160 +0,0 @@ -package inomap - -import ( - "sync" - "testing" -) - -func TestTranslate(t *testing.T) { - m := New() - q := QIno{Ino: 1} - out := m.Translate(q) - if out != 1 { - t.Errorf("expected 1, got %d", out) - } - q.Ino = maxPassthruIno - out = m.Translate(q) - if out < maxPassthruIno { - t.Errorf("got %d", out) - } - out2 := m.Translate(q) - if out2 != out { - t.Errorf("unstable mapping: %d %d", out2, out) - } -} - -func TestTranslateStress(t *testing.T) { - const baseDev = 12345 - m := New() - - // Make sure baseDev gets namespace id zero - var q QIno - q.Dev = baseDev - m.Translate(q) - - var wg sync.WaitGroup - wg.Add(4) - go func() { - // Some normal inode numbers on baseDev - var q QIno - q.Dev = baseDev - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out != i { - t.Errorf("i=%d out=%d", i, out) - break - } - } - wg.Done() - }() - go func() { - // Very high (>maxPassthruIno) inode numbers on baseDev - var q QIno - q.Dev = baseDev - for i := uint64(1); i <= 10000; i++ { - q.Ino = maxPassthruIno + i - out := m.Translate(q) - if out < maxPassthruIno { - t.Errorf("out=%d", out) - break - } - } - wg.Done() - }() - go func() { - // Device 9999999 - var q QIno - q.Dev = 9999999 - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out < maxPassthruIno { - t.Errorf("out=%d", out) - break - } - } - wg.Done() - }() - go func() { - // Device 4444444 - var q QIno - q.Dev = 4444444 - for i := uint64(1); i <= 10000; i++ { - q.Ino = i - out := m.Translate(q) - if out < maxPassthruIno { - t.Errorf("out=%d", out) - break - } - } - wg.Done() - }() - wg.Wait() - if len(m.spillMap) != 10000 { - t.Errorf("len=%d", len(m.spillMap)) - } - if len(m.namespaceMap) != 3 { - t.Errorf("len=%d", len(m.namespaceMap)) - } -} - -func TestSpill(t *testing.T) { - m := New() - var q QIno - q.Ino = maxPassthruIno + 1 - out1 := m.Translate(q) - if out1&spillBit == 0 { - t.Error("spill bit not set") - } - out2 := m.Translate(q) - if out2&spillBit == 0 { - t.Error("spill bit not set") - } - if out1 != out2 { - t.Errorf("unstable mapping: %d vs %d", out1, out2) - } -} - -// TestUniqueness checks that unique (Dev, Flags, Ino) tuples get unique inode -// numbers -func TestUniqueness(t *testing.T) { - m := New() - var q QIno - outMap := make(map[uint64]struct{}) - for q.Dev = 0; q.Dev < 10; q.Dev++ { - for q.Tag = 0; q.Tag < 10; q.Tag++ { - // some go into spill - for q.Ino = maxPassthruIno - 100; q.Ino < maxPassthruIno+100; q.Ino++ { - out := m.Translate(q) - _, found := outMap[out] - if found { - t.Fatalf("inode number %d already used", out) - } - outMap[out] = struct{}{} - } - } - } - if len(outMap) != 10*10*200 { - t.Errorf("%d", len(outMap)) - } -} - -func BenchmarkTranslateSingleDev(b *testing.B) { - m := New() - var q QIno - for n := 0; n < b.N; n++ { - q.Ino = uint64(n % 1000) - m.Translate(q) - } -} - -func BenchmarkTranslateManyDevs(b *testing.B) { - m := New() - var q QIno - for n := 0; n < b.N; n++ { - q.Dev = uint64(n % 10) - q.Ino = uint64(n % 1000) - m.Translate(q) - } -} diff --git a/internal/inomap/qino.go b/internal/inomap/qino.go deleted file mode 100644 index ed514e8..0000000 --- a/internal/inomap/qino.go +++ /dev/null @@ -1,43 +0,0 @@ -package inomap - -import ( - "syscall" -) - -type namespaceData struct { - // Stat_t.Dev is uint64 on 32- and 64-bit Linux - Dev uint64 - // Tag acts like an extension of the Dev field. - // It is used by reverse mode for virtual files. - // Normal (forward) mode does not use it and it - // stays always zero there. - Tag uint8 -} - -// QIno = Qualified Inode number. -// Uniquely identifies a backing file through the device number, -// inode number pair. -type QIno struct { - namespaceData - // Stat_t.Ino is uint64 on 32- and 64-bit Linu - Ino uint64 -} - -// NewQIno returns a filled QIno struct -func NewQIno(dev uint64, tag uint8, ino uint64) QIno { - return QIno{ - namespaceData: namespaceData{ - Dev: dev, - Tag: tag, - }, - Ino: ino, - } -} - -// QInoFromStat fills a new QIno struct with the passed Stat_t info. -func QInoFromStat(st *syscall.Stat_t) QIno { - // There are some architectures that use 32-bit values here - // (darwin, freebsd-32, maybe others). Add an explicit cast to make - // this function work everywhere. - return NewQIno(uint64(st.Dev), 0, uint64(st.Ino)) -} diff --git a/internal/nametransform/diriv.go b/internal/nametransform/diriv.go index 1d27aa5..67635b3 100644 --- a/internal/nametransform/diriv.go +++ b/internal/nametransform/diriv.go @@ -8,9 +8,8 @@ import ( "path/filepath" "syscall" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../cryptocore" + "../syscallcompat" ) const ( @@ -68,7 +67,6 @@ func WriteDirIVAt(dirfd int) error { // https://github.com/rfjakob/gocryptfs/commit/7d38f80a78644c8ec4900cc990bfb894387112ed fd, err := syscallcompat.Openat(dirfd, DirIVFilename, os.O_WRONLY|os.O_CREATE|os.O_EXCL, dirivPerms) if err != nil { - tlog.Warn.Printf("WriteDirIV: Openat: %v", err) return err } // Wrap the fd in an os.File - we need the write retry logic. @@ -77,16 +75,12 @@ func WriteDirIVAt(dirfd int) error { if err != nil { f.Close() // It is normal to get ENOSPC here - if !syscallcompat.IsENOSPC(err) { - tlog.Warn.Printf("WriteDirIV: Write: %v", err) - } // Delete incomplete gocryptfs.diriv file syscallcompat.Unlinkat(dirfd, DirIVFilename, 0) return err } err = f.Close() if err != nil { - tlog.Warn.Printf("WriteDirIV: Close: %v", err) // Delete incomplete gocryptfs.diriv file syscallcompat.Unlinkat(dirfd, DirIVFilename, 0) return err diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go index 74ddb07..21e7714 100644 --- a/internal/nametransform/longnames.go +++ b/internal/nametransform/longnames.go @@ -9,8 +9,7 @@ import ( "strings" "syscall" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/internal/tlog" + "../syscallcompat" ) const ( @@ -113,9 +112,6 @@ func ReadLongNameAt(dirfd int, cName string) (string, error) { // This function is symlink-safe through the use of Unlinkat(). func DeleteLongNameAt(dirfd int, hashName string) error { err := syscallcompat.Unlinkat(dirfd, hashName+LongNameSuffix, 0) - if err != nil { - tlog.Warn.Printf("DeleteLongName: %v", err) - } return err } @@ -141,25 +137,18 @@ func (n *NameTransform) WriteLongNameAt(dirfd int, hashName string, plainName st fdRaw, err := syscallcompat.Openat(dirfd, hashName+LongNameSuffix, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL, namePerms) if err != nil { - // Don't warn if the file already exists - this is allowed for renames - // and should be handled by the caller. - if err != syscall.EEXIST { - tlog.Warn.Printf("WriteLongName: Openat: %v", err) - } return err } fd := os.NewFile(uintptr(fdRaw), hashName+LongNameSuffix) _, err = fd.Write([]byte(cName)) if err != nil { fd.Close() - tlog.Warn.Printf("WriteLongName: Write: %v", err) // Delete incomplete longname file syscallcompat.Unlinkat(dirfd, hashName+LongNameSuffix, 0) return err } err = fd.Close() if err != nil { - tlog.Warn.Printf("WriteLongName: Close: %v", err) // Delete incomplete longname file syscallcompat.Unlinkat(dirfd, hashName+LongNameSuffix, 0) return err diff --git a/internal/nametransform/longnames_test.go b/internal/nametransform/longnames_test.go deleted file mode 100644 index 4210492..0000000 --- a/internal/nametransform/longnames_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package nametransform - -import ( - "testing" -) - -func TestIsLongName(t *testing.T) { - n := "gocryptfs.longname.LkwUdALvV_ANnzQN6ZZMYnxxfARD3IeZWCKnxGJjYmU=.name" - if NameType(n) != LongNameFilename { - t.Errorf("False negative") - } - - n = "gocryptfs.longname.LkwUdALvV_ANnzQN6ZZMYnxxfARD3IeZWCKnxGJjYmU=" - if NameType(n) != LongNameContent { - t.Errorf("False negative") - } - - n = "LkwUdALvV_ANnzQN6ZZMYnxxfARD3IeZWCKnxGJjYmU=" - if NameType(n) != LongNameNone { - t.Errorf("False positive") - } -} - -func TestRemoveLongNameSuffix(t *testing.T) { - filename := "gocryptfs.longname.LkwUdALvV_ANnzQN6ZZMYnxxfARD3IeZWCKnxGJjYmU=.name" - content := "gocryptfs.longname.LkwUdALvV_ANnzQN6ZZMYnxxfARD3IeZWCKnxGJjYmU=" - if RemoveLongNameSuffix(filename) != content { - t.Error(".name suffix not removed") - } -} diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go index ca28230..fc7c7ff 100644 --- a/internal/nametransform/names.go +++ b/internal/nametransform/names.go @@ -8,8 +8,6 @@ import ( "syscall" "github.com/rfjakob/eme" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) const ( @@ -88,22 +86,18 @@ func (n *NameTransform) decryptName(cipherName string, iv []byte) (string, error return "", err } if len(bin) == 0 { - tlog.Warn.Printf("DecryptName: empty input") return "", syscall.EBADMSG } if len(bin)%aes.BlockSize != 0 { - tlog.Debug.Printf("DecryptName %q: decoded length %d is not a multiple of 16", cipherName, len(bin)) return "", syscall.EBADMSG } bin = n.emeCipher.Decrypt(iv, bin) bin, err = unPad16(bin) if err != nil { - tlog.Warn.Printf("DecryptName %q: unPad16 error: %v", cipherName, err) return "", syscall.EBADMSG } plain := string(bin) if err := IsValidName(plain); err != nil { - tlog.Warn.Printf("DecryptName %q: invalid name after decryption: %v", cipherName, err) return "", syscall.EBADMSG } return plain, err @@ -116,7 +110,6 @@ func (n *NameTransform) decryptName(cipherName string, iv []byte) (string, error // to the full (not hashed) name if longname is used. func (n *NameTransform) EncryptName(plainName string, iv []byte) (cipherName64 string, err error) { if err := IsValidName(plainName); err != nil { - tlog.Warn.Printf("EncryptName %q: invalid plainName: %v", plainName, err) return "", syscall.EBADMSG } bin := []byte(plainName) diff --git a/internal/nametransform/names_test.go b/internal/nametransform/names_test.go deleted file mode 100644 index b4e98d4..0000000 --- a/internal/nametransform/names_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package nametransform - -import ( - "bytes" - "strings" - "testing" -) - -func TestPad16(t *testing.T) { - s := [][]byte{ - []byte("foo"), - []byte("12345678901234567"), - []byte("12345678901234567abcdefg"), - } - - for i := range s { - orig := s[i] - padded := pad16(orig) - if len(padded) <= len(orig) { - t.Errorf("Padded length not bigger than orig: %d", len(padded)) - } - if len(padded)%16 != 0 { - t.Errorf("Length is not aligend: %d", len(padded)) - } - unpadded, err := unPad16(padded) - if err != nil { - t.Error("unPad16 returned error:", err) - } - if len(unpadded) != len(orig) { - t.Errorf("Size mismatch: orig=%d unpadded=%d", len(s[i]), len(unpadded)) - } - if !bytes.Equal(orig, unpadded) { - t.Error("Content mismatch orig vs unpadded") - } - } -} - -// TestUnpad16Garbage - unPad16 should never crash on corrupt or malicious inputs -func TestUnpad16Garbage(t *testing.T) { - testCases := [][]byte{ - make([]byte, 0), - make([]byte, 16), - make([]byte, 1), - make([]byte, 17), - bytes.Repeat([]byte{16}, 16), - bytes.Repeat([]byte{17}, 16), - } - for _, v := range testCases { - _, err := unPad16([]byte(v)) - if err == nil { - t.Fail() - } - } -} - -func TestIsValidName(t *testing.T) { - cases := []struct { - in string - want bool - }{ - {"", false}, - {".", false}, - {"..", false}, - {"...", true}, - {"asdasd/asdasd", false}, - {"asdasd\000asdasd", false}, - {"hello", true}, - {strings.Repeat("x", 255), true}, - {strings.Repeat("x", 256), false}, - } - for _, c := range cases { - have := IsValidName(c.in) - if (have == nil) != c.want { - t.Errorf("IsValidName(%q): want %v have %v", c.in, c.want, have) - } - } -} diff --git a/internal/openfiletable/open_file_table.go b/internal/openfiletable/open_file_table.go deleted file mode 100644 index dfd9637..0000000 --- a/internal/openfiletable/open_file_table.go +++ /dev/null @@ -1,103 +0,0 @@ -// Package openfiletable maintains a table of currently opened files, identified -// by the device number + inode number pair. This table is used by fusefrontend -// to centrally store the current file ID and to lock files against concurrent -// writes. -package openfiletable - -import ( - "sync" - "sync/atomic" - - "github.com/rfjakob/gocryptfs/internal/inomap" -) - -// wlock - serializes write accesses to each file (identified by inode number) -// Writing partial blocks means we have to do read-modify-write cycles. We -// really don't want concurrent writes there. -// Concurrent full-block writes could actually be allowed, but are not to -// keep the locking simple. -var t table - -func init() { - t.entries = make(map[inomap.QIno]*Entry) -} - -type table struct { - // writeOpCount counts entry.ContentLock.Lock() calls. As every operation that - // modifies a file should - // call it, this effectively serves as a write-operation counter. - // The variable is accessed without holding any locks so atomic operations - // must be used. It must be the first element of the struct to guarantee - // 64-bit alignment. - writeOpCount uint64 - // Protects map access - sync.Mutex - // Table entries - entries map[inomap.QIno]*Entry -} - -// Entry is an entry in the open file table -type Entry struct { - // Reference count. Protected by the table lock. - refCount int - // ContentLock protects on-disk content from concurrent writes. Every writer - // must take this lock before modifying the file content. - ContentLock countingMutex - // ID is the file ID in the file header. - ID []byte - // IDLock must be taken before reading or writing the ID field in this struct, - // unless you have an exclusive lock on ContentLock. - IDLock sync.Mutex -} - -// Register creates an open file table entry for "qi" (or incrementes the -// reference count if the entry already exists) and returns the entry. -func Register(qi inomap.QIno) *Entry { - t.Lock() - defer t.Unlock() - - e := t.entries[qi] - if e == nil { - e = &Entry{} - t.entries[qi] = e - } - e.refCount++ - return e -} - -// Unregister decrements the reference count for "qi" and deletes the entry from -// the open file table if the reference count reaches 0. -func Unregister(qi inomap.QIno) { - t.Lock() - defer t.Unlock() - - e := t.entries[qi] - e.refCount-- - if e.refCount == 0 { - delete(t.entries, qi) - } -} - -// countingMutex incrementes t.writeLockCount on each Lock() call. -type countingMutex struct { - sync.RWMutex -} - -func (c *countingMutex) Lock() { - c.RWMutex.Lock() - atomic.AddUint64(&t.writeOpCount, 1) -} - -// WriteOpCount returns the write lock counter value. This value is incremented -// each time writeLock.Lock() on a file table entry is called. -func WriteOpCount() uint64 { - return atomic.LoadUint64(&t.writeOpCount) -} - -// CountOpenFiles returns how many entries are currently in the table -// in a threadsafe manner. -func CountOpenFiles() int { - t.Lock() - defer t.Unlock() - return len(t.entries) -} diff --git a/internal/pathiv/pathiv.go b/internal/pathiv/pathiv.go index 08042e9..db0f7af 100644 --- a/internal/pathiv/pathiv.go +++ b/internal/pathiv/pathiv.go @@ -4,7 +4,7 @@ import ( "crypto/sha256" "encoding/binary" - "github.com/rfjakob/gocryptfs/internal/nametransform" + "../nametransform" ) // Purpose identifies for which purpose the IV will be used. This is mixed into the diff --git a/internal/readpassword/extpass_test.go b/internal/readpassword/extpass_test.go deleted file mode 100644 index 9a643a5..0000000 --- a/internal/readpassword/extpass_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package readpassword - -import ( - "os" - "os/exec" - "testing" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -var testPw = []byte("test") - -func TestMain(m *testing.M) { - // Shut up info output - tlog.Info.Enabled = false - os.Exit(m.Run()) -} - -func TestExtpass(t *testing.T) { - p1 := "ads2q4tw41reg52" - p2 := string(readPasswordExtpass([]string{"echo " + p1})) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -func TestOnceExtpass(t *testing.T) { - p1 := "lkadsf0923rdfi48rqwhdsf" - p2 := string(Once([]string{"echo " + p1}, nil, "")) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -// extpass with two arguments -func TestOnceExtpass2(t *testing.T) { - p1 := "foo" - p2 := string(Once([]string{"echo", p1}, nil, "")) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -// extpass with three arguments -func TestOnceExtpass3(t *testing.T) { - p1 := "foo bar baz" - p2 := string(Once([]string{"echo", "foo", "bar", "baz"}, nil, "")) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -func TestOnceExtpassSpaces(t *testing.T) { - p1 := "mypassword" - p2 := string(Once([]string{"cat", "passfile_test_files/file with spaces.txt"}, nil, "")) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -func TestTwiceExtpass(t *testing.T) { - p1 := "w5w44t3wfe45srz434" - p2 := string(Once([]string{"echo " + p1}, nil, "")) - if p1 != p2 { - t.Errorf("p1=%q != p2=%q", p1, p2) - } -} - -// When extpass returns an empty string, we should crash. -// -// The TEST_SLAVE magic is explained at -// https://talks.golang.org/2014/testing.slide#23 . -func TestExtpassEmpty(t *testing.T) { - if os.Getenv("TEST_SLAVE") == "1" { - readPasswordExtpass([]string{"echo"}) - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestExtpassEmpty$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - err := cmd.Run() - if err != nil { - return - } - t.Fatal("empty password should have failed") -} diff --git a/internal/readpassword/passfile.go b/internal/readpassword/passfile.go deleted file mode 100644 index df6cd4d..0000000 --- a/internal/readpassword/passfile.go +++ /dev/null @@ -1,53 +0,0 @@ -package readpassword - -import ( - "bytes" - "os" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// readPassFileConcatenate reads the first line from each file name and -// concatenates the results. The result does not contain any newlines. -func readPassFileConcatenate(passfileSlice []string) (result []byte) { - for _, e := range passfileSlice { - result = append(result, readPassFile(e)...) - } - return result -} - -// readPassFile reads the first line from the passed file name. -func readPassFile(passfile string) []byte { - tlog.Info.Printf("passfile: reading from file %q", passfile) - f, err := os.Open(passfile) - if err != nil { - tlog.Fatal.Printf("fatal: passfile: could not open %q: %v", passfile, err) - os.Exit(exitcodes.ReadPassword) - } - defer f.Close() - // +1 for an optional trailing newline, - // +2 so we can detect if maxPasswordLen is exceeded. - buf := make([]byte, maxPasswordLen+2) - n, err := f.Read(buf) - if err != nil { - tlog.Fatal.Printf("fatal: passfile: could not read from %q: %v", passfile, err) - os.Exit(exitcodes.ReadPassword) - } - buf = buf[:n] - // Split into first line and "trailing garbage" - lines := bytes.SplitN(buf, []byte("\n"), 2) - if len(lines[0]) == 0 { - tlog.Fatal.Printf("fatal: passfile: empty first line in %q", passfile) - os.Exit(exitcodes.ReadPassword) - } - if len(lines[0]) > maxPasswordLen { - tlog.Fatal.Printf("fatal: passfile: max password length (%d bytes) exceeded", maxPasswordLen) - os.Exit(exitcodes.ReadPassword) - } - if len(lines) > 1 && len(lines[1]) > 0 { - tlog.Warn.Printf("warning: passfile: ignoring trailing garbage (%d bytes) after first line", - len(lines[1])) - } - return lines[0] -} diff --git a/internal/readpassword/passfile_test.go b/internal/readpassword/passfile_test.go deleted file mode 100644 index dbfe159..0000000 --- a/internal/readpassword/passfile_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package readpassword - -import ( - "os" - "os/exec" - "testing" -) - -func TestPassfile(t *testing.T) { - testcases := []struct { - file string - want string - }{ - {"mypassword.txt", "mypassword"}, - {"mypassword_garbage.txt", "mypassword"}, - {"mypassword_missing_newline.txt", "mypassword"}, - {"file with spaces.txt", "mypassword"}, - } - for _, tc := range testcases { - pw := readPassFile("passfile_test_files/" + tc.file) - if string(pw) != tc.want { - t.Errorf("Wrong result: want=%q have=%q", tc.want, pw) - } - // Calling readPassFileConcatenate with only one element should give the - // same result - pw = readPassFileConcatenate([]string{"passfile_test_files/" + tc.file}) - if string(pw) != tc.want { - t.Errorf("Wrong result: want=%q have=%q", tc.want, pw) - } - } -} - -// readPassFile() should exit instead of returning an empty string. -// -// The TEST_SLAVE magic is explained at -// https://talks.golang.org/2014/testing.slide#23 , mirror: -// http://web.archive.org/web/20200426174352/https://talks.golang.org/2014/testing.slide#23 -func TestPassfileEmpty(t *testing.T) { - if os.Getenv("TEST_SLAVE") == "1" { - readPassFile("passfile_test_files/empty.txt") - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestPassfileEmpty$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - err := cmd.Run() - if err != nil { - return - } - t.Fatal("should have exited") -} - -// File containing just a newline. -// readPassFile() should exit instead of returning an empty string. -// -// The TEST_SLAVE magic is explained at -// https://talks.golang.org/2014/testing.slide#23 , mirror: -// http://web.archive.org/web/20200426174352/https://talks.golang.org/2014/testing.slide#23 -func TestPassfileNewline(t *testing.T) { - if os.Getenv("TEST_SLAVE") == "1" { - readPassFile("passfile_test_files/newline.txt") - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestPassfileNewline$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - err := cmd.Run() - if err != nil { - return - } - t.Fatal("should have exited") -} - -// File containing "\ngarbage". -// readPassFile() should exit instead of returning an empty string. -// -// The TEST_SLAVE magic is explained at -// https://talks.golang.org/2014/testing.slide#23 , mirror: -// http://web.archive.org/web/20200426174352/https://talks.golang.org/2014/testing.slide#23 -func TestPassfileEmptyFirstLine(t *testing.T) { - if os.Getenv("TEST_SLAVE") == "1" { - readPassFile("passfile_test_files/empty_first_line.txt") - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestPassfileEmptyFirstLine$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - err := cmd.Run() - if err != nil { - return - } - t.Fatal("should have exited") -} - -// TestPassFileConcatenate tests readPassFileConcatenate -func TestPassFileConcatenate(t *testing.T) { - files := []string{ - "passfile_test_files/file with spaces.txt", - "passfile_test_files/mypassword_garbage.txt", - } - res := string(readPassFileConcatenate(files)) - if res != "mypasswordmypassword" { - t.Errorf("wrong result: %q", res) - } -} diff --git a/internal/readpassword/passfile_test_files/empty.txt b/internal/readpassword/passfile_test_files/empty.txt deleted file mode 100644 index e69de29..0000000 diff --git a/internal/readpassword/passfile_test_files/empty_first_line.txt b/internal/readpassword/passfile_test_files/empty_first_line.txt deleted file mode 100644 index a607e80..0000000 --- a/internal/readpassword/passfile_test_files/empty_first_line.txt +++ /dev/null @@ -1,2 +0,0 @@ - -garbage diff --git a/internal/readpassword/passfile_test_files/file with spaces.txt b/internal/readpassword/passfile_test_files/file with spaces.txt deleted file mode 100644 index 48d23cf..0000000 --- a/internal/readpassword/passfile_test_files/file with spaces.txt +++ /dev/null @@ -1 +0,0 @@ -mypassword diff --git a/internal/readpassword/passfile_test_files/mypassword.txt b/internal/readpassword/passfile_test_files/mypassword.txt deleted file mode 100644 index 48d23cf..0000000 --- a/internal/readpassword/passfile_test_files/mypassword.txt +++ /dev/null @@ -1 +0,0 @@ -mypassword diff --git a/internal/readpassword/passfile_test_files/mypassword_garbage.txt b/internal/readpassword/passfile_test_files/mypassword_garbage.txt deleted file mode 100644 index 74ba741..0000000 --- a/internal/readpassword/passfile_test_files/mypassword_garbage.txt +++ /dev/null @@ -1,2 +0,0 @@ -mypassword -garbage diff --git a/internal/readpassword/passfile_test_files/mypassword_missing_newline.txt b/internal/readpassword/passfile_test_files/mypassword_missing_newline.txt deleted file mode 100644 index b3c42b5..0000000 --- a/internal/readpassword/passfile_test_files/mypassword_missing_newline.txt +++ /dev/null @@ -1 +0,0 @@ -mypassword \ No newline at end of file diff --git a/internal/readpassword/passfile_test_files/newline.txt b/internal/readpassword/passfile_test_files/newline.txt deleted file mode 100644 index 8b13789..0000000 --- a/internal/readpassword/passfile_test_files/newline.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/internal/readpassword/read.go b/internal/readpassword/read.go deleted file mode 100644 index e116f0b..0000000 --- a/internal/readpassword/read.go +++ /dev/null @@ -1,159 +0,0 @@ -// Package readpassword reads a password from the terminal of from stdin. -package readpassword - -import ( - "bytes" - "fmt" - "io" - "os" - "os/exec" - "strings" - - "golang.org/x/crypto/ssh/terminal" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -const ( - // 2kB limit like EncFS - maxPasswordLen = 2048 -) - -// Once tries to get a password from the user, either from the terminal, extpass, passfile -// or stdin. Leave "prompt" empty to use the default "Password: " prompt. -func Once(extpass []string, passfile []string, prompt string) []byte { - if len(passfile) != 0 { - return readPassFileConcatenate(passfile) - } - if len(extpass) != 0 { - return readPasswordExtpass(extpass) - } - if prompt == "" { - prompt = "Password" - } - if !terminal.IsTerminal(int(os.Stdin.Fd())) { - return readPasswordStdin(prompt) - } - return readPasswordTerminal(prompt + ": ") -} - -// Twice is the same as Once but will prompt twice if we get the password from -// the terminal. -func Twice(extpass []string, passfile []string) []byte { - if len(passfile) != 0 { - return readPassFileConcatenate(passfile) - } - if len(extpass) != 0 { - return readPasswordExtpass(extpass) - } - if !terminal.IsTerminal(int(os.Stdin.Fd())) { - return readPasswordStdin("Password") - } - p1 := readPasswordTerminal("Password: ") - p2 := readPasswordTerminal("Repeat: ") - if !bytes.Equal(p1, p2) { - tlog.Fatal.Println("Passwords do not match") - os.Exit(exitcodes.ReadPassword) - } - // Wipe the password duplicate from memory - for i := range p2 { - p2[i] = 0 - } - return p1 -} - -// readPasswordTerminal reads a line from the terminal. -// Exits on read error or empty result. -func readPasswordTerminal(prompt string) []byte { - fd := int(os.Stdin.Fd()) - fmt.Fprintf(os.Stderr, prompt) - // terminal.ReadPassword removes the trailing newline - p, err := terminal.ReadPassword(fd) - if err != nil { - tlog.Fatal.Printf("Could not read password from terminal: %v\n", err) - os.Exit(exitcodes.ReadPassword) - } - fmt.Fprintf(os.Stderr, "\n") - if len(p) == 0 { - tlog.Fatal.Println("Password is empty") - os.Exit(exitcodes.PasswordEmpty) - } - return p -} - -// readPasswordStdin reads a line from stdin. -// It exits with a fatal error on read error or empty result. -func readPasswordStdin(prompt string) []byte { - tlog.Info.Printf("Reading %s from stdin", prompt) - p := readLineUnbuffered(os.Stdin) - if len(p) == 0 { - tlog.Fatal.Printf("Got empty %s from stdin", prompt) - os.Exit(exitcodes.ReadPassword) - } - return p -} - -// readPasswordExtpass executes the "extpass" program and returns the first line -// of the output. -// Exits on read error or empty result. -func readPasswordExtpass(extpass []string) []byte { - var parts []string - if len(extpass) == 1 { - parts = strings.Split(extpass[0], " ") - } else { - parts = extpass - } - tlog.Info.Printf("Reading password from extpass program %q, arguments: %q\n", parts[0], parts[1:]) - cmd := exec.Command(parts[0], parts[1:]...) - cmd.Stderr = os.Stderr - pipe, err := cmd.StdoutPipe() - if err != nil { - tlog.Fatal.Printf("extpass pipe setup failed: %v", err) - os.Exit(exitcodes.ReadPassword) - } - err = cmd.Start() - if err != nil { - tlog.Fatal.Printf("extpass cmd start failed: %v", err) - os.Exit(exitcodes.ReadPassword) - } - p := readLineUnbuffered(pipe) - pipe.Close() - err = cmd.Wait() - if err != nil { - tlog.Fatal.Printf("extpass program returned an error: %v", err) - os.Exit(exitcodes.ReadPassword) - } - if len(p) == 0 { - tlog.Fatal.Println("extpass: password is empty") - os.Exit(exitcodes.ReadPassword) - } - return p -} - -// readLineUnbuffered reads single bytes from "r" util it gets "\n" or EOF. -// The returned string does NOT contain the trailing "\n". -func readLineUnbuffered(r io.Reader) (l []byte) { - b := make([]byte, 1) - for { - if len(l) > maxPasswordLen { - tlog.Fatal.Printf("fatal: maximum password length of %d bytes exceeded", maxPasswordLen) - os.Exit(exitcodes.ReadPassword) - } - n, err := r.Read(b) - if err == io.EOF { - return l - } - if err != nil { - tlog.Fatal.Printf("readLineUnbuffered: %v", err) - os.Exit(exitcodes.ReadPassword) - } - if n == 0 { - continue - } - if b[0] == '\n' { - return l - } - l = append(l, b...) - } -} diff --git a/internal/readpassword/stdin_test.go b/internal/readpassword/stdin_test.go deleted file mode 100644 index 01dd701..0000000 --- a/internal/readpassword/stdin_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package readpassword - -import ( - "fmt" - "os" - "os/exec" - "testing" -) - -// Provide password via stdin, terminated by "\n". -func TestStdin(t *testing.T) { - p1 := "g55434t55wef" - if os.Getenv("TEST_SLAVE") == "1" { - p2 := string(readPasswordStdin("foo")) - if p1 != p2 { - fmt.Fprintf(os.Stderr, "%q != %q", p1, p2) - os.Exit(1) - } - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestStdin$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - cmd.Stderr = os.Stderr - pipe, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Fatal(err) - } - n, err := pipe.Write([]byte(p1 + "\n")) - if n == 0 || err != nil { - t.Fatal(err) - } - err = cmd.Wait() - if err != nil { - t.Fatalf("slave failed with %v", err) - } -} - -// Provide password via stdin, terminated by EOF (pipe close). This should not -// hang. -func TestStdinEof(t *testing.T) { - p1 := "asd45as5f4a36" - if os.Getenv("TEST_SLAVE") == "1" { - p2 := string(readPasswordStdin("foo")) - if p1 != p2 { - fmt.Fprintf(os.Stderr, "%q != %q", p1, p2) - os.Exit(1) - } - return - } - cmd := exec.Command(os.Args[0], "-test.run=TestStdinEof$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - cmd.Stderr = os.Stderr - pipe, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Fatal(err) - } - _, err = pipe.Write([]byte(p1)) - if err != nil { - t.Fatal(err) - } - pipe.Close() - err = cmd.Wait() - if err != nil { - t.Fatalf("slave failed with %v", err) - } -} - -// Provide empty password via stdin -func TestStdinEmpty(t *testing.T) { - if os.Getenv("TEST_SLAVE") == "1" { - readPasswordStdin("foo") - } - cmd := exec.Command(os.Args[0], "-test.run=TestStdinEmpty$") - cmd.Env = append(os.Environ(), "TEST_SLAVE=1") - pipe, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Fatal(err) - } - _, err = pipe.Write([]byte("\n")) - if err != nil { - t.Fatal(err) - } - pipe.Close() - err = cmd.Wait() - if err == nil { - t.Fatalf("empty password should have failed") - } -} diff --git a/internal/serialize_reads/sr.go b/internal/serialize_reads/sr.go deleted file mode 100644 index 96cec4f..0000000 --- a/internal/serialize_reads/sr.go +++ /dev/null @@ -1,150 +0,0 @@ -package serialize_reads - -import ( - "log" - "sync" - "time" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// serializerState is used by the Wait and Done functions -type serializerState struct { - // we get submissions through the "input" channel - input chan *submission - // q = Queue - q []*submission - // wg is used to wait for the read to complete before unblocking the next - wg sync.WaitGroup -} - -// Wait places the caller into a queue and blocks -func Wait(offset int64, size int) { - serializer.wait(offset, size) -} - -// Done signals that the read operation has finished -func Done() { - serializer.wg.Done() -} - -type submission struct { - // "ch" is closed by "eventLoop" once it wants to unblock the caller - ch chan struct{} - // submissions are prioritized by offset (lowest offset gets unblocked first) - offset int64 - // size will be used in the future to detect consecutive read requests. These - // can be unblocked immediately. - size int -} - -func (sr *serializerState) wait(offset int64, size int) { - ch := make(chan struct{}) - sb := &submission{ - ch: ch, - offset: offset, - size: size, - } - // Send our submission - sr.input <- sb - // Wait till we get unblocked - <-ch -} - -// push returns true if the queue is full after the element has been stored. -// It panics if it did not have space to store the element. -func (sr *serializerState) push(sb *submission) (full bool) { - free := 0 - stored := false - for i, v := range sr.q { - if v != nil { - continue - } - if !stored { - sr.q[i] = sb - stored = true - continue - } - free++ - } - if !stored { - // This should never happen because eventLoop checks if the queue got full - log.Panic("BUG: unhandled queue overflow") - } - if free == 0 { - return true - } - return false -} - -// pop the submission with the lowest offset off the queue -func (sr *serializerState) pop() *submission { - var winner *submission - var winnerIndex int - for i, v := range sr.q { - if v == nil { - continue - } - if winner == nil { - winner = v - winnerIndex = i - continue - } - if v.offset < winner.offset { - winner = v - winnerIndex = i - } - } - if winner == nil { - return nil - } - sr.q[winnerIndex] = nil - return winner -} - -func (sr *serializerState) eventLoop() { - sr.input = make(chan *submission) - empty := true - for { - if empty { - // If the queue is empty we block on the channel to conserve CPU - sb := <-sr.input - sr.push(sb) - empty = false - } - select { - case sb := <-sr.input: - full := sr.push(sb) - if full { - // Queue is full, unblock the new request immediately - tlog.Warn.Printf("serialize_reads: queue full, forcing unblock") - sr.unblockOne() - } - case <-time.After(time.Microsecond * 500): - // Looks like we have waited out all concurrent requests. - empty = sr.unblockOne() - } - } -} - -// Unblock a submission and wait for completion -func (sr *serializerState) unblockOne() (empty bool) { - winner := sr.pop() - if winner == nil { - return true - } - sr.wg.Add(1) - close(winner.ch) - sr.wg.Wait() - return false -} - -var serializer serializerState - -// InitSerializer sets up the internal serializer state and starts the event loop. -// Called by fusefrontend.NewFS. -func InitSerializer() { - serializer.input = make(chan *submission) - serializer.q = make([]*submission, 10) - go serializer.eventLoop() -} diff --git a/internal/siv_aead/benchmark.bash b/internal/siv_aead/benchmark.bash deleted file mode 100755 index 40b57b3..0000000 --- a/internal/siv_aead/benchmark.bash +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -eu - -cd "$(dirname "$0")" - -../stupidgcm/benchmark.bash diff --git a/internal/siv_aead/correctness_test.go b/internal/siv_aead/correctness_test.go deleted file mode 100644 index b52774b..0000000 --- a/internal/siv_aead/correctness_test.go +++ /dev/null @@ -1,148 +0,0 @@ -package siv_aead - -import ( - "bytes" - "encoding/hex" - "testing" - - "github.com/jacobsa/crypto/siv" -) - -// Test all supported key lengths -func TestKeyLens(t *testing.T) { - keyLens := []int{32, 48, 64} - nonce := make([]byte, 16) - plaintext := []byte("foobar") - for _, keyLen := range keyLens { - key := make([]byte, keyLen) - a := new2(key) - ciphertext2 := a.Seal(nil, nonce, plaintext, nil) - - ciphertext, err := siv.Encrypt(nil, key, plaintext, [][]byte{nil, nonce}) - if err != nil { - t.Error(err) - } else if o := len(ciphertext) - len(plaintext); o != a.Overhead() { - t.Errorf("keyLen=%d, actual overhead: %d\n", keyLen, o) - } - if !bytes.Equal(ciphertext, ciphertext2) { - t.Errorf("siv and siv_aead produce different results") - } - } - -} - -// Test using a 32-byte key -func TestK32(t *testing.T) { - key := bytes.Repeat([]byte{1}, 32) - nonce := bytes.Repeat([]byte{2}, 16) - plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} - aData := make([]byte, 24) - // Compare siv and siv_aead results - sResult, err := siv.Encrypt(nonce, key, plaintext, [][]byte{aData, nonce}) - if err != nil { - t.Fatal(err) - } - a := new2(key) - aResult := a.Seal(nonce, nonce, plaintext, aData) - if !bytes.Equal(sResult, aResult) { - t.Errorf("siv and siv_aead produce different results") - } - expectedResult, _ := hex.DecodeString( - "02020202020202020202020202020202ad7a4010649a84d8c1dd5f752e935eed57d45b8b10008f3834") - if !bytes.Equal(aResult, expectedResult) { - t.Errorf(hex.EncodeToString(aResult)) - } - // Verify overhead - overhead := len(aResult) - len(plaintext) - len(nonce) - if overhead != a.Overhead() { - t.Errorf("Overhead() returns a wrong value") - } - // Decrypt - p1, err := a.Open(nil, aResult[:16], aResult[16:], aData) - if err != nil { - t.Error(err) - } - if !bytes.Equal(plaintext, p1) { - t.Errorf("wrong plaintext") - } - // Decrypt and append - dst := []byte{0xaa, 0xbb, 0xcc} - p2, err := a.Open(dst, aResult[:16], aResult[16:], aData) - if err != nil { - t.Error(err) - } - p2e := append(dst, plaintext...) - if !bytes.Equal(p2e, p2) { - t.Errorf("wrong plaintext: %s", hex.EncodeToString(p2)) - } - // Decrypt corrupt - aResult[17] = 0 - _, err = a.Open(nil, aResult[:16], aResult[16:], aData) - if err == nil { - t.Error("should have failed") - } - // Decrypt and append corrupt - aResult[17] = 0 - _, err = a.Open(dst, aResult[:16], aResult[16:], aData) - if err == nil { - t.Error("should have failed") - } -} - -// Test using a 64-byte key -func TestK64(t *testing.T) { - key := bytes.Repeat([]byte{1}, 64) - nonce := bytes.Repeat([]byte{2}, 16) - plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} - aData := make([]byte, 24) - // Compare siv and siv_aead results - sResult, err := siv.Encrypt(nonce, key, plaintext, [][]byte{aData, nonce}) - if err != nil { - t.Fatal(err) - } - a := New(key) - aResult := a.Seal(nonce, nonce, plaintext, aData) - if !bytes.Equal(sResult, aResult) { - t.Errorf("siv and siv_aead produce different results") - } - expectedResult, _ := hex.DecodeString( - "02020202020202020202020202020202317b316f67c3ad336c01c9a01b4c5e552ba89e966bc4c1ade1") - if !bytes.Equal(aResult, expectedResult) { - t.Errorf(hex.EncodeToString(aResult)) - } - // Verify overhead - overhead := len(aResult) - len(plaintext) - len(nonce) - if overhead != a.Overhead() { - t.Errorf("Overhead() returns a wrong value") - } - // Decrypt - p1, err := a.Open(nil, aResult[:16], aResult[16:], aData) - if err != nil { - t.Error(err) - } - if !bytes.Equal(plaintext, p1) { - t.Errorf("wrong plaintext") - } - // Decrypt and append - dst := []byte{0xaa, 0xbb, 0xcc} - p2, err := a.Open(dst, aResult[:16], aResult[16:], aData) - if err != nil { - t.Error(err) - } - p2e := append(dst, plaintext...) - if !bytes.Equal(p2e, p2) { - t.Errorf("wrong plaintext: %s", hex.EncodeToString(p2)) - } - // Decrypt corrupt - aResult[17] = 0 - _, err = a.Open(nil, aResult[:16], aResult[16:], aData) - if err == nil { - t.Error("should have failed") - } - // Decrypt and append corrupt - aResult[17] = 0 - _, err = a.Open(dst, aResult[:16], aResult[16:], aData) - if err == nil { - t.Error("should have failed") - } -} diff --git a/internal/siv_aead/performance_test.go b/internal/siv_aead/performance_test.go deleted file mode 100644 index 626024e..0000000 --- a/internal/siv_aead/performance_test.go +++ /dev/null @@ -1 +0,0 @@ -package siv_aead diff --git a/internal/speed/benchmark.bash b/internal/speed/benchmark.bash deleted file mode 100755 index d2678a7..0000000 --- a/internal/speed/benchmark.bash +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -eu - -cd "$(dirname "$0")" - -go test -bench . diff --git a/internal/speed/speed.go b/internal/speed/speed.go deleted file mode 100644 index e097c55..0000000 --- a/internal/speed/speed.go +++ /dev/null @@ -1,148 +0,0 @@ -// Package speed implements the "-speed" command-line option, -// similar to "openssl speed". -// It benchmarks the crypto algorithms and libraries used by -// gocryptfs. -package speed - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "fmt" - "log" - "testing" - - "golang.org/x/crypto/chacha20poly1305" - - "github.com/rfjakob/gocryptfs/internal/siv_aead" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" -) - -// 128-bit file ID + 64 bit block number = 192 bits = 24 bytes -const adLen = 24 - -// gocryptfs uses fixed-size 4 kiB blocks -const blockSize = 4096 - -// Run - run the speed the test and print the results. -func Run() { - bTable := []struct { - name string - f func(*testing.B) - preferred bool - }{ - {name: "AES-GCM-256-OpenSSL", f: bStupidGCM, preferred: stupidgcm.PreferOpenSSL()}, - {name: "AES-GCM-256-Go", f: bGoGCM, preferred: !stupidgcm.PreferOpenSSL()}, - {name: "AES-SIV-512-Go", f: bAESSIV, preferred: false}, - {name: "XChaCha20-Poly1305-Go", f: bChacha20poly1305, preferred: false}, - } - for _, b := range bTable { - fmt.Printf("%-20s\t", b.name) - mbs := mbPerSec(testing.Benchmark(b.f)) - if mbs > 0 { - fmt.Printf("%7.2f MB/s", mbs) - } else { - fmt.Printf(" N/A") - } - if b.preferred { - fmt.Printf("\t(selected in auto mode)\n") - } else if b.name == "XChaCha20-Poly1305-Go" { - fmt.Printf("\t(benchmark only, not selectable yet)\n") - } else { - fmt.Printf("\t\n") - } - } -} - -func mbPerSec(r testing.BenchmarkResult) float64 { - if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 { - return 0 - } - return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds() -} - -// Get "n" random bytes from /dev/urandom or panic -func randBytes(n int) []byte { - b := make([]byte, n) - _, err := rand.Read(b) - if err != nil { - log.Panic("Failed to read random bytes: " + err.Error()) - } - return b -} - -// bStupidGCM benchmarks stupidgcm's openssl GCM -func bStupidGCM(b *testing.B) { - if stupidgcm.BuiltWithoutOpenssl { - b.Skip("openssl has been disabled at compile-time") - } - key := randBytes(32) - authData := randBytes(adLen) - iv := randBytes(16) - in := make([]byte, blockSize) - b.SetBytes(int64(len(in))) - - sGCM := stupidgcm.New(key, false) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Encrypt and append to nonce - sGCM.Seal(iv, iv, in, authData) - } -} - -// bGoGCM benchmarks Go stdlib GCM -func bGoGCM(b *testing.B) { - key := randBytes(32) - authData := randBytes(adLen) - iv := randBytes(16) - in := make([]byte, blockSize) - b.SetBytes(int64(len(in))) - - gAES, err := aes.NewCipher(key) - if err != nil { - b.Fatal(err) - } - gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Encrypt and append to nonce - gGCM.Seal(iv, iv, in, authData) - } -} - -// bAESSIV benchmarks AES-SIV from github.com/jacobsa/crypto/siv -func bAESSIV(b *testing.B) { - key := randBytes(64) - authData := randBytes(adLen) - iv := randBytes(16) - in := make([]byte, blockSize) - b.SetBytes(int64(len(in))) - gGCM := siv_aead.New(key) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Encrypt and append to nonce - gGCM.Seal(iv, iv, in, authData) - } -} - -// bChacha20poly1305 benchmarks XChaCha20 from golang.org/x/crypto/chacha20poly1305 -func bChacha20poly1305(b *testing.B) { - key := randBytes(32) - authData := randBytes(adLen) - iv := randBytes(chacha20poly1305.NonceSizeX) - in := make([]byte, blockSize) - b.SetBytes(int64(len(in))) - c, _ := chacha20poly1305.NewX(key) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - // Encrypt and append to nonce - c.Seal(iv, iv, in, authData) - } -} diff --git a/internal/speed/speed_test.go b/internal/speed/speed_test.go deleted file mode 100644 index 1e9d859..0000000 --- a/internal/speed/speed_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package speed - -/* -Make the "-speed" benchmarks also accessible to the standard test system. -Example run: - -$ go test -bench . -BenchmarkStupidGCM-2 100000 22552 ns/op 181.62 MB/s -BenchmarkGoGCM-2 20000 81871 ns/op 50.03 MB/s -BenchmarkAESSIV-2 10000 104623 ns/op 39.15 MB/s -PASS -ok github.com/rfjakob/gocryptfs/internal/speed 6.022s -*/ - -import ( - "testing" -) - -func BenchmarkStupidGCM(b *testing.B) { - bStupidGCM(b) -} - -func BenchmarkGoGCM(b *testing.B) { - bGoGCM(b) -} - -func BenchmarkAESSIV(b *testing.B) { - bAESSIV(b) -} diff --git a/internal/stupidgcm/stupidgcm_test.go b/internal/stupidgcm/stupidgcm_test.go deleted file mode 100644 index 18732df..0000000 --- a/internal/stupidgcm/stupidgcm_test.go +++ /dev/null @@ -1,195 +0,0 @@ -// +build !without_openssl - -// We compare against Go's built-in GCM implementation. Since stupidgcm only -// supports 128-bit IVs and Go only supports that from 1.5 onward, we cannot -// run these tests on older Go versions. -package stupidgcm - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/hex" - "log" - "testing" -) - -// Get "n" random bytes from /dev/urandom or panic -func randBytes(n int) []byte { - b := make([]byte, n) - _, err := rand.Read(b) - if err != nil { - log.Panic("Failed to read random bytes: " + err.Error()) - } - return b -} - -// TestEncryptDecrypt encrypts and decrypts using both stupidgcm and Go's built-in -// GCM implementation and verifies that the results are identical. -func TestEncryptDecrypt(t *testing.T) { - key := randBytes(32) - sGCM := New(key, false) - authData := randBytes(24) - iv := randBytes(16) - dst := make([]byte, 71) // 71 = random length - - gAES, err := aes.NewCipher(key) - if err != nil { - t.Fatal(err) - } - gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) - if err != nil { - t.Fatal(err) - } - - // Check all block sizes from 1 to 5000 - for i := 1; i < 5000; i++ { - in := make([]byte, i) - - sOut := sGCM.Seal(dst, iv, in, authData) - gOut := gGCM.Seal(dst, iv, in, authData) - - // Ciphertext must be identical to Go GCM - if !bytes.Equal(sOut, gOut) { - t.Fatalf("Compare failed for encryption, size %d", i) - t.Log("sOut:") - t.Log("\n" + hex.Dump(sOut)) - t.Log("gOut:") - t.Log("\n" + hex.Dump(gOut)) - } - - sOut2, sErr := sGCM.Open(dst, iv, sOut[len(dst):], authData) - if sErr != nil { - t.Fatal(sErr) - } - gOut2, gErr := gGCM.Open(dst, iv, gOut[len(dst):], authData) - if gErr != nil { - t.Fatal(gErr) - } - - // Plaintext must be identical to Go GCM - if !bytes.Equal(sOut2, gOut2) { - t.Fatalf("Compare failed for decryption, size %d", i) - } - } -} - -// Seal re-uses the "dst" buffer it is large enough. -// Check that this works correctly by testing different "dst" capacities from -// 5000 to 16 and "in" lengths from 1 to 5000. -func TestInplaceSeal(t *testing.T) { - key := randBytes(32) - sGCM := New(key, false) - authData := randBytes(24) - iv := randBytes(16) - - gAES, err := aes.NewCipher(key) - if err != nil { - t.Fatal(err) - } - gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) - if err != nil { - t.Fatal(err) - } - max := 5016 - // Check all block sizes from 1 to 5000 - for i := 1; i < max-16; i++ { - in := make([]byte, i) - dst := make([]byte, max-i) - dst = dst[:16] - - sOut := sGCM.Seal(dst, iv, in, authData) - dst2 := make([]byte, 16) - gOut := gGCM.Seal(dst2, iv, in, authData) - - // Ciphertext must be identical to Go GCM - if !bytes.Equal(sOut, gOut) { - t.Fatalf("Compare failed for encryption, size %d", i) - t.Log("sOut:") - t.Log("\n" + hex.Dump(sOut)) - t.Log("gOut:") - t.Log("\n" + hex.Dump(gOut)) - } - } -} - -// Open re-uses the "dst" buffer it is large enough. -// Check that this works correctly by testing different "dst" capacities from -// 5000 to 16 and "in" lengths from 1 to 5000. -func TestInplaceOpen(t *testing.T) { - key := randBytes(32) - sGCM := New(key, false) - authData := randBytes(24) - iv := randBytes(16) - - gAES, err := aes.NewCipher(key) - if err != nil { - t.Fatal(err) - } - gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) - if err != nil { - t.Fatal(err) - } - max := 5016 - // Check all block sizes from 1 to 5000 - for i := 1; i < max-16; i++ { - in := make([]byte, i) - - gCiphertext := gGCM.Seal(iv, iv, in, authData) - - dst := make([]byte, max-i) - // sPlaintext ... stupidgcm plaintext - sPlaintext, err := sGCM.Open(dst[:0], iv, gCiphertext[16:], authData) - if err != nil { - t.Fatal(err) - } - - // Plaintext must be identical to Go GCM - if !bytes.Equal(in, sPlaintext) { - t.Fatalf("Compare failed, i=%d", i) - } - } -} - -// TestCorruption verifies that changes in the ciphertext result in a decryption -// error -func TestCorruption(t *testing.T) { - key := randBytes(32) - sGCM := New(key, false) - authData := randBytes(24) - iv := randBytes(16) - - in := make([]byte, 354) - sOut := sGCM.Seal(nil, iv, in, authData) - sOut2, sErr := sGCM.Open(nil, iv, sOut, authData) - if sErr != nil { - t.Fatal(sErr) - } - if !bytes.Equal(in, sOut2) { - t.Fatalf("Compare failed") - } - - // Corrupt first byte - sOut[0]++ - sOut2, sErr = sGCM.Open(nil, iv, sOut, authData) - if sErr == nil || sOut2 != nil { - t.Fatalf("Should have gotten error") - } - sOut[0]-- - - // Corrupt last byte - sOut[len(sOut)-1]++ - sOut2, sErr = sGCM.Open(nil, iv, sOut, authData) - if sErr == nil || sOut2 != nil { - t.Fatalf("Should have gotten error") - } - sOut[len(sOut)-1]-- - - // Append one byte - sOut = append(sOut, 0) - sOut2, sErr = sGCM.Open(nil, iv, sOut, authData) - if sErr == nil || sOut2 != nil { - t.Fatalf("Should have gotten error") - } -} diff --git a/internal/stupidgcm/without_openssl.go b/internal/stupidgcm/without_openssl.go index deac342..d420da3 100644 --- a/internal/stupidgcm/without_openssl.go +++ b/internal/stupidgcm/without_openssl.go @@ -6,7 +6,7 @@ import ( "fmt" "os" - "github.com/rfjakob/gocryptfs/internal/exitcodes" + "../exitcodes" ) type StupidGCM struct{} diff --git a/internal/syscallcompat/emulate.go b/internal/syscallcompat/emulate.go deleted file mode 100644 index 91b592b..0000000 --- a/internal/syscallcompat/emulate.go +++ /dev/null @@ -1,29 +0,0 @@ -package syscallcompat - -import ( - "path/filepath" - "sync" - "syscall" -) - -var chdirMutex sync.Mutex - -// emulateMknodat emulates the syscall for platforms that don't have it -// in the kernel (darwin). -func emulateMknodat(dirfd int, path string, mode uint32, dev int) error { - if !filepath.IsAbs(path) { - chdirMutex.Lock() - defer chdirMutex.Unlock() - cwd, err := syscall.Open(".", syscall.O_RDONLY, 0) - if err != nil { - return err - } - defer syscall.Close(cwd) - err = syscall.Fchdir(dirfd) - if err != nil { - return err - } - defer syscall.Fchdir(cwd) - } - return syscall.Mknod(path, mode, dev) -} diff --git a/internal/syscallcompat/emulate_test.go b/internal/syscallcompat/emulate_test.go deleted file mode 100644 index 16383f2..0000000 --- a/internal/syscallcompat/emulate_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package syscallcompat - -import ( - "os" - "testing" - - "golang.org/x/sys/unix" -) - -func TestEmulateMknodat(t *testing.T) { - err := emulateMknodat(tmpDirFd, "fifo1", unix.S_IFIFO, 0) - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/fifo1") - if err != nil { - t.Fatal(err) - } - // Test with absolute path - err = emulateMknodat(-1, tmpDir+"/fifo2", unix.S_IFIFO, 0) - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/fifo2") - if err != nil { - t.Fatal(err) - } -} diff --git a/internal/syscallcompat/getdents_linux.go b/internal/syscallcompat/getdents_linux.go index 852b3cd..df886b4 100644 --- a/internal/syscallcompat/getdents_linux.go +++ b/internal/syscallcompat/getdents_linux.go @@ -13,10 +13,6 @@ import ( "unsafe" "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) const sizeofDirent = int(unsafe.Sizeof(unix.Dirent{})) @@ -26,8 +22,13 @@ const sizeofDirent = int(unsafe.Sizeof(unix.Dirent{})) // See https://github.com/rfjakob/gocryptfs/issues/197 for details. const maxReclen = 280 +type DirEntry struct { + Name string + Mode uint32 +} + // getdents wraps unix.Getdents and converts the result to []fuse.DirEntry. -func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, err error) { +func getdents(fd int) (entries []DirEntry, entriesSpecial []DirEntry, err error) { // Collect syscall result in smartBuf. // "bytes.Buffer" is smart about expanding the capacity and avoids the // exponential runtime of simple append(). @@ -43,7 +44,6 @@ func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, continue } else if err != nil { if smartBuf.Len() > 0 { - tlog.Warn.Printf("warning: unix.Getdents returned errno %d in the middle of data ( https://github.com/rfjakob/gocryptfs/issues/483 )", err.(syscall.Errno)) return nil, nil, syscall.EIO } return nil, nil, err @@ -63,14 +63,10 @@ func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, for offset < len(buf) { s := *(*unix.Dirent)(unsafe.Pointer(&buf[offset])) if s.Reclen == 0 { - tlog.Warn.Printf("Getdents: corrupt entry #%d: Reclen=0 at offset=%d. Returning EBADR", - numEntries, offset) // EBADR = Invalid request descriptor return nil, nil, syscall.EBADR } if int(s.Reclen) > maxReclen { - tlog.Warn.Printf("Getdents: corrupt entry #%d: Reclen=%d > %d. Returning EBADR", - numEntries, s.Reclen, maxReclen) return nil, nil, syscall.EBADR } offset += int(s.Reclen) @@ -80,7 +76,7 @@ func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, // Note: syscall.ParseDirent() only returns the names, // we want all the data, so we have to implement // it on our own. - entries = make([]fuse.DirEntry, 0, numEntries) + entries = make([]DirEntry, 0, numEntries) offset = 0 for offset < len(buf) { s := *(*unix.Dirent)(unsafe.Pointer(&buf[offset])) @@ -91,8 +87,7 @@ func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, offset += int(s.Reclen) if name == "." || name == ".." { // These are always directories, no need to call convertDType. - entriesSpecial = append(entriesSpecial, fuse.DirEntry{ - Ino: s.Ino, + entriesSpecial = append(entriesSpecial, DirEntry{ Mode: syscall.S_IFDIR, Name: name, }) @@ -104,8 +99,7 @@ func getdents(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, // and go on. continue } - entries = append(entries, fuse.DirEntry{ - Ino: s.Ino, + entries = append(entries, DirEntry{ Mode: mode, Name: name, }) @@ -124,7 +118,6 @@ func getdentsName(s unix.Dirent) (string, error) { } } if l < 1 { - tlog.Warn.Printf("Getdents: invalid name length l=%d. Returning EBADR", l) // EBADR = Invalid request descriptor return "", syscall.EBADR } @@ -139,18 +132,8 @@ func getdentsName(s unix.Dirent) (string, error) { var dtUnknownWarnOnce sync.Once func dtUnknownWarn(dirfd int) { - const XFS_SUPER_MAGIC = 0x58465342 // From man 2 statfs var buf syscall.Statfs_t - err := syscall.Fstatfs(dirfd, &buf) - if err == nil && buf.Type == XFS_SUPER_MAGIC { - // Old XFS filesystems always return DT_UNKNOWN. Downgrade the message - // to "info" level if we are on XFS. - // https://github.com/rfjakob/gocryptfs/issues/267 - tlog.Info.Printf("Getdents: convertDType: received DT_UNKNOWN, fstype=xfs, falling back to stat") - } else { - tlog.Warn.Printf("Getdents: convertDType: received DT_UNKNOWN, fstype=%#x, falling back to stat", - buf.Type) - } + syscall.Fstatfs(dirfd, &buf) } // convertDType converts a Dirent.Type to at Stat_t.Mode value. diff --git a/internal/syscallcompat/getdents_other.go b/internal/syscallcompat/getdents_other.go deleted file mode 100644 index 1ed5ecf..0000000 --- a/internal/syscallcompat/getdents_other.go +++ /dev/null @@ -1,61 +0,0 @@ -package syscallcompat - -import ( - "os" - "syscall" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" -) - -func fillDirEntries(fd int, names []string) ([]fuse.DirEntry, error) { - out := make([]fuse.DirEntry, 0, len(names)) - for _, name := range names { - var st unix.Stat_t - err := Fstatat(fd, name, &st, unix.AT_SYMLINK_NOFOLLOW) - if err == syscall.ENOENT { - // File disappeared between readdir and stat. Pretend we did not - // see it. - continue - } - if err != nil { - return nil, err - } - newEntry := fuse.DirEntry{ - Name: name, - Mode: uint32(st.Mode) & syscall.S_IFMT, - Ino: st.Ino, - } - out = append(out, newEntry) - } - return out, nil -} - -// emulateGetdents reads all directory entries from the open directory "fd" -// and returns normal entries and "." / ".." split into two slices. -func emulateGetdents(fd int) (out []fuse.DirEntry, outSpecial []fuse.DirEntry, err error) { - // os.File closes the fd in its finalizer. Duplicate the fd to not affect - // the original fd. - newFd, err := syscall.Dup(fd) - if err != nil { - return nil, nil, err - } - f := os.NewFile(uintptr(newFd), "") - defer f.Close() - // Get all file names in the directory - names, err := f.Readdirnames(0) - if err != nil { - return nil, nil, err - } - // Stat all the names and convert to fuse.DirEntry - out, err = fillDirEntries(fd, names) - if err != nil { - return nil, nil, err - } - outSpecial, err = fillDirEntries(fd, []string{".", ".."}) - if err != nil { - return nil, nil, err - } - return out, outSpecial, nil -} diff --git a/internal/syscallcompat/getdents_test.go b/internal/syscallcompat/getdents_test.go deleted file mode 100644 index a6f41ca..0000000 --- a/internal/syscallcompat/getdents_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// +build linux - -package syscallcompat - -import ( - "io/ioutil" - "os" - "runtime" - "strings" - "syscall" - "testing" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" -) - -var emulate = false - -func TestGetdents(t *testing.T) { - t.Logf("testing native getdents") - testGetdents(t) - t.Logf("testing emulateGetdents") - emulate = true - testGetdents(t) -} - -// skipOnGccGo skips the emulateGetdents test when we are -// running linux and were compiled with gccgo. The test is known to fail -// (https://github.com/rfjakob/gocryptfs/issues/201), but getdents emulation -// is not used on linux, so let's skip the test and ignore the failure. -func skipOnGccGo(t *testing.T) { - if !emulate || runtime.GOOS != "linux" { - return - } - // runtime.Version() output... - // on go: go1.9.2 - // on gccgo: go1.8.1 gccgo (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) - v := runtime.Version() - if strings.Contains(v, "gccgo") { - t.Skipf("test is known-broken on gccgo") - } -} - -func testGetdents(t *testing.T) { - getdentsUnderTest := getdents - if emulate { - getdentsUnderTest = emulateGetdents - } - // Fill a directory with filenames of length 1 ... 255 - testDir, err := ioutil.TempDir(tmpDir, "TestGetdents") - if err != nil { - t.Fatal(err) - } - for i := 1; i <= unix.NAME_MAX; i++ { - n := strings.Repeat("x", i) - err = ioutil.WriteFile(testDir+"/"+n, nil, 0600) - if err != nil { - t.Fatal(err) - } - } - // "/", "/dev" and "/proc/self" are good test cases because they contain - // many different file types (block and char devices, symlinks, - // mountpoints). - dirs := []string{testDir, "/", "/dev", "/proc/self"} - for _, dir := range dirs { - // Read directory using stdlib Readdir() - fd, err := os.Open(dir) - if err != nil { - t.Fatal(err) - } - defer fd.Close() - readdirEntries, err := fd.Readdir(0) - if err != nil { - t.Fatal(err) - } - readdirMap := make(map[string]*syscall.Stat_t) - for _, v := range readdirEntries { - readdirMap[v.Name()] = fuse.ToStatT(v) - } - // Read using our Getdents() implementation - _, err = fd.Seek(0, 0) // Rewind directory - if err != nil { - t.Fatal(err) - } - getdentsEntries, special, err := getdentsUnderTest(int(fd.Fd())) - if err != nil { - t.Log(err) - skipOnGccGo(t) - t.FailNow() - } - getdentsMap := make(map[string]fuse.DirEntry) - for _, v := range getdentsEntries { - getdentsMap[v.Name] = v - } - // Compare results - if len(getdentsEntries) != len(readdirEntries) { - t.Fatalf("len(getdentsEntries)=%d, len(readdirEntries)=%d", - len(getdentsEntries), len(readdirEntries)) - } - for name := range readdirMap { - g := getdentsMap[name] - r := readdirMap[name] - rTyp := r.Mode & syscall.S_IFMT - if g.Mode != rTyp { - t.Errorf("%q: g.Mode=%#o, r.Mode=%#o", name, g.Mode, rTyp) - } - if g.Ino != r.Ino { - // The inode number of a directory that is reported by stat - // and getdents is different when it is a mountpoint. Only - // throw an error when we are NOT looking at a directory. - if g.Mode != syscall.S_IFDIR { - t.Errorf("%s: g.Ino=%d, r.Ino=%d", name, g.Ino, r.Ino) - } - } - } - if len(special) != 2 { - t.Error(special) - } - if !(special[0].Name == "." && special[1].Name == ".." || - special[1].Name == "." && special[0].Name == "..") { - t.Error(special) - } - for _, v := range special { - if v.Ino == 0 { - t.Error(v) - } - if v.Mode != syscall.S_IFDIR { - t.Error(v) - } - } - } -} diff --git a/internal/syscallcompat/helpers.go b/internal/syscallcompat/helpers.go deleted file mode 100644 index e2a2215..0000000 --- a/internal/syscallcompat/helpers.go +++ /dev/null @@ -1,21 +0,0 @@ -package syscallcompat - -import ( - "os" - "syscall" -) - -// IsENOSPC tries to find out if "err" is a (potentially wrapped) ENOSPC error. -func IsENOSPC(err error) bool { - // syscallcompat.EnospcPrealloc returns the naked syscall error - if err == syscall.ENOSPC { - return true - } - // os.File.WriteAt returns &PathError - if err2, ok := err.(*os.PathError); ok { - if err2.Err == syscall.ENOSPC { - return true - } - } - return false -} diff --git a/internal/syscallcompat/main_test.go b/internal/syscallcompat/main_test.go deleted file mode 100644 index ddf6bc4..0000000 --- a/internal/syscallcompat/main_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package syscallcompat - -import ( - "fmt" - "io/ioutil" - "os" - "testing" -) - -var tmpDir string -var tmpDirFd int - -func TestMain(m *testing.M) { - origWd, err := os.Getwd() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - // Cannot import test_helpers because of import cycle - parent := fmt.Sprintf("/tmp/gocryptfs-test-parent-%d", os.Getuid()) - err = os.MkdirAll(parent, 0700) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - tmpDir, err = ioutil.TempDir(parent, "syscallcompat") - if err != nil { - fmt.Println(err) - os.Exit(1) - } - dirf, err := os.Open(tmpDir) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - defer dirf.Close() - tmpDirFd = int(dirf.Fd()) - // Run the tests - r := m.Run() - // Check that we are in the same directory again (the emulated syscalls - // use Fchdir a lot) - cwd, _ := os.Getwd() - if cwd != origWd { - fmt.Printf("working dir has changed from %q to %q", origWd, cwd) - os.Exit(1) - } - os.Exit(r) -} diff --git a/internal/syscallcompat/open_nofollow.go b/internal/syscallcompat/open_nofollow.go index f8e50e3..150eb0f 100644 --- a/internal/syscallcompat/open_nofollow.go +++ b/internal/syscallcompat/open_nofollow.go @@ -4,8 +4,6 @@ import ( "path/filepath" "strings" "syscall" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) // OpenDirNofollow opens the dir at "relPath" in a way that is secure against @@ -16,11 +14,9 @@ import ( // Retries on EINTR. func OpenDirNofollow(baseDir string, relPath string) (fd int, err error) { if !filepath.IsAbs(baseDir) { - tlog.Warn.Printf("BUG: OpenDirNofollow called with relative baseDir=%q", baseDir) return -1, syscall.EINVAL } if filepath.IsAbs(relPath) { - tlog.Warn.Printf("BUG: OpenDirNofollow called with absolute relPath=%q", relPath) return -1, syscall.EINVAL } // Open the base dir (following symlinks) diff --git a/internal/syscallcompat/open_nofollow_test.go b/internal/syscallcompat/open_nofollow_test.go deleted file mode 100644 index 1eeac3a..0000000 --- a/internal/syscallcompat/open_nofollow_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package syscallcompat - -import ( - "os" - "syscall" - "testing" -) - -func TestOpenNofollow(t *testing.T) { - err := os.MkdirAll(tmpDir+"/d1/d2/d3", 0700) - if err != nil { - t.Fatal(err) - } - // Create a file - dirfd, err := OpenDirNofollow(tmpDir, "d1/d2/d3") - if err != nil { - t.Fatal(err) - } - fd, err := Openat(dirfd, "f1", syscall.O_RDWR|syscall.O_CREAT|syscall.O_EXCL, 0600) - if err != nil { - t.Fatal(err) - } - syscall.Close(fd) - _, err = os.Stat(tmpDir + "/d1/d2/d3/f1") - if err != nil { - t.Fatal(err) - } - // Replace "d1" with a symlink - open should fail with ELOOP - err = os.Rename(tmpDir+"/d1", tmpDir+"/d1.renamed") - if err != nil { - t.Fatal(err) - } - os.Symlink(tmpDir+"/d1.renamed", tmpDir+"/d1") - fd, err = OpenDirNofollow(tmpDir, "d1/d2/d3") - if err == nil { - t.Fatalf("should have failed") - } - if err != syscall.ELOOP && err != syscall.ENOTDIR { - t.Errorf("expected ELOOP or ENOTDIR, got %v", err) - } - // Check to see that the base dir can be opened as well - fd, err = OpenDirNofollow(tmpDir, "") - if err != nil { - t.Errorf("cannot open base dir: %v", err) - } else { - syscall.Close(fd) - } -} diff --git a/internal/syscallcompat/sys_common.go b/internal/syscallcompat/sys_common.go index fc020bd..0123b25 100644 --- a/internal/syscallcompat/sys_common.go +++ b/internal/syscallcompat/sys_common.go @@ -5,8 +5,6 @@ import ( "syscall" "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) // PATH_MAX is the maximum allowed path length on Linux. @@ -47,16 +45,9 @@ func Faccessat(dirfd int, path string, mode uint32) error { // Openat wraps the Openat syscall. // Retries on EINTR. func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { - if flags&syscall.O_CREAT != 0 { - // O_CREAT should be used with O_EXCL. O_NOFOLLOW has no effect with O_EXCL. - if flags&syscall.O_EXCL == 0 { - tlog.Warn.Printf("Openat: O_CREAT without O_EXCL: flags = %#x", flags) - flags |= syscall.O_EXCL - } - } else { + if flags&syscall.O_CREAT == 0 { // If O_CREAT is not used, we should use O_NOFOLLOW if flags&syscall.O_NOFOLLOW == 0 { - tlog.Warn.Printf("Openat: O_NOFOLLOW missing: flags = %#x", flags) flags |= syscall.O_NOFOLLOW } } @@ -70,7 +61,6 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { // Why would we ever want to call this without AT_SYMLINK_NOFOLLOW? if flags&unix.AT_SYMLINK_NOFOLLOW == 0 { - tlog.Warn.Printf("Fchownat: adding missing AT_SYMLINK_NOFOLLOW flag") flags |= unix.AT_SYMLINK_NOFOLLOW } return unix.Fchownat(dirfd, path, uid, gid, flags) @@ -81,7 +71,6 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func Fstatat(dirfd int, path string, stat *unix.Stat_t, flags int) (err error) { // Why would we ever want to call this without AT_SYMLINK_NOFOLLOW? if flags&unix.AT_SYMLINK_NOFOLLOW == 0 { - tlog.Warn.Printf("Fstatat: adding missing AT_SYMLINK_NOFOLLOW flag") flags |= unix.AT_SYMLINK_NOFOLLOW } err = retryEINTR(func() error { diff --git a/internal/syscallcompat/sys_common_test.go b/internal/syscallcompat/sys_common_test.go deleted file mode 100644 index 7141b92..0000000 --- a/internal/syscallcompat/sys_common_test.go +++ /dev/null @@ -1,327 +0,0 @@ -package syscallcompat - -import ( - "bytes" - "os" - "runtime" - "syscall" - "testing" - - "golang.org/x/sys/unix" -) - -func TestReadlinkat(t *testing.T) { - for _, targetLen := range []int{100, 500, 4000} { - target := string(bytes.Repeat([]byte("x"), targetLen)) - err := syscall.Symlink(target, tmpDir+"/readlinkat") - if err != nil { - if targetLen > 1000 { - // Symlinks longer than 1024 (?) bytes are not supported on - // MacOS and XFS - t.Logf("skipping targetLen=%d: %v", targetLen, err) - continue - } - t.Fatalf("targetLen=%d: %v", targetLen, err) - } - target2, err := Readlinkat(tmpDirFd, "readlinkat") - if err != nil { - t.Fatal(err) - } - if target != target2 { - t.Errorf("target=%q != target2=%q", target, target2) - } - err = syscall.Unlink(tmpDir + "/readlinkat") - if err != nil { - t.Fatal(err) - } - } -} - -func TestOpenat(t *testing.T) { - // Always pass O_NOFOLLOW to avoid this warning: - // Openat: O_NOFOLLOW missing: flags = 0x0" - _, err := Openat(tmpDirFd, "testOpenAt", syscall.O_NOFOLLOW, 0) - if err == nil { - t.Errorf("should have failed") - } - fd, err := os.Create(tmpDir + "/testOpenAt") - if err != nil { - t.Fatal(err) - } - fd.Close() - rawFd, err := Openat(tmpDirFd, "testOpenAt", syscall.O_NOFOLLOW, 0) - if err != nil { - t.Fatal(err) - } - defer syscall.Close(rawFd) - if rawFd < 0 { - t.Fatalf("rawFd=%d", rawFd) - } - // Test with absolute path - rawFd, err = Openat(-1, tmpDir+"/testOpenAt", syscall.O_NOFOLLOW, 0) - if err != nil { - t.Fatal(err) - } - defer syscall.Close(rawFd) - if rawFd < 0 { - t.Fatalf("rawFd=%d", rawFd) - } -} - -func TestRenameat(t *testing.T) { - os.Mkdir(tmpDir+"/dir1", 0700) - dir1, err := os.Open(tmpDir + "/dir1") - if err != nil { - t.Fatal(err) - } - defer dir1.Close() - os.Mkdir(tmpDir+"/dir2", 0700) - dir2, err := os.Open(tmpDir + "/dir2") - if err != nil { - t.Fatal(err) - } - defer dir2.Close() - fd, err := os.Create(tmpDir + "/dir1/f1") - if err != nil { - t.Fatal(err) - } - fd.Close() - err = Renameat(int(dir1.Fd()), "f1", int(dir2.Fd()), "f2") - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/dir2/f2") - if err != nil { - t.Fatal(err) - } - // Test with absolute path - err = Renameat(-1, tmpDir+"/dir2/f2", -1, tmpDir+"/dir2/f1") - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/dir2/f1") - if err != nil { - t.Fatal(err) - } -} - -func TestUnlinkat(t *testing.T) { - os.Mkdir(tmpDir+"/unlink1", 0700) - dirfd, err := os.Open(tmpDir + "/unlink1") - if err != nil { - t.Fatal(err) - } - defer dirfd.Close() - // Try to delete file - fd, err := os.Create(tmpDir + "/unlink1/f1") - if err != nil { - t.Fatal(err) - } - fd.Close() - err = Unlinkat(int(dirfd.Fd()), "f1", 0) - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/unlink1/f1") - if err == nil { - t.Fatalf("file not deleted!") - } - // Try to delete dir - err = os.Mkdir(tmpDir+"/unlink1/d1", 0700) - if err != nil { - t.Fatal(err) - } - err = Unlinkat(int(dirfd.Fd()), "d1", 0) - if err == nil { - t.Fatalf("this should fail due to missing AT_REMOVEDIR flag") - } - err = Unlinkat(int(dirfd.Fd()), "d1", unix.AT_REMOVEDIR) - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/unlink1/d1") - if err == nil { - t.Fatalf("dir not deleted!") - } - // Test with absolute path - err = os.Mkdir(tmpDir+"/unlink1/d1", 0700) - if err != nil { - t.Fatal(err) - } - err = Unlinkat(-1, tmpDir+"/unlink1/d1", unix.AT_REMOVEDIR) - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(tmpDir + "/unlink1/d1") - if err == nil { - t.Fatalf("dir not deleted!") - } -} - -func TestFchmodatNofollow(t *testing.T) { - regular := "TestFchmodat_Regular" - f, err := os.OpenFile(tmpDir+"/"+regular, os.O_CREATE|os.O_WRONLY, 0000) - if err != nil { - t.Fatal(err) - } - f.Close() - symlink := "TestFchmodat_Symlink" - err = syscall.Symlink(regular, tmpDir+"/"+symlink) - if err != nil { - t.Fatal(err) - } - dirfd, err := syscall.Open(tmpDir, syscall.O_RDONLY, 0) - if err != nil { - t.Fatal(err) - } - defer syscall.Close(dirfd) - - // Check that chmod on a regular file works ok - err = FchmodatNofollow(dirfd, regular, 0111) - if err != nil { - t.Fatal(err) - } - var st syscall.Stat_t - syscall.Lstat(tmpDir+"/"+regular, &st) - st.Mode &= 0777 - if st.Mode != 0111 { - t.Errorf("wrong mode: %#0o", st.Mode) - } - err = FchmodatNofollow(dirfd, regular, 0000) - if err != nil { - t.Error(err) - } - syscall.Lstat(tmpDir+"/"+regular, &st) - st.Mode &= 0777 - if st.Mode != 0000 { - t.Errorf("wrong mode: %#0o", st.Mode) - } - - // Check what happens on a symlink - err = FchmodatNofollow(dirfd, symlink, 0333) - // On Darwin, permissions on symlinks are significant and can be changed. On - // Linux they are ignored, and FchmodatNofollow rejects attempts to change - // them. - if err == nil && runtime.GOOS == "linux" { - syscall.Lstat(tmpDir+"/"+symlink, &st) - st.Mode &= 0777 - t.Errorf("chmod on symlink should have failed, but did not. New mode=%#0o", st.Mode) - } - syscall.Lstat(tmpDir+"/"+regular, &st) - st.Mode &= 0777 - if st.Mode != 0000 { - t.Errorf("chmod on symlink affected symlink target: New mode=%#0o", st.Mode) - } -} - -// symlinkCheckMode looks if the mode bits in "st" say that this is a symlink. -// Calls t.Fatal() if not. -func symlinkCheckMode(t *testing.T, st syscall.Stat_t) { - if runtime.GOOS == "darwin" { - // On MacOS, symlinks don't carry their own permissions, so - // only check the file type. - if st.Mode&syscall.S_IFMT != syscall.S_IFLNK { - t.Fatalf("This is not a symlink: mode = 0%o", st.Mode) - } - return - } - if st.Mode != 0120777 { - t.Fatalf("Wrong mode, have 0%o, want 0120777", st.Mode) - } -} - -// We used to have our own wrapper for Symlinkat. The wrapper is gone but the test -// is still useful. -func TestSymlinkat(t *testing.T) { - err := unix.Symlinkat("/foo/bar/baz", tmpDirFd, "symlink1") - if err != nil { - t.Fatal(err) - } - var st syscall.Stat_t - err = syscall.Lstat(tmpDir+"/symlink1", &st) - if err != nil { - t.Fatal(err) - } - symlinkCheckMode(t, st) - // Test with absolute path - err = unix.Symlinkat("/foo/bar/baz", -1, tmpDir+"/symlink2") - if err != nil { - t.Fatal(err) - } - err = syscall.Lstat(tmpDir+"/symlink2", &st) - if err != nil { - t.Fatal(err) - } - symlinkCheckMode(t, st) -} - -// We used to have our own wrapper for Mkdirat. The wrapper is gone but the test -// is still useful. -func TestMkdirat(t *testing.T) { - err := unix.Mkdirat(tmpDirFd, "mkdirat", 0700) - if err != nil { - t.Fatal(err) - } - fi, err := os.Stat(tmpDir + "/mkdirat") - if err != nil { - t.Fatal(err) - } - if !fi.IsDir() { - t.Fatalf("mkdirat did not create a directory") - } - // Test with absolute path - err = unix.Mkdirat(-1, tmpDir+"/mkdirat2", 0700) - if err != nil { - t.Fatal(err) - } - fi, err = os.Stat(tmpDir + "/mkdirat2") - if err != nil { - t.Fatal(err) - } - if !fi.IsDir() { - t.Fatalf("mkdirat did not create a directory") - } -} - -func TestFstatat(t *testing.T) { - var st unix.Stat_t - // stat a normal file (size 3) - f, err := os.Create(tmpDir + "/fstatat") - if err != nil { - t.Fatal(err) - } - _, err = f.Write([]byte("foo")) - if err != nil { - t.Fatal(err) - } - f.Close() - err = Fstatat(tmpDirFd, "fstatat", &st, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - t.Fatal(err) - } - if st.Size != 3 { - t.Errorf("wrong file size: %d", st.Size) - } - // stat a symlink and check that the size matches the length of the - // symlink target. This proves that we have stat'ed the symlink itself. - err = os.Symlink(tmpDir+"/fstatat", tmpDir+"/fstatatSymlink") - if err != nil { - t.Fatal(err) - } - err = Fstatat(tmpDirFd, "fstatatSymlink", &st, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - t.Fatal(err) - } - expectedSize := int64(len(tmpDir + "/fstatat")) - if st.Size != expectedSize { - t.Errorf("symlink size: expected=%d, got=%d", expectedSize, st.Size) - } -} - -// BenchmarkLgetxattr benchmarks Lgetxattr. Lgetxattr is very hot as the kernel -// queries security.capabilities for every file access. -func BenchmarkLgetxattr(b *testing.B) { - for i := 0; i < b.N; i++ { - Lgetxattr("/", "user.this.attr.does.not.exist") - } -} diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go deleted file mode 100644 index 075563f..0000000 --- a/internal/syscallcompat/sys_darwin.go +++ /dev/null @@ -1,230 +0,0 @@ -package syscallcompat - -import ( - "log" - "path/filepath" - "runtime" - "syscall" - "time" - "unsafe" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" -) - -const ( - // O_DIRECT means oncached I/O on Linux. No direct equivalent on MacOS and defined - // to zero there. - O_DIRECT = 0 - - // O_PATH is only defined on Linux - O_PATH = 0 - - // RENAME_NOREPLACE is only defined on Linux - RENAME_NOREPLACE = 0 - - // KAUTH_UID_NONE and KAUTH_GID_NONE are special values to - // revert permissions to the process credentials. - KAUTH_UID_NONE = ^uint32(0) - 100 - KAUTH_GID_NONE = ^uint32(0) - 100 -) - -// Unfortunately pthread_setugid_np does not have a syscall wrapper yet. -func pthread_setugid_np(uid uint32, gid uint32) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETTID, uintptr(uid), uintptr(gid), 0) - if e1 != 0 { - err = e1 - } - return -} - -// Unfortunately fsetattrlist does not have a syscall wrapper yet. -func fsetattrlist(fd int, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall.Syscall6(syscall.SYS_FSETATTRLIST, uintptr(fd), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = e1 - } - return -} - -// Setattrlist already has a syscall wrapper, but it is not exported. -func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall.Syscall6(syscall.SYS_SETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = e1 - } - return -} - -// Sorry, fallocate is not available on OSX at all and -// fcntl F_PREALLOCATE is not accessible from Go. -// See https://github.com/rfjakob/gocryptfs/issues/18 if you want to help. -func EnospcPrealloc(fd int, off int64, len int64) error { - return nil -} - -// See above. -func Fallocate(fd int, mode uint32, off int64, len int64) error { - return syscall.EOPNOTSUPP -} - -// Dup3 is not available on Darwin, so we use Dup2 instead. -func Dup3(oldfd int, newfd int, flags int) (err error) { - if flags != 0 { - log.Panic("darwin does not support dup3 flags") - } - return syscall.Dup2(oldfd, newfd) -} - -//////////////////////////////////////////////////////// -//// Emulated Syscalls (see emulate.go) //////////////// -//////////////////////////////////////////////////////// - -func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) { - if context != nil { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err = pthread_setugid_np(context.Owner.Uid, context.Owner.Gid) - if err != nil { - return -1, err - } - defer pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) - } - - return Openat(dirfd, path, flags, mode) -} - -func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { - return emulateMknodat(dirfd, path, mode, dev) -} - -func MknodatUser(dirfd int, path string, mode uint32, dev int, context *fuse.Context) (err error) { - if context != nil { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err = pthread_setugid_np(context.Owner.Uid, context.Owner.Gid) - if err != nil { - return err - } - defer pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) - } - - return Mknodat(dirfd, path, mode, dev) -} - -func FchmodatNofollow(dirfd int, path string, mode uint32) (err error) { - return unix.Fchmodat(dirfd, path, mode, unix.AT_SYMLINK_NOFOLLOW) -} - -func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) { - if context != nil { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err = pthread_setugid_np(context.Owner.Uid, context.Owner.Gid) - if err != nil { - return err - } - defer pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) - } - - return unix.Symlinkat(oldpath, newdirfd, newpath) -} - -func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (err error) { - if context != nil { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err = pthread_setugid_np(context.Owner.Uid, context.Owner.Gid) - if err != nil { - return err - } - defer pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) - } - - return unix.Mkdirat(dirfd, path, mode) -} - -type attrList struct { - bitmapCount uint16 - _ uint16 - CommonAttr uint32 - VolAttr uint32 - DirAttr uint32 - FileAttr uint32 - Forkattr uint32 -} - -func timesToAttrList(a *time.Time, m *time.Time) (attrList attrList, attributes [2]unix.Timespec) { - attrList.bitmapCount = unix.ATTR_BIT_MAP_COUNT - attrList.CommonAttr = 0 - i := 0 - if m != nil { - attributes[i] = unix.Timespec(fuse.UtimeToTimespec(m)) - attrList.CommonAttr |= unix.ATTR_CMN_MODTIME - i += 1 - } - if a != nil { - attributes[i] = unix.Timespec(fuse.UtimeToTimespec(a)) - attrList.CommonAttr |= unix.ATTR_CMN_ACCTIME - i += 1 - } - return attrList, attributes -} - -// FutimesNano syscall. -func FutimesNano(fd int, a *time.Time, m *time.Time) (err error) { - attrList, attributes := timesToAttrList(a, m) - return fsetattrlist(fd, unsafe.Pointer(&attrList), unsafe.Pointer(&attributes), - unsafe.Sizeof(attributes), 0) -} - -// UtimesNanoAtNofollow is like UtimesNanoAt but never follows symlinks. -// -// Unfortunately we cannot use unix.UtimesNanoAt since it is broken and just -// ignores the provided 'dirfd'. In addition, it also lacks handling of 'nil' -// pointers (used to preserve one of both timestamps). -func UtimesNanoAtNofollow(dirfd int, path string, a *time.Time, m *time.Time) (err error) { - if !filepath.IsAbs(path) { - chdirMutex.Lock() - defer chdirMutex.Unlock() - var cwd int - cwd, err = syscall.Open(".", syscall.O_RDONLY, 0) - if err != nil { - return err - } - defer syscall.Close(cwd) - err = syscall.Fchdir(dirfd) - if err != nil { - return err - } - defer syscall.Fchdir(cwd) - } - - _p0, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - - attrList, attributes := timesToAttrList(a, m) - return setattrlist(_p0, unsafe.Pointer(&attrList), unsafe.Pointer(&attributes), - unsafe.Sizeof(attributes), unix.FSOPT_NOFOLLOW) -} - -func Getdents(fd int) ([]fuse.DirEntry, error) { - entries, _, err := emulateGetdents(fd) - return entries, err -} - -func GetdentsSpecial(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, err error) { - return emulateGetdents(fd) -} - -// Renameat2 does not exist on Darwin, so we call Renameat and ignore the flags. -func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { - return unix.Renameat(olddirfd, oldpath, newdirfd, newpath) -} diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go index 9672be7..d0fa027 100644 --- a/internal/syscallcompat/sys_linux.go +++ b/internal/syscallcompat/sys_linux.go @@ -2,20 +2,9 @@ package syscallcompat import ( - "fmt" - "io/ioutil" - "runtime" - "strconv" - "strings" - "sync" "syscall" - "time" "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/tlog" ) const ( @@ -32,8 +21,6 @@ const ( RENAME_NOREPLACE = unix.RENAME_NOREPLACE ) -var preallocWarn sync.Once - // EnospcPrealloc preallocates ciphertext space without changing the file // size. This guarantees that we don't run out of space while writing a // ciphertext block (that would corrupt the block). @@ -49,233 +36,18 @@ func EnospcPrealloc(fd int, off int64, len int64) (err error) { if err == syscall.EOPNOTSUPP { // ZFS and ext3 do not support fallocate. Warn but continue anyway. // https://github.com/rfjakob/gocryptfs/issues/22 - preallocWarn.Do(func() { - tlog.Warn.Printf("Warning: The underlying filesystem " + - "does not support fallocate(2). gocryptfs will continue working " + - "but is no longer resistant against out-of-space errors.\n") - }) return nil } return err } } -// Fallocate wraps the Fallocate syscall. -func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { - return syscall.Fallocate(fd, mode, off, len) -} - -func getSupplementaryGroups(pid uint32) (gids []int) { - procPath := fmt.Sprintf("/proc/%d/task/%d/status", pid, pid) - blob, err := ioutil.ReadFile(procPath) - if err != nil { - return nil - } - - lines := strings.Split(string(blob), "\n") - for _, line := range lines { - if strings.HasPrefix(line, "Groups:") { - f := strings.Fields(line[7:]) - gids = make([]int, len(f)) - for i := range gids { - val, err := strconv.ParseInt(f[i], 10, 32) - if err != nil { - return nil - } - gids[i] = int(val) - } - return gids - } - } - - return nil -} - -// asUser runs the function `f` under the effective uid, gid, groups specified -// in `context`. -func asUser(f func() (int, error), context *fuse.Context) (int, error) { - if context != nil { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - // Since go1.16beta1 (commit d1b1145cace8b968307f9311ff611e4bb810710c , - // https://go-review.googlesource.com/c/go/+/210639 ) - // syscall.{Setgroups,Setregid,Setreuid} affects all threads, which - // is exactly what we not want. - // - // We now use unix.{Setgroups,Setregid,Setreuid} instead. - - err := unix.Setgroups(getSupplementaryGroups(context.Pid)) - if err != nil { - return -1, err - } - defer unix.Setgroups(nil) - - err = unix.Setregid(-1, int(context.Owner.Gid)) - if err != nil { - return -1, err - } - defer unix.Setregid(-1, 0) - - err = unix.Setreuid(-1, int(context.Owner.Uid)) - if err != nil { - return -1, err - } - defer unix.Setreuid(-1, 0) - } - return f() -} - -// OpenatUser runs the Openat syscall in the context of a different user. -// -// It switches the current thread to the new user, performs the syscall, -// and switches back. -// -// If `context` is nil, this function behaves like ordinary Openat (no -// user switching). -func OpenatUser(dirfd int, path string, flags int, mode uint32, context *fuse.Context) (fd int, err error) { - f := func() (int, error) { - return Openat(dirfd, path, flags, mode) - } - return asUser(f, context) -} - -// Mknodat wraps the Mknodat syscall. -func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { - return syscall.Mknodat(dirfd, path, mode, dev) -} - -// MknodatUser runs the Mknodat syscall in the context of a different user. -// If `context` is nil, this function behaves like ordinary Mknodat. -// -// See OpenatUser() for how this works. -func MknodatUser(dirfd int, path string, mode uint32, dev int, context *fuse.Context) (err error) { - f := func() (int, error) { - err := Mknodat(dirfd, path, mode, dev) - return -1, err - } - _, err = asUser(f, context) - return err -} - -// Dup3 wraps the Dup3 syscall. We want to use Dup3 rather than Dup2 because Dup2 -// is not implemented on arm64. -func Dup3(oldfd int, newfd int, flags int) (err error) { - return syscall.Dup3(oldfd, newfd, flags) -} - -// FchmodatNofollow is like Fchmodat but never follows symlinks. -// -// This should be handled by the AT_SYMLINK_NOFOLLOW flag, but Linux -// does not implement it, so we have to perform an elaborate dance -// with O_PATH and /proc/self/fd. -// -// See also: Qemu implemented the same logic as fchmodat_nofollow(): -// https://git.qemu.org/?p=qemu.git;a=blob;f=hw/9pfs/9p-local.c#l335 -func FchmodatNofollow(dirfd int, path string, mode uint32) (err error) { - // Open handle to the filename (but without opening the actual file). - // This succeeds even when we don't have read permissions to the file. - fd, err := syscall.Openat(dirfd, path, syscall.O_NOFOLLOW|O_PATH, 0) - if err != nil { - return err - } - defer syscall.Close(fd) - - // Now we can check the type without the risk of race-conditions. - // Return syscall.ELOOP if it is a symlink. - var st syscall.Stat_t - err = syscall.Fstat(fd, &st) - if err != nil { - return err - } - if st.Mode&syscall.S_IFMT == syscall.S_IFLNK { - return syscall.ELOOP - } - - // Change mode of the actual file. Fchmod does not work with O_PATH, - // but Chmod via /proc/self/fd works. - procPath := fmt.Sprintf("/proc/self/fd/%d", fd) - return syscall.Chmod(procPath, mode) -} - -// SymlinkatUser runs the Symlinkat syscall in the context of a different user. -// If `context` is nil, this function behaves like ordinary Symlinkat. -// -// See OpenatUser() for how this works. -func SymlinkatUser(oldpath string, newdirfd int, newpath string, context *fuse.Context) (err error) { - f := func() (int, error) { - err := unix.Symlinkat(oldpath, newdirfd, newpath) - return -1, err - } - _, err = asUser(f, context) - return err -} - -// MkdiratUser runs the Mkdirat syscall in the context of a different user. -// If `context` is nil, this function behaves like ordinary Mkdirat. -// -// See OpenatUser() for how this works. -func MkdiratUser(dirfd int, path string, mode uint32, context *fuse.Context) (err error) { - f := func() (int, error) { - err := unix.Mkdirat(dirfd, path, mode) - return -1, err - } - _, err = asUser(f, context) - return err -} - -// LsetxattrUser runs the Lsetxattr syscall in the context of a different user. -// This is useful when setting ACLs, as the result depends on the user running -// the operation (see fuse-xfstests generic/375). -// -// If `context` is nil, this function behaves like ordinary Lsetxattr. -func LsetxattrUser(path string, attr string, data []byte, flags int, context *fuse.Context) (err error) { - f := func() (int, error) { - err := unix.Lsetxattr(path, attr, data, flags) - return -1, err - } - _, err = asUser(f, context) - return err -} - -func timesToTimespec(a *time.Time, m *time.Time) []unix.Timespec { - ts := make([]unix.Timespec, 2) - ts[0] = unix.Timespec(fuse.UtimeToTimespec(a)) - ts[1] = unix.Timespec(fuse.UtimeToTimespec(m)) - return ts -} - -// FutimesNano syscall. -func FutimesNano(fd int, a *time.Time, m *time.Time) (err error) { - ts := timesToTimespec(a, m) - // To avoid introducing a separate syscall wrapper for futimens() - // (as done in go-fuse, for example), we instead use the /proc/self/fd trick. - procPath := fmt.Sprintf("/proc/self/fd/%d", fd) - return unix.UtimesNanoAt(unix.AT_FDCWD, procPath, ts, 0) -} - -// UtimesNanoAtNofollow is like UtimesNanoAt but never follows symlinks. -// Retries on EINTR. -func UtimesNanoAtNofollow(dirfd int, path string, a *time.Time, m *time.Time) (err error) { - ts := timesToTimespec(a, m) - err = retryEINTR(func() error { - return unix.UtimesNanoAt(dirfd, path, ts, unix.AT_SYMLINK_NOFOLLOW) - }) - return err -} - // Getdents syscall with "." and ".." filtered out. -func Getdents(fd int) ([]fuse.DirEntry, error) { +func Getdents(fd int) ([]DirEntry, error) { entries, _, err := getdents(fd) return entries, err } -// GetdentsSpecial calls the Getdents syscall, -// with normal entries and "." / ".." split into two slices. -func GetdentsSpecial(fd int) (entries []fuse.DirEntry, entriesSpecial []fuse.DirEntry, err error) { - return getdents(fd) -} - // Renameat2 does not exist on Darwin, so we have to wrap it here. // Retries on EINTR. func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { diff --git a/internal/syscallcompat/unix2syscall_darwin.go b/internal/syscallcompat/unix2syscall_darwin.go deleted file mode 100644 index 5767a27..0000000 --- a/internal/syscallcompat/unix2syscall_darwin.go +++ /dev/null @@ -1,26 +0,0 @@ -package syscallcompat - -import ( - "syscall" - - "golang.org/x/sys/unix" -) - -// Unix2syscall converts a unix.Stat_t struct to a syscall.Stat_t struct. -func Unix2syscall(u unix.Stat_t) syscall.Stat_t { - return syscall.Stat_t{ - Dev: u.Dev, - Ino: u.Ino, - Nlink: u.Nlink, - Mode: u.Mode, - Uid: u.Uid, - Gid: u.Gid, - Rdev: u.Rdev, - Size: u.Size, - Blksize: u.Blksize, - Blocks: u.Blocks, - Atimespec: syscall.Timespec(u.Atim), - Mtimespec: syscall.Timespec(u.Mtim), - Ctimespec: syscall.Timespec(u.Ctim), - } -} diff --git a/internal/tlog/log.go b/internal/tlog/log.go deleted file mode 100644 index 6d32a6b..0000000 --- a/internal/tlog/log.go +++ /dev/null @@ -1,201 +0,0 @@ -// Package tlog is a "toggled logger" that can be enabled and disabled and -// provides coloring. -package tlog - -import ( - "encoding/hex" - "encoding/json" - "fmt" - "log" - "log/syslog" - "os" - - "golang.org/x/crypto/ssh/terminal" -) - -const ( - // ProgramName is used in log reports. - ProgramName = "gocryptfs" - wpanicMsg = "-wpanic turns this warning into a panic: " -) - -// Escape sequences for terminal colors. These are set in init() if and only -// if stdout is a terminal. Otherwise they are empty strings. -var ( - // ColorReset is used to reset terminal colors. - ColorReset string - // ColorGrey is a terminal color setting string. - ColorGrey string - // ColorRed is a terminal color setting string. - ColorRed string - // ColorGreen is a terminal color setting string. - ColorGreen string - // ColorYellow is a terminal color setting string. - ColorYellow string -) - -// JSONDump writes the object in json form. -func JSONDump(obj interface{}) string { - b, err := json.MarshalIndent(obj, "", "\t") - if err != nil { - return err.Error() - } - - return string(b) -} - -// toggledLogger - a Logger than can be enabled and disabled -type toggledLogger struct { - // Enable or disable output - Enabled bool - // Panic after logging a message, useful in regression tests - Wpanic bool - // Private prefix and postfix are used for coloring - prefix string - postfix string - - Logger *log.Logger -} - -// trimNewline removes one trailing newline from "msg" -func trimNewline(msg string) string { - if len(msg) == 0 { - return msg - } - if msg[len(msg)-1] == '\n' { - return msg[:len(msg)-1] - } - return msg -} - -func (l *toggledLogger) Printf(format string, v ...interface{}) { - if !l.Enabled { - return - } - msg := trimNewline(fmt.Sprintf(format, v...)) - l.Logger.Printf(l.prefix + msg + l.postfix) - if l.Wpanic { - l.Logger.Panic(wpanicMsg + msg) - } -} -func (l *toggledLogger) Println(v ...interface{}) { - if !l.Enabled { - return - } - msg := trimNewline(fmt.Sprint(v...)) - l.Logger.Println(l.prefix + msg + l.postfix) - if l.Wpanic { - l.Logger.Panic(wpanicMsg + msg) - } -} - -// Debug logs debug messages -// Can be enabled by passing "-d" -var Debug *toggledLogger - -// Info logs informational message -// Can be disabled by passing "-q" -var Info *toggledLogger - -// Warn logs warnings, -// meaning nothing serious by itself but might indicate problems. -// Passing "-wpanic" will make this function panic after printing the message. -var Warn *toggledLogger - -// Fatal error, we are about to exit -var Fatal *toggledLogger - -func init() { - if terminal.IsTerminal(int(os.Stdout.Fd())) { - ColorReset = "\033[0m" - ColorGrey = "\033[2m" - ColorRed = "\033[31m" - ColorGreen = "\033[32m" - ColorYellow = "\033[33m" - } - - Debug = &toggledLogger{ - Logger: log.New(os.Stdout, "", 0), - } - Info = &toggledLogger{ - Enabled: true, - Logger: log.New(os.Stdout, "", 0), - } - Warn = &toggledLogger{ - Enabled: true, - Logger: log.New(os.Stderr, "", 0), - prefix: ColorYellow, - postfix: ColorReset, - } - Fatal = &toggledLogger{ - Enabled: true, - Logger: log.New(os.Stderr, "", 0), - prefix: ColorRed, - postfix: ColorReset, - } -} - -// SwitchToSyslog redirects the output of this logger to syslog. -// p = facility | severity -func (l *toggledLogger) SwitchToSyslog(p syslog.Priority) { - w, err := syslog.New(p, ProgramName) - if err != nil { - Warn.Printf("SwitchToSyslog: %v", err) - } else { - l.Logger.SetOutput(w) - // Disable colors - l.prefix = "" - l.postfix = "" - } -} - -// SwitchLoggerToSyslog redirects the default log.Logger that the go-fuse lib uses -// to syslog. -func SwitchLoggerToSyslog() { - p := syslog.LOG_USER | syslog.LOG_WARNING - w, err := syslog.New(p, ProgramName) - if err != nil { - Warn.Printf("SwitchLoggerToSyslog: %v", err) - } else { - log.SetPrefix("go-fuse: ") - // Disable printing the timestamp, syslog already provides that - log.SetFlags(0) - log.SetOutput(w) - } -} - -// PrintMasterkeyReminder reminds the user that he should store the master key in -// a safe place. -func PrintMasterkeyReminder(key []byte) { - if !Info.Enabled { - // Quiet mode - return - } - if !terminal.IsTerminal(int(os.Stdout.Fd())) { - // We don't want the master key to end up in a log file - Info.Printf("Not running on a terminal, suppressing master key display\n") - return - } - h := hex.EncodeToString(key) - var hChunked string - // Try to make it less scary by splitting it up in chunks - for i := 0; i < len(h); i += 8 { - hChunked += h[i : i+8] - if i < 52 { - hChunked += "-" - } - if i == 24 { - hChunked += "\n " - } - } - Info.Printf(` -Your master key is: - - %s - -If the gocryptfs.conf file becomes corrupted or you ever forget your password, -there is only one hope for recovery: The master key. Print it to a piece of -paper and store it in a drawer. This message is only printed once. - -`, ColorGrey+hChunked+ColorReset) -} diff --git a/internal/tlog/tlog_test.go b/internal/tlog/tlog_test.go deleted file mode 100644 index 2e1c034..0000000 --- a/internal/tlog/tlog_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package tlog - -import ( - "testing" -) - -// Test that trimNewline() works as expected -func TestTrimNewline(t *testing.T) { - testTable := []struct { - in string - want string - }{ - {"...\n", "..."}, - {"\n...\n", "\n..."}, - {"", ""}, - {"\n", ""}, - {"\n\n", "\n"}, - {" ", " "}, - } - for _, v := range testTable { - have := trimNewline(v.in) - if v.want != have { - t.Errorf("want=%q have=%q", v.want, have) - } - } -} diff --git a/main.go b/main.go index edd61ff..38dd16d 100644 --- a/main.go +++ b/main.go @@ -1,335 +1,3 @@ -// gocryptfs is an encrypted overlay filesystem written in Go. -// See README.md ( https://github.com/rfjakob/gocryptfs/blob/master/README.md ) -// and the official website ( https://nuetzlich.net/gocryptfs/ ) for details. package main -import ( - "fmt" - "log" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fido2" - "github.com/rfjakob/gocryptfs/internal/readpassword" - "github.com/rfjakob/gocryptfs/internal/speed" - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// GitVersion is the gocryptfs version according to git, set by build.bash -var GitVersion = "[GitVersion not set - please compile using ./build.bash]" - -// GitVersionFuse is the go-fuse library version, set by build.bash -var GitVersionFuse = "[GitVersionFuse not set - please compile using ./build.bash]" - -// BuildDate is a date string like "2017-09-06", set by build.bash -var BuildDate = "0000-00-00" - -// raceDetector is set to true by race.go if we are compiled with "go build -race" -var raceDetector bool - -// loadConfig loads the config file `args.config` and decrypts the masterkey, -// or gets via the `-masterkey` or `-zerokey` command line options, if specified. -func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile, err error) { - // First check if the file can be read at all. - cf, err = configfile.Load(args.config) - if err != nil { - tlog.Fatal.Printf("Cannot open config file: %v", err) - return nil, nil, err - } - // The user may have passed the master key on the command line (probably because - // he forgot the password). - masterkey = handleArgsMasterkey(args) - if masterkey != nil { - return masterkey, cf, nil - } - var pw []byte - if cf.IsFeatureFlagSet(configfile.FlagFIDO2) { - if args.fido2 == "" { - tlog.Fatal.Printf("Masterkey encrypted using FIDO2 token; need to use the --fido2 option.") - os.Exit(exitcodes.Usage) - } - pw = fido2.Secret(args.fido2, cf.FIDO2.CredentialID, cf.FIDO2.HMACSalt) - } else { - pw = readpassword.Once([]string(args.extpass), []string(args.passfile), "") - } - tlog.Info.Println("Decrypting master key") - masterkey, err = cf.DecryptMasterKey(pw) - for i := range pw { - pw[i] = 0 - } - - if err != nil { - tlog.Fatal.Println(err) - return nil, nil, err - } - return masterkey, cf, nil -} - -// changePassword - change the password of config file "filename" -// Does not return (calls os.Exit both on success and on error). -func changePassword(args *argContainer) { - var confFile *configfile.ConfFile - { - var masterkey []byte - var err error - masterkey, confFile, err = loadConfig(args) - if err != nil { - exitcodes.Exit(err) - } - if len(masterkey) == 0 { - log.Panic("empty masterkey") - } - if confFile.IsFeatureFlagSet(configfile.FlagFIDO2) { - tlog.Fatal.Printf("Password change is not supported on FIDO2-enabled filesystems.") - os.Exit(exitcodes.Usage) - } - tlog.Info.Println("Please enter your new password.") - newPw := readpassword.Twice([]string(args.extpass), []string(args.passfile)) - logN := confFile.ScryptObject.LogN() - if args._explicitScryptn { - logN = args.scryptn - } - confFile.EncryptKey(masterkey, newPw, logN) - for i := range newPw { - newPw[i] = 0 - } - for i := range masterkey { - masterkey[i] = 0 - } - // masterkey and newPw run out of scope here - } - // Are we resetting the password without knowing the old one using - // "-masterkey"? - if args.masterkey != "" { - bak := args.config + ".bak" - err := os.Link(args.config, bak) - if err != nil { - tlog.Fatal.Printf("Could not create backup file: %v", err) - os.Exit(exitcodes.Init) - } - tlog.Info.Printf(tlog.ColorGrey+ - "A copy of the old config file has been created at %q.\n"+ - "Delete it after you have verified that you can access your files with the new password."+ - tlog.ColorReset, bak) - } - err := confFile.WriteFile() - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.WriteConf) - } - tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset) -} - -// printVersion prints a version string like this: -// gocryptfs v1.7-32-gcf99cfd; go-fuse v1.0.0-174-g22a9cb9; 2019-05-12 go1.12 linux/amd64 -func printVersion() { - var tagsSlice []string - if stupidgcm.BuiltWithoutOpenssl { - tagsSlice = append(tagsSlice, "without_openssl") - } - tags := "" - if tagsSlice != nil { - tags = " " + strings.Join(tagsSlice, " ") - } - built := fmt.Sprintf("%s %s", BuildDate, runtime.Version()) - if raceDetector { - built += " -race" - } - fmt.Printf("%s %s%s; go-fuse %s; %s %s/%s\n", - tlog.ProgramName, GitVersion, tags, GitVersionFuse, built, - runtime.GOOS, runtime.GOARCH) -} - -func main() { - mxp := runtime.GOMAXPROCS(0) - if mxp < 4 && os.Getenv("GOMAXPROCS") == "" { - // On a 2-core machine, setting maxprocs to 4 gives 10% better performance. - // But don't override an explicitly set GOMAXPROCS env variable. - runtime.GOMAXPROCS(4) - } - // mount(1) unsets PATH. Since exec.Command does not handle this case, we set - // PATH to a default value if it's empty or unset. - if os.Getenv("PATH") == "" { - os.Setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin") - } - // Show microseconds in go-fuse debug output (-fusedebug) - log.SetFlags(log.Lmicroseconds) - var err error - // Parse all command-line options (i.e. arguments starting with "-") - // into "args". Path arguments are parsed below. - args := parseCliOpts() - // Fork a child into the background if "-fg" is not set AND we are mounting - // a filesystem. The child will do all the work. - if !args.fg && flagSet.NArg() == 2 { - ret := forkChild() - os.Exit(ret) - } - if args.debug { - tlog.Debug.Enabled = true - } - // "-v" - if args.version { - tlog.Debug.Printf("openssl=%v\n", args.openssl) - tlog.Debug.Printf("on-disk format %d\n", contentenc.CurrentVersion) - printVersion() - os.Exit(0) - } - // "-hh" - if args.hh { - helpLong() - os.Exit(0) - } - // "-speed" - if args.speed { - printVersion() - speed.Run() - os.Exit(0) - } - if args.wpanic { - tlog.Warn.Wpanic = true - tlog.Debug.Printf("Panicking on warnings") - } - // Every operation below requires CIPHERDIR. Exit if we don't have it. - if flagSet.NArg() == 0 { - if flagSet.NFlag() == 0 { - // Naked call to "gocryptfs". Just print the help text. - helpShort() - } else { - // The user has passed some flags, but CIPHERDIR is missing. State - // what is wrong. - tlog.Fatal.Printf("CIPHERDIR argument is missing") - } - os.Exit(exitcodes.Usage) - } - // Check that CIPHERDIR exists - args.cipherdir, _ = filepath.Abs(flagSet.Arg(0)) - err = isDir(args.cipherdir) - if err != nil { - tlog.Fatal.Printf("Invalid cipherdir: %v", err) - os.Exit(exitcodes.CipherDir) - } - // "-q" - if args.quiet { - tlog.Info.Enabled = false - } - // "-reverse" implies "-aessiv" - if args.reverse { - args.aessiv = true - } else { - if args.exclude != nil { - tlog.Fatal.Printf("-exclude only works in reverse mode") - os.Exit(exitcodes.ExcludeError) - } - } - // "-config" - if args.config != "" { - args.config, err = filepath.Abs(args.config) - if err != nil { - tlog.Fatal.Printf("Invalid \"-config\" setting: %v", err) - os.Exit(exitcodes.Init) - } - tlog.Info.Printf("Using config file at custom location %s", args.config) - args._configCustom = true - } else if args.reverse { - args.config = filepath.Join(args.cipherdir, configfile.ConfReverseName) - } else { - args.config = filepath.Join(args.cipherdir, configfile.ConfDefaultName) - } - // "-force_owner" - if args.force_owner != "" { - var uidNum, gidNum int64 - ownerPieces := strings.SplitN(args.force_owner, ":", 2) - if len(ownerPieces) != 2 { - tlog.Fatal.Printf("force_owner must be in form UID:GID") - os.Exit(exitcodes.Usage) - } - uidNum, err = strconv.ParseInt(ownerPieces[0], 0, 32) - if err != nil || uidNum < 0 { - tlog.Fatal.Printf("force_owner: Unable to parse UID %v as positive integer", ownerPieces[0]) - os.Exit(exitcodes.Usage) - } - gidNum, err = strconv.ParseInt(ownerPieces[1], 0, 32) - if err != nil || gidNum < 0 { - tlog.Fatal.Printf("force_owner: Unable to parse GID %v as positive integer", ownerPieces[1]) - os.Exit(exitcodes.Usage) - } - args._forceOwner = &fuse.Owner{Uid: uint32(uidNum), Gid: uint32(gidNum)} - } - // "-cpuprofile" - if args.cpuprofile != "" { - onExitFunc := setupCpuprofile(args.cpuprofile) - defer onExitFunc() - } - // "-memprofile" - if args.memprofile != "" { - onExitFunc := setupMemprofile(args.memprofile) - defer onExitFunc() - } - // "-trace" - if args.trace != "" { - onExitFunc := setupTrace(args.trace) - defer onExitFunc() - } - if args.cpuprofile != "" || args.memprofile != "" || args.trace != "" { - tlog.Info.Printf("Note: You must unmount gracefully, otherwise the profile file(s) will stay empty!\n") - } - // "-openssl" - if !args.openssl { - tlog.Debug.Printf("OpenSSL disabled, using Go GCM") - } else { - tlog.Debug.Printf("OpenSSL enabled") - } - // Operation flags - nOps := countOpFlags(&args) - if nOps == 0 { - // Default operation: mount. - if flagSet.NArg() != 2 { - prettyArgs := prettyArgs() - tlog.Info.Printf("Wrong number of arguments (have %d, want 2). You passed: %s", - flagSet.NArg(), prettyArgs) - tlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]", tlog.ProgramName) - os.Exit(exitcodes.Usage) - } - doMount(&args) - // Don't call os.Exit to give deferred functions a chance to run - return - } - if nOps > 1 { - tlog.Fatal.Printf("At most one of -info, -init, -passwd, -fsck is allowed") - os.Exit(exitcodes.Usage) - } - if flagSet.NArg() != 1 { - tlog.Fatal.Printf("The options -info, -init, -passwd, -fsck take exactly one argument, %d given", - flagSet.NArg()) - os.Exit(exitcodes.Usage) - } - // "-info" - if args.info { - info(args.config) - os.Exit(0) - } - // "-init" - if args.init { - initDir(&args) - os.Exit(0) - } - // "-passwd" - if args.passwd { - changePassword(&args) - os.Exit(0) - } - // "-fsck" - if args.fsck { - code := fsck(&args) - os.Exit(code) - } -} +func main() {} diff --git a/masterkey.go b/masterkey.go deleted file mode 100644 index 8d75c75..0000000 --- a/masterkey.go +++ /dev/null @@ -1,60 +0,0 @@ -package main - -import ( - "encoding/hex" - "os" - "strings" - - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/readpassword" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// unhexMasterKey - Convert a hex-encoded master key to binary. -// Calls os.Exit on failure. -func unhexMasterKey(masterkey string, fromStdin bool) []byte { - masterkey = strings.Replace(masterkey, "-", "", -1) - key, err := hex.DecodeString(masterkey) - if err != nil { - tlog.Fatal.Printf("Could not parse master key: %v", err) - os.Exit(exitcodes.MasterKey) - } - if len(key) != cryptocore.KeyLen { - tlog.Fatal.Printf("Master key has length %d but we require length %d", len(key), cryptocore.KeyLen) - os.Exit(exitcodes.MasterKey) - } - tlog.Info.Printf("Using explicit master key.") - if !fromStdin { - tlog.Info.Printf(tlog.ColorYellow + - "THE MASTER KEY IS VISIBLE VIA \"ps ax\" AND MAY BE STORED IN YOUR SHELL HISTORY!\n" + - "ONLY USE THIS MODE FOR EMERGENCIES" + tlog.ColorReset) - } - return key -} - -// handleArgsMasterkey looks at `args.masterkey` and `args.zerokey`, gets the -// masterkey from the source the user wanted (string on the command line, stdin, all-zero), -// and returns it in binary. Returns nil if no masterkey source was specified. -func handleArgsMasterkey(args *argContainer) (masterkey []byte) { - // "-masterkey=stdin" - if args.masterkey == "stdin" { - in := string(readpassword.Once(nil, nil, "Masterkey")) - return unhexMasterKey(in, true) - } - // "-masterkey=941a6029-3adc6a1c-..." - if args.masterkey != "" { - return unhexMasterKey(args.masterkey, false) - } - // "-zerokey" - if args.zerokey { - tlog.Info.Printf("Using all-zero dummy master key.") - tlog.Info.Printf(tlog.ColorYellow + - "ZEROKEY MODE PROVIDES NO SECURITY AT ALL AND SHOULD ONLY BE USED FOR TESTING." + - tlog.ColorReset) - return make([]byte, cryptocore.KeyLen) - } - // No master key source specified on the command line. Caller must parse - // the config file. - return nil -} diff --git a/mount.go b/mount.go deleted file mode 100644 index f992f94..0000000 --- a/mount.go +++ /dev/null @@ -1,531 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "log" - "log/syslog" - "math" - "net" - "os" - "os/exec" - "os/signal" - "path" - "path/filepath" - "runtime" - "runtime/debug" - "strings" - "sync/atomic" - "syscall" - "time" - - "golang.org/x/sys/unix" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/contentenc" - "github.com/rfjakob/gocryptfs/internal/cryptocore" - "github.com/rfjakob/gocryptfs/internal/ctlsocksrv" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/fusefrontend" - "github.com/rfjakob/gocryptfs/internal/fusefrontend_reverse" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/openfiletable" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// AfterUnmount is called after the filesystem has been unmounted. -// This can be used for cleanup and printing statistics. -type AfterUnmounter interface { - AfterUnmount() -} - -// doMount mounts an encrypted directory. -// Called from main. -func doMount(args *argContainer) { - // Check mountpoint - var err error - args.mountpoint, err = filepath.Abs(flagSet.Arg(1)) - if err != nil { - tlog.Fatal.Printf("Invalid mountpoint: %v", err) - os.Exit(exitcodes.MountPoint) - } - // We cannot mount "/home/user/.cipher" at "/home/user" because the mount - // will hide ".cipher" also for us. - if args.cipherdir == args.mountpoint || strings.HasPrefix(args.cipherdir, args.mountpoint+"/") { - tlog.Fatal.Printf("Mountpoint %q would shadow cipherdir %q, this is not supported", - args.mountpoint, args.cipherdir) - os.Exit(exitcodes.MountPoint) - } - // Reverse-mounting "/foo" at "/foo/mnt" means we would be recursively - // encrypting ourselves. - if strings.HasPrefix(args.mountpoint, args.cipherdir+"/") { - tlog.Fatal.Printf("Mountpoint %q is contained in cipherdir %q, this is not supported", - args.mountpoint, args.cipherdir) - os.Exit(exitcodes.MountPoint) - } - if args.nonempty { - err = isDir(args.mountpoint) - } else { - err = isEmptyDir(args.mountpoint) - // OSXFuse will create the mountpoint for us ( https://github.com/rfjakob/gocryptfs/issues/194 ) - if runtime.GOOS == "darwin" && os.IsNotExist(err) { - tlog.Info.Printf("Mountpoint %q does not exist, but should be created by OSXFuse", - args.mountpoint) - err = nil - } - } - if err != nil { - tlog.Fatal.Printf("Invalid mountpoint: %v", err) - os.Exit(exitcodes.MountPoint) - } - // Open control socket early so we can error out before asking the user - // for the password - if args.ctlsock != "" { - // We must use an absolute path because we cd to / when daemonizing. - // This messes up the delete-on-close logic in the unix socket object. - args.ctlsock, _ = filepath.Abs(args.ctlsock) - var sock net.Listener - sock, err = net.Listen("unix", args.ctlsock) - if err != nil { - tlog.Fatal.Printf("ctlsock: %v", err) - os.Exit(exitcodes.CtlSock) - } - args._ctlsockFd = sock - // Close also deletes the socket file - defer func() { - err = sock.Close() - if err != nil { - tlog.Warn.Printf("ctlsock close: %v", err) - } - }() - } - // Preallocation on Btrfs is broken ( https://github.com/rfjakob/gocryptfs/issues/395 ) - // and slow ( https://github.com/rfjakob/gocryptfs/issues/63 ). - if !args.noprealloc { - // darwin does not have unix.BTRFS_SUPER_MAGIC, so we define it here - const BTRFS_SUPER_MAGIC = 0x9123683e - var st unix.Statfs_t - err = unix.Statfs(args.cipherdir, &st) - // Cast to uint32 avoids compile error on arm: "constant 2435016766 overflows int32" - if err == nil && uint32(st.Type) == BTRFS_SUPER_MAGIC { - tlog.Info.Printf(tlog.ColorYellow + - "Btrfs detected, forcing -noprealloc. See https://github.com/rfjakob/gocryptfs/issues/395 for why." + - tlog.ColorReset) - args.noprealloc = true - } - } - // We cannot use JSON for pretty-printing as the fields are unexported - tlog.Debug.Printf("cli args: %#v", args) - // Initialize gocryptfs (read config file, ask for password, ...) - fs, wipeKeys := initFuseFrontend(args) - // Try to wipe secret keys from memory after unmount - defer wipeKeys() - // Initialize go-fuse FUSE server - srv := initGoFuse(fs, args) - if x, ok := fs.(AfterUnmounter); ok { - defer x.AfterUnmount() - } - - tlog.Info.Println(tlog.ColorGreen + "Filesystem mounted and ready." + tlog.ColorReset) - // We have been forked into the background, as evidenced by the set - // "notifypid". - if args.notifypid > 0 { - // Chdir to the root directory so we don't block unmounting the CWD - os.Chdir("/") - // Switch to syslog - if !args.nosyslog { - // Switch all of our logs and the generic logger to syslog - tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO) - tlog.Debug.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_DEBUG) - tlog.Warn.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_WARNING) - tlog.Fatal.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_CRIT) - tlog.SwitchLoggerToSyslog() - // Daemons should redirect stdin, stdout and stderr - redirectStdFds() - } - // Disconnect from the controlling terminal by creating a new session. - // This prevents us from getting SIGINT when the user presses Ctrl-C - // to exit a running script that has called gocryptfs. - _, err = syscall.Setsid() - if err != nil { - tlog.Warn.Printf("Setsid: %v", err) - } - // Send SIGUSR1 to our parent - sendUsr1(args.notifypid) - } - // Increase the open file limit to 4096. This is not essential, so do it after - // we have switched to syslog and don't bother the user with warnings. - setOpenFileLimit() - // Wait for SIGINT in the background and unmount ourselves if we get it. - // This prevents a dangling "Transport endpoint is not connected" - // mountpoint if the user hits CTRL-C. - handleSigint(srv, args.mountpoint) - // Return memory that was allocated for scrypt (64M by default!) and other - // stuff that is no longer needed to the OS - debug.FreeOSMemory() - // Set up autounmount, if requested. - if args.idle > 0 && !args.reverse { - // Not being in reverse mode means we always have a forward file system. - fwdFs := fs.(*fusefrontend.RootNode) - go idleMonitor(args.idle, fwdFs, srv, args.mountpoint) - } - // Wait for unmount. - srv.Wait() -} - -// Based on the EncFS idle monitor: -// https://github.com/vgough/encfs/blob/1974b417af189a41ffae4c6feb011d2a0498e437/encfs/main.cpp#L851 -// idleMonitor is a function to be run as a thread that checks for -// filesystem idleness and unmounts if we've been idle for long enough. -const checksDuringTimeoutPeriod = 4 - -func idleMonitor(idleTimeout time.Duration, fs *fusefrontend.RootNode, srv *fuse.Server, mountpoint string) { - // sleepNs is the sleep time between checks, in nanoseconds. - sleepNs := contentenc.MinUint64( - uint64(idleTimeout/checksDuringTimeoutPeriod), - uint64(2*time.Minute)) - timeoutCycles := int(math.Ceil(float64(idleTimeout) / float64(sleepNs))) - idleCount := 0 - idleTime := func() time.Duration { - return time.Duration(sleepNs * uint64(idleCount)) - } - for { - // Atomically check whether the flag is 0 and reset it to 1 if so. - isIdle := !atomic.CompareAndSwapUint32(&fs.IsIdle, 0, 1) - // Any form of current or recent access resets the idle counter. - openFileCount := openfiletable.CountOpenFiles() - if !isIdle || openFileCount > 0 { - idleCount = 0 - } else { - idleCount++ - } - tlog.Debug.Printf( - "idleMonitor: idle for %v (idleCount = %d, isIdle = %t, open = %d)", - idleTime(), idleCount, isIdle, openFileCount) - if idleCount > 0 && idleCount%timeoutCycles == 0 { - tlog.Info.Printf("idleMonitor: filesystem idle; unmounting: %s", mountpoint) - err := srv.Unmount() - if err != nil { - // We get "Device or resource busy" when a process has its - // working directory on the mount. Log the event at Info level - // so the user finds out why their filesystem does not get - // unmounted. - tlog.Info.Printf("idleMonitor: unmount failed: %v. Resetting idle time.", err) - idleCount = 0 - } - } - time.Sleep(time.Duration(sleepNs)) - } -} - -// setOpenFileLimit tries to increase the open file limit to 4096 (the default hard -// limit on Linux). -func setOpenFileLimit() { - var lim syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim) - if err != nil { - tlog.Warn.Printf("Getting RLIMIT_NOFILE failed: %v", err) - return - } - if lim.Cur >= 4096 { - return - } - lim.Cur = 4096 - err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim) - if err != nil { - tlog.Warn.Printf("Setting RLIMIT_NOFILE to %+v failed: %v", lim, err) - // %+v output: "{Cur:4097 Max:4096}" ^ - } -} - -// initFuseFrontend - initialize gocryptfs/internal/fusefrontend -// Calls os.Exit on errors -func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys func()) { - var err error - var confFile *configfile.ConfFile - // Get the masterkey from the command line if it was specified - masterkey := handleArgsMasterkey(args) - // Otherwise, load masterkey from config file (normal operation). - // Prompts the user for the password. - if masterkey == nil { - masterkey, confFile, err = loadConfig(args) - if err != nil { - if args._ctlsockFd != nil { - // Close the socket file (which also deletes it) - args._ctlsockFd.Close() - } - exitcodes.Exit(err) - } - } - // Reconciliate CLI and config file arguments into a fusefrontend.Args struct - // that is passed to the filesystem implementation - cryptoBackend := cryptocore.BackendGoGCM - if args.openssl { - cryptoBackend = cryptocore.BackendOpenSSL - } - if args.aessiv { - cryptoBackend = cryptocore.BackendAESSIV - } - // forceOwner implies allow_other, as documented. - // Set this early, so args.allow_other can be relied on below this point. - if args._forceOwner != nil { - args.allow_other = true - } - frontendArgs := fusefrontend.Args{ - Cipherdir: args.cipherdir, - PlaintextNames: args.plaintextnames, - LongNames: args.longnames, - ConfigCustom: args._configCustom, - NoPrealloc: args.noprealloc, - SerializeReads: args.serialize_reads, - ForceDecode: args.forcedecode, - ForceOwner: args._forceOwner, - Exclude: args.exclude, - ExcludeWildcard: args.excludeWildcard, - ExcludeFrom: args.excludeFrom, - Suid: args.suid, - KernelCache: args.kernel_cache, - SharedStorage: args.sharedstorage, - } - // confFile is nil when "-zerokey" or "-masterkey" was used - if confFile != nil { - // Settings from the config file override command line args - frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(configfile.FlagPlaintextNames) - args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64) - args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF) - if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) { - cryptoBackend = cryptocore.BackendAESSIV - } else if args.reverse { - tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file") - os.Exit(exitcodes.Usage) - } - } - // If allow_other is set and we run as root, try to give newly created files to - // the right user. - if args.allow_other && os.Getuid() == 0 { - frontendArgs.PreserveOwner = true - } - jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t") - tlog.Debug.Printf("frontendArgs: %s", string(jsonBytes)) - - // Init crypto backend - cCore := cryptocore.New(masterkey, cryptoBackend, contentenc.DefaultIVBits, args.hkdf, args.forcedecode) - cEnc := contentenc.New(cCore, contentenc.DefaultBS, args.forcedecode) - nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.raw64) - // Init badname patterns - nameTransform.BadnamePatterns = make([]string, 0) - for _, pattern := range args.badname { - _, err := filepath.Match(pattern, "") // Make sure pattern is valid - if err != nil { - tlog.Fatal.Printf("-badname: invalid pattern %q supplied", pattern) - os.Exit(exitcodes.Usage) - } else { - nameTransform.BadnamePatterns = append(nameTransform.BadnamePatterns, pattern) - } - } - // After the crypto backend is initialized, - // we can purge the master key from memory. - for i := range masterkey { - masterkey[i] = 0 - } - masterkey = nil - // Spawn fusefrontend - if args.reverse { - if cryptoBackend != cryptocore.BackendAESSIV { - log.Panic("reverse mode must use AES-SIV, everything else is insecure") - } - rootNode = fusefrontend_reverse.NewRootNode(frontendArgs, cEnc, nameTransform) - } else { - rootNode = fusefrontend.NewRootNode(frontendArgs, cEnc, nameTransform) - } - // We have opened the socket early so that we cannot fail here after - // asking the user for the password - if args._ctlsockFd != nil { - go ctlsocksrv.Serve(args._ctlsockFd, rootNode.(ctlsocksrv.Interface)) - } - return rootNode, func() { cCore.Wipe() } -} - -// initGoFuse calls into go-fuse to mount `rootNode` on `args.mountpoint`. -// The mountpoint is ready to use when the functions returns. -// On error, it calls os.Exit and does not return. -func initGoFuse(rootNode fs.InodeEmbedder, args *argContainer) *fuse.Server { - var fuseOpts *fs.Options - sec := time.Second - if args.sharedstorage { - // sharedstorage mode sets all cache timeouts to zero so changes to the - // backing shared storage show up immediately. - // Hard links are disabled by using automatically incrementing - // inode numbers provided by go-fuse. - fuseOpts = &fs.Options{ - FirstAutomaticIno: 1000, - } - } else { - fuseOpts = &fs.Options{ - // These options are to be compatible with libfuse defaults, - // making benchmarking easier. - NegativeTimeout: &sec, - AttrTimeout: &sec, - EntryTimeout: &sec, - } - } - fuseOpts.NullPermissions = true - // Enable go-fuse warnings - fuseOpts.Logger = log.New(os.Stderr, "go-fuse: ", log.Lmicroseconds) - fuseOpts.MountOptions = fuse.MountOptions{ - // Writes and reads are usually capped at 128kiB on Linux through - // the FUSE_MAX_PAGES_PER_REQ kernel constant in fuse_i.h. Our - // sync.Pool buffer pools are sized acc. to the default. Users may set - // the kernel constant higher, and Synology NAS kernels are known to - // have it >128kiB. We cannot handle more than 128kiB, so we tell - // the kernel to limit the size explicitly. - MaxWrite: fuse.MAX_KERNEL_WRITE, - Options: []string{fmt.Sprintf("max_read=%d", fuse.MAX_KERNEL_WRITE)}, - Debug: args.fusedebug, - } - - mOpts := &fuseOpts.MountOptions - if args.allow_other { - tlog.Info.Printf(tlog.ColorYellow + "The option \"-allow_other\" is set. Make sure the file " + - "permissions protect your data from unwanted access." + tlog.ColorReset) - mOpts.AllowOther = true - // Make the kernel check the file permissions for us - mOpts.Options = append(mOpts.Options, "default_permissions") - } - if args.acl { - mOpts.EnableAcl = true - } - if args.forcedecode { - tlog.Info.Printf(tlog.ColorYellow + "THE OPTION \"-forcedecode\" IS ACTIVE. GOCRYPTFS WILL RETURN CORRUPT DATA!" + - tlog.ColorReset) - } - // fusermount from libfuse 3.x removed the "nonempty" option and exits - // with an error if it sees it. Only add it to the options on libfuse 2.x. - if args.nonempty && haveFusermount2() { - mOpts.Options = append(mOpts.Options, "nonempty") - } - // Set values shown in "df -T" and friends - // First column, "Filesystem" - fsname := args.cipherdir - if args.fsname != "" { - fsname = args.fsname - } - fsname2 := strings.Replace(fsname, ",", "_", -1) - if fsname2 != fsname { - tlog.Warn.Printf("Warning: %q will be displayed as %q in \"df -T\"", fsname, fsname2) - fsname = fsname2 - } - mOpts.Options = append(mOpts.Options, "fsname="+fsname) - // Second column, "Type", will be shown as "fuse." + Name - mOpts.Name = "gocryptfs" - if args.reverse { - mOpts.Name += "-reverse" - } - // Add a volume name if running osxfuse. Otherwise the Finder will show it as - // something like "osxfuse Volume 0 (gocryptfs)". - if runtime.GOOS == "darwin" { - volname := strings.Replace(path.Base(args.mountpoint), ",", "_", -1) - mOpts.Options = append(mOpts.Options, "volname="+volname) - } - // The kernel enforces read-only operation, we just have to pass "ro". - // Reverse mounts are always read-only. - if args.ro || args.reverse { - mOpts.Options = append(mOpts.Options, "ro") - } else if args.rw { - mOpts.Options = append(mOpts.Options, "rw") - } - // If both "nosuid" & "suid", "nodev" & "dev", etc were passed, the safer - // option wins. - if args.nosuid { - mOpts.Options = append(mOpts.Options, "nosuid") - } else if args.suid { - mOpts.Options = append(mOpts.Options, "suid") - } - if args.nodev { - mOpts.Options = append(mOpts.Options, "nodev") - } else if args.dev { - mOpts.Options = append(mOpts.Options, "dev") - } - if args.noexec { - mOpts.Options = append(mOpts.Options, "noexec") - } else if args.exec { - mOpts.Options = append(mOpts.Options, "exec") - } - // Add additional mount options (if any) after the stock ones, so the user has - // a chance to override them. - if args.ko != "" { - parts := strings.Split(args.ko, ",") - tlog.Debug.Printf("Adding -ko mount options: %v", parts) - mOpts.Options = append(mOpts.Options, parts...) - } - srv, err := fs.Mount(args.mountpoint, rootNode, fuseOpts) - if err != nil { - tlog.Fatal.Printf("fs.Mount failed: %s", strings.TrimSpace(err.Error())) - if runtime.GOOS == "darwin" { - tlog.Info.Printf("Maybe you should run: /Library/Filesystems/osxfuse.fs/Contents/Resources/load_osxfuse") - } - os.Exit(exitcodes.FuseNewServer) - } - - // All FUSE file and directory create calls carry explicit permission - // information. We need an unrestricted umask to create the files and - // directories with the requested permissions. - syscall.Umask(0000) - - return srv -} - -// haveFusermount2 finds out if the "fusermount" binary is from libfuse 2.x. -func haveFusermount2() bool { - path, err := exec.LookPath("fusermount") - if err != nil { - path = "/bin/fusermount" - } - cmd := exec.Command(path, "-V") - var out bytes.Buffer - cmd.Stdout = &out - err = cmd.Run() - if err != nil { - tlog.Warn.Printf("warning: haveFusermount2: %v", err) - return false - } - // libfuse 2: fusermount version: 2.9.9 - // libfuse 3: fusermount3 version: 3.9.0 - v := out.String() - if strings.HasPrefix(v, "fusermount version") { - return true - } - return false -} - -func handleSigint(srv *fuse.Server, mountpoint string) { - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) - signal.Notify(ch, syscall.SIGTERM) - go func() { - <-ch - unmount(srv, mountpoint) - os.Exit(exitcodes.SigInt) - }() -} - -// unmount() calls srv.Unmount(), and if that fails, calls "fusermount -u -z" -// (lazy unmount). -func unmount(srv *fuse.Server, mountpoint string) { - err := srv.Unmount() - if err != nil { - tlog.Warn.Printf("unmount: srv.Unmount returned %v", err) - if runtime.GOOS == "linux" { - // MacOSX does not support lazy unmount - tlog.Info.Printf("Trying lazy unmount") - cmd := exec.Command("fusermount", "-u", "-z", mountpoint) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Run() - } - } -} diff --git a/package-release-tarballs.bash b/package-release-tarballs.bash deleted file mode 100755 index ac651bf..0000000 --- a/package-release-tarballs.bash +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -set -eu - -cd "$(dirname "$0")" - -SIGNME="" - -# git_archive_extra PREFIX EXTRA1 [EXTRA2 ...] -# -# Call git-archive and add additional files to the tarball. -# Output tarball is called "$PREFIX.tar.gz" and contains one folder -# called "$PREFIX". -git_archive_extra() { - local PREFIX=$1 - shift - # Add files tracked in git - git archive --prefix "$PREFIX/" -o "$PREFIX.tar" HEAD - # Add "extra" files - tar --owner=root --group=root --transform "s!^!$PREFIX/!" --append -f "$PREFIX.tar" "$@" - # Compress - gzip -f "$PREFIX.tar" -} - -package_source() { - local GITVERSION - GITVERSION=$(git describe --tags --dirty) - echo "$GITVERSION" > VERSION - - # Render the manpages and include them in the tarball. This - # avoids a build-dependency to pandoc. - ./Documentation/MANPAGE-render.bash - - # gocryptfs source tarball - local PREFIX_SRC_ONLY=gocryptfs_${GITVERSION}_src - git_archive_extra "$PREFIX_SRC_ONLY" VERSION Documentation/*.1 - - # gocryptfs source + dependencies tarball - go mod vendor - local PREFIX_SRC_DEPS=gocryptfs_${GITVERSION}_src-deps - git_archive_extra "$PREFIX_SRC_DEPS" VERSION Documentation/*.1 vendor - - rm VERSION - rm -R vendor - - echo "Tars created." - SIGNME+=" $PREFIX_SRC_ONLY.tar.gz $PREFIX_SRC_DEPS.tar.gz" -} - -package_static_binary() { - # Compiles the gocryptfs binary and sets $GITVERSION - source build-without-openssl.bash - - if ldd gocryptfs > /dev/null ; then - echo "error: compiled gocryptfs binary is not static" - exit 1 - fi - - # Build man pages gocryptfs.1 & gocryptfs-xray.1 - ./Documentation/MANPAGE-render.bash > /dev/null - - local ARCH - ARCH=$(go env GOARCH) - local OS - OS=$(go env GOOS) - - local TARBALL - TARBALL=gocryptfs_${GITVERSION}_${OS}-static_${ARCH}.tar - local TARGZ - TARGZ=$TARBALL.gz - - tar --owner=root --group=root --create -vf "$TARBALL" gocryptfs - tar --owner=root --group=root --append -vf "$TARBALL" -C gocryptfs-xray gocryptfs-xray - tar --owner=root --group=root --append -vf "$TARBALL" -C Documentation gocryptfs.1 gocryptfs-xray.1 - - gzip -f "$TARBALL" - - echo "Tar created." - SIGNME+=" $TARGZ" -} - -signing_hint() { - local GITVERSION - GITVERSION=$(git describe --tags --dirty) - - echo "Hint for signing:" - echo " for i in gocryptfs_${GITVERSION}_*.tar.gz ; do gpg -u 23A02740 --armor --detach-sig \$i ; done" -} - -if git describe --dirty | grep dirty ; then - echo "Tree is dirty - I will not package this!" - exit 1 -fi - -package_source -package_static_binary -signing_hint diff --git a/profiling.go b/profiling.go deleted file mode 100644 index 11d6326..0000000 --- a/profiling.go +++ /dev/null @@ -1,95 +0,0 @@ -package main - -import ( - "os" - "runtime/pprof" - "runtime/trace" - "time" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// setupCpuprofile is called to handle a non-empty "-cpuprofile" cli argument -func setupCpuprofile(cpuprofileArg string) func() { - tlog.Info.Printf("Writing CPU profile to %s", cpuprofileArg) - f, err := os.Create(cpuprofileArg) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Profiler) - } - err = pprof.StartCPUProfile(f) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Profiler) - } - return func() { - pprof.StopCPUProfile() - } -} - -// setupTrace is called to handle a non-empty "-memprofile" cli argument -func setupMemprofile(memprofileArg string) func() { - tlog.Info.Printf("Will write memory profile to %q", memprofileArg) - f, err := os.Create(memprofileArg) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Profiler) - } - exiting := false - // Write the memory profile to disk every 60 seconds to get the in-use - // memory stats. - go func() { - for { - time.Sleep(60 * time.Second) - if exiting { - return - } - _, err = f.Seek(0, 0) - if err != nil { - tlog.Warn.Printf("memprofile: Seek failed: %v", err) - return - } - err = f.Truncate(0) - if err != nil { - tlog.Warn.Printf("memprofile: Truncate failed: %v", err) - return - } - err = pprof.WriteHeapProfile(f) - if err == nil { - tlog.Info.Printf("memprofile: periodic write to %q succeeded", - memprofileArg) - } else { - tlog.Warn.Printf("memprofile: periodic WriteHeapProfile failed: %v", err) - return - } - } - }() - // Final write on exit. - return func() { - exiting = true - err = pprof.WriteHeapProfile(f) - if err != nil { - tlog.Warn.Printf("memprofile: on-exit WriteHeapProfile failed: %v", err) - } - f.Close() - } -} - -// setupTrace is called to handle a non-empty "-trace" cli argument -func setupTrace(traceArg string) func() { - tlog.Info.Printf("Writing execution trace to %s", traceArg) - f, err := os.Create(traceArg) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Profiler) - } - err = trace.Start(f) - if err != nil { - tlog.Fatal.Println(err) - os.Exit(exitcodes.Profiler) - } - return func() { - trace.Stop() - } -} diff --git a/profiling/ls.bash b/profiling/ls.bash deleted file mode 100755 index 5f736b6..0000000 --- a/profiling/ls.bash +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -# Download /tmp/linux-3.0.tar.gz -../tests/dl-linux-tarball.bash - -T=$(mktemp -d) -mkdir $T/a $T/b - -../gocryptfs -init -quiet -scryptn 10 -extpass "echo test" $T/a -../gocryptfs -quiet -nosyslog -extpass "echo test" $T/a $T/b - -# Cleanup trap -trap "cd /; fusermount -u -z $T/b; rm -Rf $T/a" EXIT - -echo "Creating 40000 empty files (linux-3.0.tar.gz contains 36782 files)..." -SECONDS=0 -for dir in $(seq -w 1 200); do - mkdir $T/b/$dir - ( cd $T/b/$dir ; touch $(seq -w 1 200) ) -done -echo "done, $SECONDS seconds" - -echo "Remount..." -fusermount -u $T/b -../gocryptfs -quiet -nosyslog -extpass "echo test" -cpuprofile $T/cprof -memprofile $T/mprof \ - $T/a $T/b - -echo "Running ls under profiler (3x)..." -for i in 1 2 3; do -SECONDS=0 -ls -lR $T/b > /dev/null -echo "$i done, $SECONDS seconds" -done - -echo -echo "Hint: go tool pprof ../gocryptfs $T/cprof" -echo " go tool pprof -alloc_space ../gocryptfs $T/mprof" diff --git a/profiling/streaming-read.bash b/profiling/streaming-read.bash deleted file mode 100755 index df75c68..0000000 --- a/profiling/streaming-read.bash +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -T=$(mktemp -d) -mkdir $T/a $T/b - -../gocryptfs -init -quiet -scryptn 10 -extpass "echo test" $T/a -../gocryptfs -quiet -extpass "echo test" $T/a $T/b - -# Cleanup trap -trap "cd /; fusermount -u -z $T/b; rm -Rf $T/a" EXIT - -# Write 100MB test file -dd if=/dev/zero of=$T/b/zero bs=1M count=100 status=none - -# Remount with profiling -fusermount -u $T/b -../gocryptfs -quiet -extpass "echo test" -cpuprofile $T/cprof -memprofile $T/mprof \ - $T/a $T/b - -# Read 10 x 100MB instead of 1 x 1GB to keep the used disk space low -for i in $(seq 1 10); do - dd if=$T/b/zero of=/dev/null bs=1M count=100 -done - -echo -echo "Hint: go tool pprof ../gocryptfs $T/cprof" -echo " go tool pprof -alloc_space ../gocryptfs $T/mprof" diff --git a/profiling/streaming-write.bash b/profiling/streaming-write.bash deleted file mode 100755 index 7732cfb..0000000 --- a/profiling/streaming-write.bash +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -T=$(mktemp -d) -mkdir $T/a $T/b - -../gocryptfs -init -quiet -scryptn 10 -extpass "echo test" $T/a -../gocryptfs -quiet -extpass "echo test" -cpuprofile $T/cprof -memprofile $T/mprof \ - $T/a $T/b - -# Cleanup trap -trap "cd /; fusermount -u -z $T/b; rm -Rf $T/a" EXIT - -# Write 10 x 100MB instead of 1 x 1GB to keep the used disk space low -for i in $(seq 1 10); do - dd if=/dev/zero of=$T/b/zero bs=1M count=100 -done - -echo -echo "Hint: go tool pprof ../gocryptfs $T/cprof" -echo " go tool pprof -alloc_space ../gocryptfs $T/mprof" diff --git a/profiling/tar-extract.bash b/profiling/tar-extract.bash deleted file mode 100755 index 21b2e2b..0000000 --- a/profiling/tar-extract.bash +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -# Download /tmp/linux-3.0.tar.gz -../tests/dl-linux-tarball.bash - -T=$(mktemp -d) -mkdir $T/a $T/b - -../gocryptfs -init -quiet -scryptn 10 -extpass "echo test" $T/a -../gocryptfs -quiet -extpass "echo test" -cpuprofile $T/cprof -memprofile $T/mprof \ - $T/a $T/b - -# Cleanup trap -trap "cd /; fusermount -u -z $T/b; rm -Rf $T/a" EXIT - -echo "Extracting..." -time tar xzf /tmp/linux-3.0.tar.gz -C $T/b - -echo -echo "Hint: go tool pprof ../gocryptfs $T/cprof" -echo " go tool pprof -alloc_space ../gocryptfs $T/mprof" diff --git a/profiling/write-trace.bash b/profiling/write-trace.bash deleted file mode 100755 index 3475140..0000000 --- a/profiling/write-trace.bash +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -eu -# -# Write an execution trace of writing 100MB of data -# to a new gocryptfs mount on /tmp - -cd "$(dirname "$0")" - -T=$(mktemp -d) -mkdir $T/a $T/b - -../gocryptfs -init -quiet -scryptn 10 -extpass "echo test" $T/a -../gocryptfs -quiet -extpass "echo test" -trace $T/trace \ - $T/a $T/b - -# Cleanup trap -trap "cd /; fusermount -u -z $T/b; rm -Rf $T/a" EXIT - -# Write only 1x100MB, otherwise the trace gets too big. -dd if=/dev/zero of=$T/b/zero bs=1M count=100 - -echo -echo "Hint: go tool trace $T/trace" - diff --git a/race.go b/race.go deleted file mode 100644 index a17501a..0000000 --- a/race.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build race - -package main - -func init() { - // adds " -race" to the output of "gocryptfs -version" - raceDetector = true -} diff --git a/sendusr1.go b/sendusr1.go deleted file mode 100644 index 0fdcd0e..0000000 --- a/sendusr1.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "os" - "syscall" - - "github.com/rfjakob/gocryptfs/internal/tlog" -) - -// Send signal USR1 to "pid" (usually our parent process). This notifies it -// that the mounting has completed successfully. -func sendUsr1(pid int) { - p, err := os.FindProcess(pid) - if err != nil { - tlog.Warn.Printf("sendUsr1: FindProcess: %v\n", err) - return - } - err = p.Signal(syscall.SIGUSR1) - if err != nil { - tlog.Warn.Printf("sendUsr1: Signal: %v\n", err) - } -} diff --git a/test-without-openssl.bash b/test-without-openssl.bash deleted file mode 100755 index 3f9de9e..0000000 --- a/test-without-openssl.bash +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -eu - -cd "$(dirname "$0")" - -./test.bash -tags without_openssl "$@" diff --git a/test.bash b/test.bash deleted file mode 100755 index 091f0ac..0000000 --- a/test.bash +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash - -if [[ -z $TMPDIR ]]; then - TMPDIR=/var/tmp - export TMPDIR -else - echo "Using TMPDIR=$TMPDIR" -fi - -set -eu - -cd "$(dirname "$0")" -export GO111MODULE=on -MYNAME=$(basename "$0") -TESTDIR=$TMPDIR/gocryptfs-test-parent-$UID -mkdir -p "$TESTDIR" -LOCKFILE=$TESTDIR/$MYNAME.lock - -function unmount_leftovers { - RET=0 - for i in $(mount | grep "$TESTDIR" | cut -f3 -d" "); do - echo "Warning: unmounting leftover filesystem: $i" - tests/fuse-unmount.bash "$i" - RET=1 - done - return $RET -} - -( -# Prevent multiple parallel test.bash instances as this causes -# all kinds of mayham -if ! command -v flock > /dev/null ; then - echo "flock is not available, skipping" -elif ! flock -n 200 ; then - echo "Could not acquire lock on $LOCKFILE - already running?" - exit 1 -fi - -# Clean up dangling filesystems and don't exit if we found some -unmount_leftovers || true - -./build-without-openssl.bash -# Don't build with openssl if we were passed "-tags without_openssl" -if [[ "$*" != *without_openssl* ]] ; then - ./build.bash -fi - -if ! go tool | grep vet > /dev/null ; then - echo "'go tool vet' not available - skipping" -elif [[ -d vendor ]] ; then - echo "vendor directory exists, skipping 'go tool vet'" -else - go vet "$@" . -fi - -if command -v shellcheck > /dev/null ; then - # SC2002 = useless cat. Does no harm, disable the check. - shellcheck -x -e SC2002 ./*.bash -else - echo "shellcheck not installed - skipping" -fi - -# We don't want all the subprocesses -# holding the lock file open -# vvvvv -go test -count 1 ./... "$@" 200>&- -# ^^^^^^^^ -# Disable result caching - -# Clean up dangling filesystems but do exit with an error if we found one -unmount_leftovers || { echo "Error: the tests left mounted filesystems behind" ; exit 1 ; } - -# The tests cannot to this themselves as they are run in parallel. -# Don't descend into possibly still mounted example filesystems. -if [[ $OSTYPE == *linux* ]] ; then - rm -Rf --one-file-system "$TESTDIR" -else - # MacOS "rm" does not understand "--one-file-system" - rm -Rf "$TESTDIR" -fi - -if grep -R "panic(" ./*.go internal ; then - echo "$MYNAME: Please use log.Panic instead of naked panic!" - exit 1 -fi - -# All functions from the commit msg in https://go-review.googlesource.com/c/go/+/210639 -if find . -type f -name \*.go -print0 | xargs -0 grep -E 'syscall.(Setegid|Seteuid|Setgroups|Setgid|Setregid|Setreuid|Setresgid|Setresuid|Setuid)\(' ; then - echo "$MYNAME: You probably want to use unix.Setgroups and friends. See the comments in OpenatUser() for why." - exit 1 -fi - -) 200> "$LOCKFILE" diff --git a/tests/canonical-benchmarks.bash b/tests/canonical-benchmarks.bash deleted file mode 100755 index 71563ab..0000000 --- a/tests/canonical-benchmarks.bash +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -eu -# -# Run the set of "canonical" benchmarks that are shown on -# https://nuetzlich.net/gocryptfs/comparison/ -# against the directory passed as "$1". -# -# This is called by the top-level script "benchmark.bash". - -cd "$(dirname "$0")" -MYNAME=$(basename "$0") -MD5="$PWD/stress_tests/linux-3.0.md5sums" - -if [ $# -ne 1 ]; then - echo "usage: $MYNAME TESTDIR" - exit 1 -fi - -# Download /tmp/linux-3.0.tar.gz -./dl-linux-tarball.bash - -# cd to TESTDIR -cd "$1" - -# Execute command, discard all stdout output, print elapsed time -# (to stderr, unfortunately). -function etime { - # Make the bash builtin "time" print out only the elapsed wall clock - # seconds - TIMEFORMAT=%R - time "$@" > /dev/null -} - -echo -n "WRITE: " -dd if=/dev/zero of=zero bs=131072 count=2000 2>&1 | tail -n 1 -sleep 0.1 -echo -n "READ: " -dd if=zero of=/dev/null bs=131072 count=2000 2>&1 | tail -n 1 -rm zero -sleep 0.1 -echo -n "UNTAR: " -etime tar xzf /tmp/linux-3.0.tar.gz -sleep 0.1 -echo -n "MD5: " -etime md5sum --quiet -c $MD5 -sleep 0.1 -echo -n "LS: " -etime ls -lR linux-3.0 -sleep 0.1 -echo -n "RM: " -etime rm -Rf linux-3.0 diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go deleted file mode 100644 index 9248f5d..0000000 --- a/tests/cli/cli_test.go +++ /dev/null @@ -1,888 +0,0 @@ -package cli - -// Test CLI operations like "-init", "-password" etc - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" - "strconv" - "strings" - "sync" - "syscall" - "testing" - "time" - - "github.com/rfjakob/gocryptfs/internal/configfile" - "github.com/rfjakob/gocryptfs/internal/exitcodes" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var testPw = []byte("test") - -func TestMain(m *testing.M) { - test_helpers.ResetTmpDir(false) - before := test_helpers.ListFds(0, "") - r := m.Run() - after := test_helpers.ListFds(0, "") - if len(before) != len(after) { - fmt.Printf("fd leak in test process? before, after:\n%v\n%v\n", before, after) - os.Exit(1) - } - os.Exit(r) -} - -// Test -init flag -func TestInit(t *testing.T) { - dir := test_helpers.InitFS(t) - _, c, err := configfile.LoadAndDecrypt(dir+"/"+configfile.ConfDefaultName, testPw) - if err != nil { - t.Fatal(err) - } - if c.IsFeatureFlagSet(configfile.FlagAESSIV) { - t.Error("AESSIV flag should not be set") - } -} - -// Test that gocryptfs.conf and gocryptfs.diriv are there with the expected -// permissions after -init -func TestInitFilePerms(t *testing.T) { - dir := test_helpers.InitFS(t) - var st syscall.Stat_t - syscall.Stat(dir+"/gocryptfs.conf", &st) - perms := st.Mode & 0777 - if perms != 0400 { - t.Errorf("Wrong permissions for gocryptfs.conf: %#o", perms) - } - st = syscall.Stat_t{} - syscall.Stat(dir+"/gocryptfs.diriv", &st) - perms = st.Mode & 0777 - // From v1.7.1, these are created with 0440 permissions, see - // https://github.com/rfjakob/gocryptfs/issues/387 . - // From v2.0, created with 0444 perms, see - // https://github.com/rfjakob/gocryptfs/issues/539 . - if perms != 0444 { - t.Errorf("Wrong permissions for gocryptfs.diriv: %#o", perms) - } -} - -// Test -init with -devrandom flag -func TestInitDevRandom(t *testing.T) { - test_helpers.InitFS(t, "-devrandom") -} - -// Test -init with -aessiv -func TestInitAessiv(t *testing.T) { - dir := test_helpers.InitFS(t, "-aessiv") - _, c, err := configfile.LoadAndDecrypt(dir+"/"+configfile.ConfDefaultName, testPw) - if err != nil { - t.Fatal(err) - } - if !c.IsFeatureFlagSet(configfile.FlagAESSIV) { - t.Error("AESSIV flag should be set but is not") - } -} - -// Test -init with -reverse -func TestInitReverse(t *testing.T) { - dir := test_helpers.InitFS(t, "-reverse") - _, c, err := configfile.LoadAndDecrypt(dir+"/"+configfile.ConfReverseName, testPw) - if err != nil { - t.Fatal(err) - } - if !c.IsFeatureFlagSet(configfile.FlagAESSIV) { - t.Error("AESSIV flag should be set but is not") - } -} - -// testPasswd changes the password from "test" to "test" using -// the -extpass method, then from "test" to "newpasswd" using the -// stdin method. -func testPasswd(t *testing.T, dir string, extraArgs ...string) { - // Change password using "-extpass" - args := []string{"-q", "-passwd", "-extpass", "echo test"} - args = append(args, extraArgs...) - args = append(args, dir) - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() - if err != nil { - t.Error(err) - } - // Change password using stdin - args = []string{"-q", "-passwd"} - args = append(args, extraArgs...) - args = append(args, dir) - cmd = exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - p, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Error(err) - } - // Old password - p.Write([]byte("test\n")) - // New password - p.Write([]byte("newpasswd\n")) - p.Close() - err = cmd.Wait() - if err != nil { - t.Error(err) - } -} - -// Test -passwd flag -func TestPasswd(t *testing.T) { - // Create FS - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - // Add content - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo test") - file1 := mnt + "/file1" - err := ioutil.WriteFile(file1, []byte("somecontent"), 0600) - if err != nil { - t.Fatal(err) - } - err = test_helpers.UnmountErr(mnt) - if err != nil { - t.Fatal(err) - } - // Change password to "newpasswd" - testPasswd(t, dir) - // Mount and verify - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo newpasswd") - content, err := ioutil.ReadFile(file1) - if err != nil { - t.Error(err) - } else if string(content) != "somecontent" { - t.Errorf("wrong content: %q", string(content)) - } - err = test_helpers.UnmountErr(mnt) - if err != nil { - t.Fatal(err) - } -} - -// cp copies file at `src` to `dst`, overwriting -// `dst` if it already exists. Calls t.Fatal on failure. -func cp(t *testing.T, src string, dst string) { - conf, err := ioutil.ReadFile(src) - if err != nil { - t.Fatal(err) - } - syscall.Unlink(dst) - err = ioutil.WriteFile(dst, conf, 0600) - if err != nil { - t.Fatal(err) - } -} - -// Test -passwd with -masterkey -func TestPasswdMasterkey(t *testing.T) { - // Create FS - dir := test_helpers.InitFS(t) - // Overwrite with config with known master key - cp(t, "gocryptfs.conf.b9e5ba23", dir+"/gocryptfs.conf") - // Add content - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo test") - file1 := mnt + "/file1" - err := ioutil.WriteFile(file1, []byte("somecontent"), 0600) - if err != nil { - t.Fatal(err) - } - test_helpers.UnmountPanic(mnt) - // Change password using stdin - args := []string{"-q", "-passwd", "-masterkey", - "b9e5ba23-981a22b8-c8d790d8-627add29-f680513f-b7b7035f-d203fb83-21d82205"} - args = append(args, dir) - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - p, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Error(err) - } - // New password - p.Write([]byte("newpasswd\n")) - p.Close() - err = cmd.Wait() - if err != nil { - t.Error(err) - } - // Mount and verify - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo newpasswd") - content, err := ioutil.ReadFile(file1) - if err != nil { - t.Error(err) - } else if string(content) != "somecontent" { - t.Errorf("wrong content: %q", string(content)) - } - test_helpers.UnmountPanic(mnt) -} - -// Test -passwd with -masterkey=stdin -func TestPasswdMasterkeyStdin(t *testing.T) { - // Create FS - dir := test_helpers.InitFS(t) - // Overwrite with config with known master key - cp(t, "gocryptfs.conf.b9e5ba23", dir+"/gocryptfs.conf") - // Add content - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo test") - file1 := mnt + "/file1" - err := ioutil.WriteFile(file1, []byte("somecontent"), 0600) - if err != nil { - t.Fatal(err) - } - test_helpers.UnmountPanic(mnt) - // Change password using stdin - args := []string{"-q", "-passwd", "-masterkey=stdin"} - args = append(args, dir) - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - p, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Error(err) - } - // Masterkey - p.Write([]byte("b9e5ba23-981a22b8-c8d790d8-627add29-f680513f-b7b7035f-d203fb83-21d82205\n")) - // New password - p.Write([]byte("newpasswd\n")) - p.Close() - err = cmd.Wait() - if err != nil { - t.Fatal(err) - } - // Mount and verify - test_helpers.MountOrFatal(t, dir, mnt, "-extpass", "echo newpasswd") - content, err := ioutil.ReadFile(file1) - if err != nil { - t.Fatal(err) - } else if string(content) != "somecontent" { - t.Errorf("wrong content: %q", string(content)) - } - test_helpers.UnmountPanic(mnt) -} - -// Test -passwd with -reverse -func TestPasswdReverse(t *testing.T) { - // Create FS - dir := test_helpers.InitFS(t, "-reverse") - testPasswd(t, dir, "-reverse") -} - -// Test -passwd with -scryptn -func TestPasswdScryptn(t *testing.T) { - dir := test_helpers.InitFS(t) - cf, err := configfile.Load(dir + "/gocryptfs.conf") - if err != nil { - t.Fatal(err) - } - testPasswd(t, dir, "-scryptn", strconv.Itoa(cf.ScryptObject.LogN()+1)) - cf2, err := configfile.Load(dir + "/gocryptfs.conf") - if err != nil { - t.Fatal(err) - } - if cf2.ScryptObject.LogN() != cf.ScryptObject.LogN()+1 { - t.Errorf("wrong logN value %d", cf2.ScryptObject.LogN()) - } -} - -// Test -init & -config flag -func TestInitConfig(t *testing.T) { - config := test_helpers.TmpDir + "/TestInitConfig.conf" - dir := test_helpers.InitFS(t, "-config="+config) - - _, err := os.Stat(config) - if err != nil { - t.Fatal(err) - } - - // Test -passwd & -config - cmd2 := exec.Command(test_helpers.GocryptfsBinary, "-q", "-passwd", "-extpass", "echo test", - "-config", config, dir) - cmd2.Stdout = os.Stdout - cmd2.Stderr = os.Stderr - err = cmd2.Run() - if err != nil { - t.Error(err) - } -} - -// Test -ro -func TestRo(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-ro", "-extpass=echo test") - defer test_helpers.UnmountPanic(mnt) - - file := mnt + "/file" - err := os.Mkdir(file, 0777) - if err == nil { - t.Errorf("Mkdir should have failed") - } - _, err = os.Create(file) - if err == nil { - t.Errorf("Create should have failed") - } -} - -// Test "-nonempty" -func TestNonempty(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := os.Mkdir(mnt, 0700) - if err != nil { - t.Fatal(err) - } - err = ioutil.WriteFile(mnt+"/somefile", []byte("xyz"), 0600) - if err != nil { - t.Fatal(err) - } - err = test_helpers.Mount(dir, mnt, false, "-extpass=echo test") - if err == nil { - t.Errorf("Mounting over a file should fail per default") - } - // Should work with "-nonempty" - test_helpers.MountOrFatal(t, dir, mnt, "-nonempty", "-extpass=echo test") - test_helpers.UnmountPanic(mnt) -} - -// -nofail should be ignored and the mount should succeed -func TestNofail(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-nofail", "-extpass=echo test") - defer test_helpers.UnmountPanic(mnt) -} - -// Test "mountpoint shadows cipherdir" handling -func TestShadows(t *testing.T) { - mnt := test_helpers.InitFS(t) - cipher := mnt + ".cipher" - err := os.Rename(mnt, cipher) - if err != nil { - t.Fatal(err) - } - // This should work - // (note that MountOrFatal creates "mnt" again) - test_helpers.MountOrFatal(t, cipher, mnt, "-extpass=echo test") - test_helpers.UnmountPanic(mnt) - cipher2 := mnt + "/cipher" - err = os.Rename(cipher, cipher2) - if err != nil { - t.Fatal(err) - } - // This should fail - err = test_helpers.Mount(cipher2, mnt, false, "-extpass=echo test") - if err == nil { - t.Errorf("Should have failed") - } -} - -// TestMountPasswordIncorrect makes sure the correct exit code is used when the password -// was incorrect while mounting -func TestMountPasswordIncorrect(t *testing.T) { - cDir := test_helpers.InitFS(t) // Create filesystem with password "test" - pDir := cDir + ".mnt" - err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo WRONG", "-wpanic=false") - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != exitcodes.PasswordIncorrect { - t.Errorf("want=%d, got=%d", exitcodes.PasswordIncorrect, exitCode) - } -} - -// TestPasswdPasswordIncorrect makes sure the correct exit code is used when the password -// was incorrect while changing the password -func TestPasswdPasswordIncorrect(t *testing.T) { - cDir := test_helpers.InitFS(t) // Create filesystem with password "test" - // Change password - cmd := exec.Command(test_helpers.GocryptfsBinary, "-passwd", cDir) - childStdin, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Fatal(err) - } - _, err = childStdin.Write([]byte("WRONGPASSWORD\nNewPassword")) - if err != nil { - t.Fatal(err) - } - err = childStdin.Close() - if err != nil { - t.Fatal(err) - } - err = cmd.Wait() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != exitcodes.PasswordIncorrect { - t.Errorf("want=%d, got=%d", exitcodes.PasswordIncorrect, exitCode) - } -} - -// Check that we correctly background on mount and close stderr and stdout. -// Something like -// gocryptfs a b | cat -// must not hang ( https://github.com/rfjakob/gocryptfs/issues/130 ). -func TestMountBackground(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := os.Mkdir(mnt, 0700) - if err != nil { - t.Fatal(err) - } - // Manually create a pipe pair and connect the child's stdout and stderr - // to it. We cannot use StdoutPipe because that will close the pipe - // when the child forks away. - pr, pw, err := os.Pipe() - if err != nil { - t.Fatal(err) - } - args := []string{"-extpass", "echo test", dir, mnt} - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = pw - cmd.Stderr = pw - err = cmd.Run() - if err != nil { - t.Error(err) - } - pw.Close() - defer test_helpers.UnmountPanic(mnt) - // Read until we get EOF. - c1 := make(chan struct{}, 1) - go func() { - buf := make([]byte, 1000) - for { - _, err = pr.Read(buf) - // We should get io.EOF when the child closes stdout - // and stderr. - if err != nil { - pr.Close() - c1 <- struct{}{} - return - } - } - }() - select { - case <-c1: - return - case <-time.After(time.Second * 5): - t.Fatal("timeout") - } -} - -// Test that "gocryptfs -init -info CIPHERDIR" returns an error to the -// user. Only one operation flag is allowed. -func TestMultipleOperationFlags(t *testing.T) { - // Test all combinations - opFlags := []string{"-init", "-info", "-passwd", "-fsck"} - for _, flag1 := range opFlags { - var flag2 string - for _, flag2 = range opFlags { - if flag1 == flag2 { - continue - } - args := []string{flag1, flag2, "/tmp"} - //t.Logf("testing %v", args) - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - err := cmd.Run() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != exitcodes.Usage { - t.Fatalf("this should have failed with code %d, but returned %d", - exitcodes.Usage, exitCode) - } - } - } -} - -func TestNoexec(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-extpass=echo test", "-noexec") - defer test_helpers.UnmountPanic(mnt) - sh := mnt + "/x.sh" - content := `#!/bin/bash -echo hello -` - err := ioutil.WriteFile(sh, []byte(content), 0755) - if err != nil { - t.Fatal(err) - } - err = exec.Command(sh).Run() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != int(syscall.EACCES) { - t.Errorf("got exitcode %d instead of EPERM (%d)", exitCode, syscall.EPERM) - } -} - -// Test that a missing argument to "-o" triggers exit code 1. -// See also cli_args_test.go for comprehensive tests of "-o" parsing. -func TestMissingOArg(t *testing.T) { - cmd := exec.Command(test_helpers.GocryptfsBinary, "foo", "bar", "-o") - err := cmd.Run() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != exitcodes.Usage { - t.Fatalf("this should have failed with code %d, but returned %d", - exitcodes.Usage, exitCode) - } -} - -// -exclude must return an error in forward mode -func TestExcludeForward(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := test_helpers.Mount(dir, mnt, false, "-extpass", "echo test", "-exclude", "foo") - if err == nil { - t.Errorf("-exclude in forward mode should fail") - } - t.Log(err) -} - -// Check that the config file can be read from a named pipe. -// Make sure bug https://github.com/rfjakob/gocryptfs/issues/258 does not come -// back. -func TestConfigPipe(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := os.Mkdir(mnt, 0700) - if err != nil { - t.Fatal(err) - } - bashLine := fmt.Sprintf("%s -q -extpass \"echo test\" -config <(cat %s/gocryptfs.conf) %s %s", test_helpers.GocryptfsBinary, dir, dir, mnt) - cmd := exec.Command("bash", "-c", bashLine) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stdout - err = cmd.Run() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != 0 { - t.Errorf("bash command\n%q\nresulted in exit code %d", bashLine, exitCode) - return - } - test_helpers.UnmountPanic(mnt) -} - -// Ciphertext dir and mountpoint contains a comma -// https://github.com/rfjakob/gocryptfs/issues/262 -func TestComma(t *testing.T) { - dir0 := test_helpers.InitFS(t) - dir := dir0 + ",foo,bar" - err := os.Rename(dir0, dir) - if err != nil { - t.Fatal(err) - } - mnt := dir + ".mnt" - err = test_helpers.Mount(dir, mnt, false, "-extpass", "echo test", "-wpanic=0") - if err != nil { - t.Fatalf("Failed to mount %q on %q: %v", dir, mnt, err) - } - test_helpers.UnmountPanic(mnt) -} - -// Mount with idle timeout 10ms and check that the process exits by itself -// within 5 seconds. -func TestIdle(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := os.Mkdir(mnt, 0700) - if err != nil { - t.Fatal(err) - } - cmd := exec.Command(test_helpers.GocryptfsBinary, - "-q", "-nosyslog", "-fg", "-extpass", "echo test", "-i", "10ms", dir, mnt) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err = cmd.Start() - if err != nil { - t.Fatal(err) - } - timer := time.AfterFunc(5*time.Second, func() { - t.Error("timeout waiting for umount") - cmd.Process.Kill() - }) - err = cmd.Wait() - timer.Stop() - if err != nil { - t.Error(err) - } -} - -// Mount with idle timeout of 100ms read something every 10ms. The fs should -// NOT get unmounted. Regression test for https://github.com/rfjakob/gocryptfs/issues/421 -func TestNotIdle(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - err := test_helpers.Mount(dir, mnt, false, "-extpass", "echo test", "-i=100ms") - if err != nil { - t.Fatal(err) - } - err = ioutil.WriteFile(mnt+"/foo", []byte("foo"), 0600) - if err != nil { - t.Fatal(err) - } - // Read every 10 milliseconds for a total of 1 second - for i := 1; i < 100; i++ { - _, err = ioutil.ReadFile(mnt + "/foo") - if err != nil { - t.Fatalf("iteration %d failed: %v", i, err) - } - time.Sleep(10 * time.Millisecond) - } - // Keep a file handle open for 1 second - fd, err := os.Open(mnt + "/foo") - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) - buf := make([]byte, 100) - _, err = fd.Read(buf) - if err != nil { - t.Fatal(err) - } - fd.Close() - // All good. - test_helpers.UnmountPanic(mnt) -} - -// TestSymlinkedCipherdir checks that if CIPHERDIR itself is a symlink, it is -// followed. -// https://github.com/rfjakob/gocryptfs/issues/450 -func TestSymlinkedCipherdir(t *testing.T) { - dir := test_helpers.InitFS(t) - dirSymlink := dir + ".symlink" - err := os.Symlink(dir, dirSymlink) - if err != nil { - t.Fatal(err) - } - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dirSymlink, mnt, "-extpass=echo test") - defer test_helpers.UnmountPanic(mnt) - - file := mnt + "/file" - f, err := os.Create(file) - if err != nil { - t.Fatal(err) - } - f.Close() - - f, err = os.Open(mnt) - if err != nil { - t.Fatal(err) - } - defer f.Close() - names, err := f.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - if len(names) != 1 || names[0] != "file" { - t.Errorf("wrong Readdirnames result: %v", names) - } -} - -// TestBadname tests the `-badname` option -func TestBadname(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - validFileName := "file" - invalidSuffix := ".invalid_file" - - // use static suffix for testing - test_helpers.MountOrFatal(t, dir, mnt, "-badname=*", "-extpass=echo test") - defer test_helpers.UnmountPanic(mnt) - - // write one valid filename (empty content) - file := mnt + "/" + validFileName - err := ioutil.WriteFile(file, nil, 0600) - if err != nil { - t.Fatal(err) - } - - // read encrypted file name - fread, err := os.Open(dir) - if err != nil { - t.Fatal(err) - } - defer fread.Close() - - encryptedfilename := "" - ciphernames, err := fread.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - for _, ciphername := range ciphernames { - if ciphername != "gocryptfs.conf" && ciphername != "gocryptfs.diriv" { - encryptedfilename = ciphername - // found cipher name of "file" - break - } - } - - // write invalid file which should be decodable - err = ioutil.WriteFile(dir+"/"+encryptedfilename+invalidSuffix, nil, 0600) - if err != nil { - t.Fatal(err) - } - // write invalid file which is not decodable (cropping the encrpyted file name) - err = ioutil.WriteFile(dir+"/"+encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix, nil, 0600) - if err != nil { - t.Fatal(err) - } - - // check for filenames - f, err := os.Open(mnt) - if err != nil { - t.Fatal(err) - } - defer f.Close() - names, err := f.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - foundDecodable := false - foundUndecodable := false - for _, name := range names { - if strings.Contains(name, validFileName+invalidSuffix+" GOCRYPTFS_BAD_NAME") { - foundDecodable = true - } else if strings.Contains(name, encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix+" GOCRYPTFS_BAD_NAME") { - foundUndecodable = true - } - } - - if !foundDecodable { - t.Errorf("did not find invalid name %s in %v", validFileName+invalidSuffix+" GOCRYPTFS_BAD_NAME", names) - } - - if !foundUndecodable { - t.Errorf("did not find invalid name %s in %v", encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix+" GOCRYPTFS_BAD_NAME", names) - } -} - -// TestPassfile tests the `-passfile` option -func TestPassfile(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - passfile1 := mnt + ".1.txt" - ioutil.WriteFile(passfile1, []byte("test"), 0600) - test_helpers.MountOrFatal(t, dir, mnt, "-passfile="+passfile1) - defer test_helpers.UnmountPanic(mnt) -} - -// TestPassfileX2 tests that the `-passfile` option can be passed twice -func TestPassfileX2(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - passfile1 := mnt + ".1.txt" - passfile2 := mnt + ".2.txt" - ioutil.WriteFile(passfile1, []byte("te"), 0600) - ioutil.WriteFile(passfile2, []byte("st"), 0600) - test_helpers.MountOrFatal(t, dir, mnt, "-passfile="+passfile1, "-passfile="+passfile2) - defer test_helpers.UnmountPanic(mnt) -} - -// TestInitNotEmpty checks that `gocryptfs -init` returns the right error code -// if CIPHERDIR is not empty. See https://github.com/rfjakob/gocryptfs/pull/503 -func TestInitNotEmpty(t *testing.T) { - dir := test_helpers.TmpDir + "/" + t.Name() - if err := os.Mkdir(dir, 0700); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(dir+"/foo", nil, 0700); err != nil { - t.Fatal(err) - } - cmd := exec.Command(test_helpers.GocryptfsBinary, "-init", "-extpass", "echo test", dir) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() - exitCode := test_helpers.ExtractCmdExitCode(err) - if exitCode != exitcodes.CipherDir { - t.Fatalf("wrong exit code: have=%d, want=%d", exitCode, exitcodes.CipherDir) - } -} - -// TestSharedstorage checks that `-sharedstorage` hands out arbitrary inode -// numbers (no hard link tracking) -func TestSharedstorage(t *testing.T) { - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - test_helpers.MountOrFatal(t, dir, mnt, "-extpass=echo test", "-sharedstorage") - defer test_helpers.UnmountPanic(mnt) - foo1 := mnt + "/foo1" - foo2 := mnt + "/foo2" - if err := ioutil.WriteFile(foo1, nil, 0755); err != nil { - t.Fatal(err) - } - if err := os.Link(foo1, foo2); err != nil { - t.Fatal(err) - } - var st1, st2, st3 syscall.Stat_t - if err := syscall.Stat(foo1, &st1); err != nil { - t.Fatal(err) - } - // The link show show a new inode number - if err := syscall.Stat(foo2, &st2); err != nil { - t.Fatal(err) - } - // Stat()'ing again should give us again a new inode number - if err := syscall.Stat(foo2, &st3); err != nil { - t.Fatal(err) - } - if st1.Ino == st2.Ino || st2.Ino == st3.Ino || st1.Ino == st3.Ino { - t.Error(st1.Ino, st2.Ino, st3.Ino) - } - // Check that we we don't have stat caching. New length should show up - // on the hard link immediately. - if err := ioutil.WriteFile(foo1, []byte("xxxxxx"), 0755); err != nil { - t.Fatal(err) - } - if err := syscall.Stat(foo2, &st2); err != nil { - t.Fatal(err) - } - if st2.Size != 6 { - t.Fatal(st2.Size) - } -} - -// Test that the filesystem is immediately ready for Creat() after mount returns -func TestMountCreat(t *testing.T) { - const concurrency = 2 - const repeat = 2 - - dir := test_helpers.InitFS(t) - mnt := dir + ".mnt" - - for j := 0; j < repeat; j++ { - test_helpers.MountOrFatal(t, dir, mnt, "-extpass=echo test") - var wg sync.WaitGroup - wg.Add(concurrency) - for i := 0; i < concurrency; i++ { - go func(i int) { - path := fmt.Sprintf("%s/%d", mnt, i) - fd, err := syscall.Creat(path, 0600) - syscall.Close(fd) - if err != nil { - t.Errorf("Creat %q: %v", path, err) - } - wg.Done() - }(i) - } - wg.Wait() - test_helpers.UnmountPanic(mnt) - } -} diff --git a/tests/cli/gocryptfs.conf.b9e5ba23 b/tests/cli/gocryptfs.conf.b9e5ba23 deleted file mode 100644 index 9b2e61a..0000000 --- a/tests/cli/gocryptfs.conf.b9e5ba23 +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Creator": "gocryptfs v1.1-rc1-31-gc487e17-dirty", - "EncryptedKey": "vthRM/vXg3Cn16jld2JxPiRv8OSBSwTYDzOqdlrvD1agJefZhhvDQS7b5fC7B7JRL4UiVUKkNaJRVMRf", - "ScryptObject": { - "Salt": "uVwNDUMLWktmV0WgvPHztVrmoahfYN8A/22I/uq66sU=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames" - ] -} \ No newline at end of file diff --git a/tests/defaults/1980.tar.gz b/tests/defaults/1980.tar.gz deleted file mode 100644 index 1073746..0000000 Binary files a/tests/defaults/1980.tar.gz and /dev/null differ diff --git a/tests/defaults/acl_test.go b/tests/defaults/acl_test.go deleted file mode 100644 index b3826e8..0000000 --- a/tests/defaults/acl_test.go +++ /dev/null @@ -1,202 +0,0 @@ -package defaults - -import ( - "io/ioutil" - "math/rand" - "os" - "os/exec" - "path/filepath" - "syscall" - "testing" - "time" - - "golang.org/x/sys/unix" - - "github.com/pkg/xattr" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// https://github.com/rfjakob/gocryptfs/issues/543 -func TestCpA(t *testing.T) { - fn1 := filepath.Join(test_helpers.TmpDir, t.Name()) - fn2 := filepath.Join(test_helpers.DefaultPlainDir, t.Name()) - - rand.Seed(int64(time.Now().Nanosecond())) - - { - // Need unrestricted umask - old := syscall.Umask(000) - defer syscall.Umask(old) - } - - for i := 0; i < 10; i++ { - // Random permissions (except owner read, which cp needs) - var modeWant os.FileMode = os.FileMode(rand.Int31n(0777+1) | 0400) - - // Create file outside mount - err := ioutil.WriteFile(fn1, nil, modeWant) - if err != nil { - t.Fatal(err) - } - // Verify perms (umask problems?) - fi, err := os.Stat(fn1) - if err != nil { - t.Fatal(err) - } - if fi.Mode() != modeWant { - t.Errorf("ioutil.WriteFile created wrong permissions: want %o have %o", modeWant, fi.Mode()) - } - - // "cp -a" from outside to inside mount - c := exec.Command("cp", "-a", fn1, fn2) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - err = c.Run() - if err != nil { - t.Fatal(err) - } - - // Check perms - fi, err = os.Stat(fn2) - if err != nil { - t.Fatal(err) - } - if fi.Mode() != modeWant { - t.Errorf("cp -a did not preserve permissions: want %o have %o", modeWant, fi.Mode()) - } - - syscall.Unlink(fn1) - syscall.Unlink(fn2) - } -} - -func getfacl(fn string) (string, error) { - c := exec.Command("getfacl", "-c", "--", fn) - out, err := c.Output() - return string(out), err -} - -// https://github.com/rfjakob/gocryptfs/issues/543 -func TestAcl543(t *testing.T) { - fn1 := test_helpers.TmpDir + "/TestAcl543" - fn2 := test_helpers.DefaultPlainDir + "/TestAcl543" - - var c *exec.Cmd - - var modeWant os.FileMode = 0777 - - { - // Need unrestricted umask - old := syscall.Umask(000) - defer syscall.Umask(old) - } - - // Set acl on file outside gocryptfs mount - err := ioutil.WriteFile(fn1, nil, modeWant) - if err != nil { - t.Fatal(err) - } - c = exec.Command("setfacl", "-m", "u:daemon:rwx", fn1) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - err = c.Run() - if err != nil { - t.Skip(err) - } - aclWant, err := getfacl(fn1) - if err != nil { - t.Fatal(err) - } - fi, err := os.Stat(fn1) - if fi.Mode() != modeWant { - t.Fatalf("mode changed from %o to %o", modeWant, fi.Mode()) - } - - // Set acl on file inside gocryptfs mount - err = ioutil.WriteFile(fn2, nil, modeWant) - if err != nil { - t.Fatal(err) - } - c = exec.Command("setfacl", "-m", "u:daemon:rwx", fn2) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - err = c.Run() - if err != nil { - t.Fatal(err) - } - aclHave1, err := getfacl(fn1) - if err != nil { - t.Fatal(err) - } - if aclHave1 != aclWant { - t.Error(aclHave1) - } - os.Remove(fn2) - - // "cp -a" from outside to inside mount - c = exec.Command("cp", "-a", fn1, fn2) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - err = c.Run() - if err != nil { - t.Fatal(err) - } - fi, err = os.Stat(fn2) - if err != nil { - t.Fatal(err) - } - if fi.Mode() != modeWant { - t.Errorf("cp -a did not preserve permissions: want %o have %o", modeWant, fi.Mode()) - } - aclHave2, err := getfacl(fn2) - if err != nil { - t.Fatal(err) - } - if aclHave2 != aclWant { - t.Errorf("cp -a did not preserve acl: %q", aclHave1) - } -} - -// Check that we handle zero-sized and undersized buffers correctly -func TestXattrOverflow(t *testing.T) { - fn := filepath.Join(test_helpers.DefaultPlainDir, t.Name()) - ioutil.WriteFile(fn, nil, 0600) - - attr := "user.foo123" - val := []byte("12341234") - err := xattr.LSet(fn, attr, val) - if err != nil { - t.Skip(err) - } - - // Getxattr - sz, err := unix.Lgetxattr(fn, attr, nil) - if err != nil { - t.Error(err) - } - if sz != len(val) { - t.Errorf("wrong sz: want %d have %d", len(val), sz) - } - sz, err = unix.Lgetxattr(fn, attr, make([]byte, 1)) - if err != syscall.ERANGE { - t.Error(err) - } - - // Listxattr - szWant, err := unix.Llistxattr(fn, make([]byte, 64*1024)) - if err != nil { - t.Fatal(err) - } - sz, err = unix.Llistxattr(fn, nil) - if err != nil { - t.Error(err) - } - if sz != szWant { - t.Errorf("wrong sz: want %d have %d", szWant, sz) - } - sz, err = unix.Llistxattr(fn, make([]byte, 1)) - if err != syscall.ERANGE { - t.Error(err) - } -} diff --git a/tests/defaults/ctlsock_test.go b/tests/defaults/ctlsock_test.go deleted file mode 100644 index 64b72a2..0000000 --- a/tests/defaults/ctlsock_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package defaults - -import ( - "os" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/ctlsock" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestCtlSock(t *testing.T) { - cDir := test_helpers.InitFS(t) - pDir := cDir + ".mnt" - sock := cDir + ".sock" - test_helpers.MountOrFatal(t, cDir, pDir, "-ctlsock="+sock, "-extpass", "echo test") - defer test_helpers.UnmountPanic(pDir) - req := ctlsock.RequestStruct{ - EncryptPath: "foobar", - } - response := test_helpers.QueryCtlSock(t, sock, req) - if response.Result == "" || response.ErrNo != 0 { - t.Errorf("got an error reply: %+v", response) - } - req.EncryptPath = "not-existing-dir/xyz" - response = test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != int32(syscall.ENOENT) || response.Result != "" { - t.Errorf("incorrect error handling: wanted ErrNo=%d, have %+v", syscall.ENOENT, response) - } - // Strange paths should not cause a crash - crashers := []string{"/foo", "foo/", "/foo/", ".", "/////", "/../../."} - for _, c := range crashers { - req.EncryptPath = c - // QueryCtlSock calls t.Fatal if it gets EOF when gocryptfs panics - response = test_helpers.QueryCtlSock(t, sock, req) - if response.WarnText == "" { - t.Errorf("We should get a warning about non-canonical paths here") - } - } -} - -func TestCtlSockDecrypt(t *testing.T) { - cDir := test_helpers.InitFS(t) - pDir := cDir + ".mnt" - sock := cDir + ".sock" - test_helpers.MountOrFatal(t, cDir, pDir, "-ctlsock="+sock, "-extpass", "echo test") - defer test_helpers.UnmountPanic(pDir) - - paths := []string{ - "xxxxxxx123456789", - "foo/bar/baz", - test_helpers.X255, - "123/" + test_helpers.X255, - "123/" + test_helpers.X255 + "/456", - } - - for _, p := range paths { - // Create path - err := os.MkdirAll(pDir+"/"+p, 0700) - if err != nil { - t.Fatal(err) - } - // Encrypt the path through the ctlsock - req := ctlsock.RequestStruct{ - EncryptPath: p, - } - response := test_helpers.QueryCtlSock(t, sock, req) - if response.Result == "" || response.ErrNo != 0 { - t.Fatalf("got an error reply: %+v", response) - } - // Check if the encrypted path actually exists - cPath := response.Result - _, err = os.Stat(cDir + "/" + cPath) - if err != nil { - t.Fatal(err) - } - // Decrypt the path through the ctlsock and see if we get the original path - req = ctlsock.RequestStruct{ - DecryptPath: cPath, - } - response = test_helpers.QueryCtlSock(t, sock, req) - if response.Result == "" || response.ErrNo != 0 { - t.Errorf("query=%+v, response=%+v", req, response) - continue - } - if response.Result != p { - t.Errorf("want=%q got=%q", p, response.Result) - } - } -} - -func TestCtlSockDecryptCrash(t *testing.T) { - cDir := test_helpers.InitFS(t) - pDir := cDir + ".mnt" - sock := cDir + ".sock" - test_helpers.MountOrFatal(t, cDir, pDir, "-ctlsock="+sock, "-extpass", "echo test") - defer test_helpers.UnmountPanic(pDir) -} diff --git a/tests/defaults/diriv_test.go b/tests/defaults/diriv_test.go deleted file mode 100644 index bf8f233..0000000 --- a/tests/defaults/diriv_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package defaults - -import ( - "io/ioutil" - "os" - "sync" - "sync/atomic" - "syscall" - "testing" - "time" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestDirIVRace(t *testing.T) { - // Create "dir1" with one file in it - dir1 := test_helpers.DefaultPlainDir + "/TestDirIVRace_Dir1" - err := os.Mkdir(dir1, 0700) - if err != nil { - t.Fatal(err) - } - err = ioutil.WriteFile(dir1+"/file", nil, 0600) - if err != nil { - t.Fatal(err) - } - - // Create directory "dir2" - dir2 := test_helpers.DefaultPlainDir + "/TestDirIVRace_Dir2" - err = os.Mkdir(dir2, 0700) - if err != nil { - t.Fatal(err) - } - file2 := dir2 + "/file" - err = ioutil.WriteFile(file2, nil, 0600) - if err != nil { - t.Fatal(err) - } - - var stop int32 - defer func() { atomic.StoreInt32(&stop, 1) }() - - var wg sync.WaitGroup - wg.Add(1) - go func() { - wg.Done() - for { - // Keep dir2 in the diriv cache - fd, err2 := os.Open(file2) - if err2 == nil { - fd.Close() - } - if atomic.LoadInt32(&stop) != 0 { - return - } - } - }() - wg.Wait() - time.Sleep(time.Millisecond) - - // Overwrite dir2 with dir1 - err = syscall.Unlink(file2) - if err != nil { - t.Fatal(err) - } - err = syscall.Rename(dir1, dir2) - if err != nil { - t.Fatal(err) - } - // We should be able to stat file2 - _, err = os.Stat(file2) - if err != nil { - t.Error(err) - } -} diff --git a/tests/defaults/main_test.go b/tests/defaults/main_test.go deleted file mode 100644 index 8873f8f..0000000 --- a/tests/defaults/main_test.go +++ /dev/null @@ -1,372 +0,0 @@ -// Tests and benchmarks performed with default settings only. -package defaults - -import ( - "bytes" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "sync" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestMain(m *testing.M) { - test_helpers.ResetTmpDir(true) - test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "-zerokey") - r := m.Run() - test_helpers.UnmountPanic(test_helpers.DefaultPlainDir) - os.Exit(r) -} - -// Test that we get the right timestamp when extracting a tarball. -func Test1980Tar(t *testing.T) { - c := exec.Command("tar", "xzf", "1980.tar.gz", "-C", test_helpers.DefaultPlainDir) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - err := c.Run() - if err != nil { - t.Fatal(err) - } - fi, err := os.Stat(test_helpers.DefaultPlainDir + "/1980.txt") - if err != nil { - t.Fatal(err) - } - m := fi.ModTime().Unix() - if m != 315619323 { - t.Errorf("Wrong mtime: %d", m) - } -} - -// In gocryptfs before v1.2, the file header was only read once for each -// open. But truncating a file to zero will generate a new random file ID. -// The sequence below caused an I/O error to be returned. -func TestOpenTruncateRead(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/TestTruncateWrite" - // First FD is used for write and truncate. - writeFd, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } - defer writeFd.Close() - abc := []byte("abc") - _, err = writeFd.WriteAt(abc, 0) - if err != nil { - t.Fatal(err) - } - // Second FD is just for reading. - readFd, err := os.Open(fn) - if err != nil { - t.Fatal(err) - } - defer readFd.Close() - content := make([]byte, 3) - _, err = readFd.ReadAt(content, 0) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(content, abc) { - t.Fatalf("wrong content: %s", string(content)) - } - // Truncate to zero to generate a new file ID and write new content. - err = writeFd.Truncate(0) - if err != nil { - t.Fatal(err) - } - xyz := []byte("xyz") - _, err = writeFd.WriteAt(xyz, 0) - if err != nil { - t.Fatal(err) - } - // Try to read from the other FD. - _, err = readFd.ReadAt(content, 0) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(content, xyz) { - t.Fatalf("wrong content: %s", string(content)) - } -} - -// TestWORead tries to read from a write-only FD. -func TestWORead(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/TestWORead" - fd, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0600) - if err != nil { - t.Fatal(err) - } - defer fd.Close() - buf := make([]byte, 10) - _, err = fd.Read(buf) - if err == nil { - t.Error("Reading from write-only file should fail, but did not") - } -} - -// xfstests generic/124 triggers this warning: -// cipherSize 18 == header size: interrupted write? -// This test reproduces the problem. -func TestXfs124(t *testing.T) { - // GOMAXPROCS=8 and N=5000 seem to reliably trigger the problem. With N=1000, - // the test passes sometimes. - runtime.GOMAXPROCS(8) - N := 5000 - - fn := test_helpers.DefaultPlainDir + "/TestXfs124" - fd, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } - defer fd.Close() - - var wg sync.WaitGroup - wg.Add(2) - - go func() { - buf := make([]byte, 10) - var err2 error - for i := 0; i < N; i++ { - err2 = fd.Truncate(0) - if err2 != nil { - panic(err2) - } - _, err2 = fd.WriteAt(buf, 0) - if err2 != nil { - panic(err2) - } - } - wg.Done() - }() - - fd2, err := os.Open(fn) - if err != nil { - t.Fatal(err) - } - defer fd2.Close() - - go func() { - buf := make([]byte, 10) - var err3 error - for i := 0; i < N; i++ { - _, err3 = fd2.ReadAt(buf, 0) - if err3 == io.EOF { - continue - } - if err3 != nil { - panic(err3) - } - } - wg.Done() - }() - - wg.Wait() -} - -func TestWrite0200File(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/TestWrite0200File" - err := ioutil.WriteFile(fn, nil, 0200) - if err != nil { - t.Fatalf("creating empty file failed: %v", err) - } - fd, err := os.OpenFile(fn, os.O_WRONLY, 0) - if err != nil { - t.Fatal(err) - } - fi, err := fd.Stat() - if err != nil { - t.Fatal(err) - } - perms := fi.Mode().Perm() - if perms != 0200 { - t.Fatal("wrong initial permissions") - } - defer fd.Close() - _, err = fd.Write(make([]byte, 10)) - if err != nil { - t.Fatal(err) - } - perms = fi.Mode().Perm() - if perms != 0200 { - t.Fatal("wrong restored permissions") - } -} - -// TestMvWarnings: -// When xattr support was introduced, mv threw warnings like these: -// mv: preserving permissions for ‘b/x’: Operation not permitted -// because we returned EPERM when it tried to set system.posix_acl_access. -// Now we return EOPNOTSUPP and mv is happy. -func TestMvWarnings(t *testing.T) { - fn := test_helpers.TmpDir + "/TestMvWarnings" - err := ioutil.WriteFile(fn, nil, 0600) - if err != nil { - t.Fatalf("creating file failed: %v", err) - } - cmd := exec.Command("mv", fn, test_helpers.DefaultPlainDir) - out, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Fatal(err) - } - if len(out) != 0 { - t.Fatalf("Got warnings from mv:\n%s", string(out)) - } -} - -// Check for this bug in symlink handling: -// $ ln -s /asd/asdasd/asdasd b/foo -// $ mv b/foo . -// mv: listing attributes of 'b/foo': No such file or directory -// strace shows: -// llistxattr("b/foo", NULL, 0) = -1 ENOENT (No such file or directory) -func TestMvWarningSymlink(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/TestMvWarningSymlink" - err := os.Symlink("/foo/bar/baz", fn) - if err != nil { - t.Fatal(err) - } - cmd := exec.Command("mv", fn, test_helpers.TmpDir) - out, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - if runtime.GOOS == "darwin" { - t.Skip("mv on darwin chokes on broken symlinks, see https://github.com/rfjakob/gocryptfs/issues/349") - } - t.Fatal(err) - } - if len(out) != 0 { - t.Log(strings.TrimSpace(string(out))) - t.Fatal("Got warnings") - } -} - -// See TestMvWarnings. -func TestCpWarnings(t *testing.T) { - fn := test_helpers.TmpDir + "/TestCpWarnings" - err := ioutil.WriteFile(fn, []byte("foo"), 0600) - if err != nil { - t.Fatalf("creating file failed: %v", err) - } - cmd := exec.Command("cp", "-a", fn, test_helpers.DefaultPlainDir) - out, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Fatal(err) - } - if len(out) != 0 { - t.Fatalf("Got warnings from cp -a:\n%s", string(out)) - } -} - -// TestSeekData tests that fs.FileLseeker is implemented -func TestSeekData(t *testing.T) { - fn := filepath.Join(test_helpers.DefaultPlainDir, t.Name()) - f, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } - var oneTiB int64 = 1024 * 1024 * 1024 * 1024 - if _, err = f.Seek(oneTiB, 0); err != nil { - t.Fatal(err) - } - if _, err = f.Write([]byte("foo")); err != nil { - t.Fatal(err) - } - f.Close() - - const SEEK_DATA = 3 - - f, err = os.Open(fn) - if err != nil { - t.Fatal(err) - } - off, err := f.Seek(1024*1024, SEEK_DATA) - if err != nil { - t.Fatal(err) - } - if off < oneTiB-1024*1024 { - t.Errorf("off=%d, expected=%d\n", off, oneTiB) - } - f.Close() -} - -/* -TestMd5sumMaintainers tries to repro this interesting -bug that was seen during gocryptfs v2.0 development: - -$ md5sum linux-3.0/MAINTAINERS linux-3.0/MAINTAINERS linux-3.0/MAINTAINERS linux-3.0/MAINTAINERS -279b6ab0491e7532132e8f32afe6c04d linux-3.0/MAINTAINERS <-- WRONG!!!! -99cc9f0dfd86e63231b94edd43a43e02 linux-3.0/MAINTAINERS <-- correct -99cc9f0dfd86e63231b94edd43a43e02 linux-3.0/MAINTAINERS -99cc9f0dfd86e63231b94edd43a43e02 linux-3.0/MAINTAINERS - -strace shows: - -Bad ---- -fstat(3, {st_mode=S_IFREG|0644, st_size=196745, ...}) = 0 -read(3, "\n\tList of maintainers and how to"..., 32768) = 32768 -read(3, "M:\tSylwester Nawrocki \nL:\tlinux"..., 32768) = 32768 -read(3, "ach-spear3xx/\n\nSPEAR6XX MACHINE "..., 32768) = 32768 -read(3, "", 32768) = 0 -lseek(3, 0, SEEK_CUR) = 196608 -close(3) = 0 -fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0 -write(1, "279b6ab0491e7532132e8f32afe6c04d"..., 56279b6ab0491e7532132e8f32afe6c04d linux-3.0/MAINTAINERS - -Good ----- -fstat(3, {st_mode=S_IFREG|0644, st_size=195191, ...}) = 0 -read(3, "\n\tList of maintainers and how to"..., 32768) = 32768 -read(3, "M:\tSylwester Nawrocki \nL:\tlinux"..., 32768) = 32768 -read(3, "ach-spear3xx/\n\nSPEAR6XX MACHINE "..., 32768) = 31351 -read(3, "", 4096) = 0 -lseek(3, 0, SEEK_CUR) = 195191 -close(3) = 0 -fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0 -write(1, "99cc9f0dfd86e63231b94edd43a43e02"..., 5699cc9f0dfd86e63231b94edd43a43e02 linux-3.0/MAINTAINERS -*/ -func TestMd5sumMaintainers(t *testing.T) { - fn := filepath.Join(test_helpers.DefaultPlainDir, t.Name()) - f, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } - // Size of the MAINTAINERS file = 195191 - const sizeWant = 195191 - content := make([]byte, sizeWant) - _, err = f.Write(content) - if err != nil { - t.Fatal(err) - } - f.Close() - - // Remount to clear the linux kernel attr cache - // (otherwise we would have to wait 2 seconds for the entry to expire) - test_helpers.UnmountPanic(test_helpers.DefaultPlainDir) - test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "-zerokey") - - cmd := exec.Command("md5sum", fn, fn, fn, fn) - out2, err := cmd.CombinedOutput() - out := string(out2) - - // 195191 zero bytes have this md5sum - const md5Want = "b99bf6917f688068acd49126f3b1b005" - - n := strings.Count(out, md5Want) - if n != 4 { - t.Errorf("found %d instead of %d instances of %q", n, 4, md5Want) - t.Logf("full output:\n%s", out) - } -} diff --git a/tests/defaults/performance_test.go b/tests/defaults/performance_test.go deleted file mode 100644 index a2ecf8c..0000000 --- a/tests/defaults/performance_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Tests and benchmarks performed with default settings only. -package defaults - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// Benchmarks -func BenchmarkStreamWrite(t *testing.B) { - buf := make([]byte, 1024*1024) - t.SetBytes(int64(len(buf))) - - file, err := os.Create(test_helpers.DefaultPlainDir + "/BenchmarkWrite") - if err != nil { - t.Fatal(err) - } - - t.ResetTimer() - var i int - for i = 0; i < t.N; i++ { - written, err := file.Write(buf) - if err != nil { - fmt.Printf("err=\"%s\", written=%d\n", err.Error(), written) - t.Fatal(err) - } - } - file.Close() -} - -func BenchmarkStreamRead(t *testing.B) { - buf := make([]byte, 1024*1024) - t.SetBytes(int64(len(buf))) - - fn := test_helpers.DefaultPlainDir + "/BenchmarkWrite" - fi, err := os.Stat(fn) - if err != nil { - t.Fatal(err) - } - mb := int(fi.Size() / 1024 / 1024) - - if t.N > mb { - // Grow file so we can satisfy the test - //fmt.Printf("Growing file to %d MB... ", t.N) - var f2 *os.File - f2, err = os.OpenFile(fn, os.O_WRONLY|os.O_APPEND, 0666) - if err != nil { - fmt.Println(err) - t.FailNow() - } - for h := 0; h < t.N-mb; h++ { - _, err = f2.Write(buf) - if err != nil { - fmt.Println(err) - t.FailNow() - } - } - f2.Close() - } - - file, err := os.Open(fn) - if err != nil { - t.FailNow() - } - t.ResetTimer() - var i int - for i = 0; i < t.N; i++ { - _, err := file.Read(buf) - if err == io.EOF { - fmt.Println("Test file too small") - t.SkipNow() - } else if err != nil { - fmt.Println(err) - t.FailNow() - } - } - file.Close() -} - -// createFiles - create "count" files of size "size" bytes each -func createFiles(t *testing.B, count int, size int) { - dir := fmt.Sprintf("%s/createFiles_%d_%d", test_helpers.DefaultPlainDir, count, size) - err := os.Mkdir(dir, 0777) - if err != nil { - t.Fatal(err) - } - buf := make([]byte, size) - t.SetBytes(int64(len(buf))) - t.ResetTimer() - var i int - for i = 0; i < count; i++ { - file := fmt.Sprintf("%s/%d", dir, i) - if size > 0 { - err = ioutil.WriteFile(file, buf, 0666) - } else { - var fh *os.File - fh, err = os.Create(file) - fh.Close() - } - if err != nil { - t.Fatal(err) - } - } - t.StopTimer() - os.RemoveAll(dir) -} - -func BenchmarkCreate0B(t *testing.B) { - createFiles(t, t.N, 0) -} - -func BenchmarkCreate1B(t *testing.B) { - createFiles(t, t.N, 1) -} - -func BenchmarkCreate100B(t *testing.B) { - createFiles(t, t.N, 100) -} - -func BenchmarkCreate4kB(t *testing.B) { - createFiles(t, t.N, 4*1024) -} - -func BenchmarkCreate10kB(t *testing.B) { - createFiles(t, t.N, 10*1024) -} diff --git a/tests/dl-linux-tarball.bash b/tests/dl-linux-tarball.bash deleted file mode 100755 index fa27e37..0000000 --- a/tests/dl-linux-tarball.bash +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -eu -# -# This script checks the size of /tmp/linux-3.0.tar.gz and downloads -# a fresh copy if the size is incorrect or the file is missing. - -URL=https://cdn.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.gz -TGZ=/tmp/linux-3.0.tar.gz - -SIZE_WANT=96675825 -SIZE_ACTUAL=0 -if [[ -e $TGZ ]]; then - if [[ $OSTYPE == linux* ]] ; then - SIZE_ACTUAL=$(stat -c %s $TGZ) - else - # Mac OS X - SIZE_ACTUAL=$(stat -f %z $TGZ) - fi -fi - -if [[ $SIZE_ACTUAL -ne $SIZE_WANT ]]; then - echo "Downloading linux-3.0.tar.gz" - if command -v wget > /dev/null ; then - wget -nv --show-progress -c -O $TGZ $URL - else - curl -o $TGZ $URL - fi -fi diff --git a/tests/example_filesystems/content/abs b/tests/example_filesystems/content/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/content/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/content/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/example_filesystems/content/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/content/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/content/rel b/tests/example_filesystems/content/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/content/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/content/status.txt b/tests/example_filesystems/content/status.txt deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/content/status.txt +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/example_filesystems_test.go b/tests/example_filesystems/example_filesystems_test.go deleted file mode 100644 index 36fb554..0000000 --- a/tests/example_filesystems/example_filesystems_test.go +++ /dev/null @@ -1,384 +0,0 @@ -package example_filesystems - -// Mount example filesystems, check that the example content (normal file, symlinks) -// is there and test mkdir and rmdir -// -// Runs all the tests twice, once with "-openssl=false" and once with -// "-openssl=true". - -import ( - "flag" - "fmt" - "os" - "os/exec" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var opensslOpt string - -// tmpFsPath contains a private writeable copy of the example_filesystems -// folder. -var tmpFsPath string - -func TestMain(m *testing.M) { - // Make "testing.Verbose()" return the correct value - flag.Parse() - variants := []string{"-openssl=false"} - if !stupidgcm.BuiltWithoutOpenssl { - variants = append(variants, "-openssl=true") - } else { - fmt.Println("Skipping OpenSSL tests, I have been compiled without openssl support") - } - for _, opensslOpt = range variants { - if testing.Verbose() { - fmt.Printf("example_filesystems: testing with %q\n", opensslOpt) - } - test_helpers.ResetTmpDir(false) - - // Create a private copy of the example filesystems that we can - // mess with - cmd := exec.Command("cp", "-a", "../example_filesystems", test_helpers.TmpDir) - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - err := cmd.Run() - if err != nil { - fmt.Printf("cp -a failed: %v\n", err) - os.Exit(1) - } - tmpFsPath = test_helpers.TmpDir + "/example_filesystems/" - - r := m.Run() - if r != 0 { - os.Exit(r) - } - } - os.Exit(0) -} - -// This filesystem is not supported anymore. -func TestExampleFSv04(t *testing.T) { - cDir := "v0.4" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt) - if err == nil { - t.Errorf("Mounting too old FS should fail") - } -} - -// This filesystem is not supported anymore. -func TestExampleFSv05(t *testing.T) { - cDir := "v0.5" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt) - if err == nil { - t.Errorf("Mounting too old FS should fail") - } -} - -// This filesystem is not supported anymore. -func TestExampleFSv06(t *testing.T) { - cDir := "v0.6" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt) - if err == nil { - t.Errorf("Mounting too old FS should fail") - } -} - -// This filesystem is not supported anymore. -func TestExampleFSv06PlaintextNames(t *testing.T) { - cDir := "v0.6-plaintextnames" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo test", opensslOpt) - if err == nil { - t.Errorf("Mounting too old FS should fail") - } -} - -// Test example_filesystems/v0.7 -// with password mount and -masterkey mount -// v0.7 adds 128 bit GCM IVs -func TestExampleFSv07(t *testing.T) { - cDir := "v0.7" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := os.Mkdir(pDir, 0777) - if err != nil { - t.Fatal(err) - } - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt) - checkExampleFS(t, pDir, true) - test_helpers.UnmountPanic(pDir) - test_helpers.MountOrFatal(t, cDir, pDir, "-masterkey", - "ed7f6d83-40cce86c-0e7d79c2-a9438710-575221bf-30a0eb60-2821fa8f-7f3123bf", - "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFS(t, pDir, true) - test_helpers.UnmountPanic(pDir) -} - -// gocryptfs v0.7 filesystem created with "-plaintextnames" -func TestExampleFSv07PlaintextNames(t *testing.T) { - cDir := "v0.7-plaintextnames" - pDir := test_helpers.TmpDir + "/" + cDir + ".mnt" - cDir = tmpFsPath + cDir - - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt) - checkExampleFS(t, pDir, true) - test_helpers.UnmountPanic(pDir) - // The actual unmount takes some time, this causes weird problems. Just don't - // reuse the mountpoint. - pDir = pDir + ".2" - test_helpers.MountOrFatal(t, cDir, pDir, "-plaintextnames", "-masterkey", - "6d96397b-585631e1-c7cba69d-61e738b6-4d5ad2c2-e21f0fb3-52f60d3a-b08526f7", - "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFS(t, pDir, true) - test_helpers.UnmountPanic(pDir) -} - -// Test example_filesystems/v0.9 -// (gocryptfs v0.9 introduced long file name support) -func TestExampleFSv09(t *testing.T) { - cDir := "v0.9" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := os.Mkdir(pDir, 0777) - if err != nil { - t.Fatal(err) - } - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) - pDir = pDir + ".2" - test_helpers.MountOrFatal(t, cDir, pDir, "-masterkey", - "1cafe3f4-bc316466-2214c47c-ecd89bf3-4e078fe4-f5faeea7-8b7cab02-884f5e1c", - "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) -} - -// gocryptfs v1.1 introduced AES-SIV -func TestExampleFSv11(t *testing.T) { - cDir := "v1.1-aessiv" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := os.Mkdir(pDir, 0777) - if err != nil { - t.Fatal(err) - } - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) - pDir = pDir + ".2" - test_helpers.MountOrFatal(t, cDir, pDir, "-masterkey", - "eaf371c3-f9a55336-8819f22b-7bccd7c2-a738cf61-7261c658-14c28a03-9428992b", - "-aessiv", "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) -} - -// gocryptfs v1.1 introduced reverse mode -func TestExampleFSv11reverse(t *testing.T) { - dirA := "v1.1-reverse" - dirB := test_helpers.TmpDir + "/" + dirA + ".B" - err := os.Mkdir(dirB, 0700) - if err != nil { - t.Fatal(err) - } - dirC := test_helpers.TmpDir + "/" + dirA + ".C" - err = os.Mkdir(dirC, 0700) - if err != nil { - t.Fatal(err) - } - dirA = tmpFsPath + dirA - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-extpass", "echo test", opensslOpt) - c := dirB + "/gocryptfs.conf" - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-extpass", "echo test", opensslOpt) - checkExampleFSrw(t, dirC, false) - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) - - m := "68b51855-042abd80-635ae1ba-90152a78-2ec2d243-832ac72a-eab0561a-f2d37913" - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-masterkey", m, - "-raw64=false", "-hkdf=false", opensslOpt) - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-aessiv", "-masterkey", m, - "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFSrw(t, dirC, false) - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) -} - -// gocryptfs v1.1 introduced reverse mode -func TestExampleFSv11reversePlaintextnames(t *testing.T) { - dirA := "v1.1-reverse-plaintextnames" - dirB := test_helpers.TmpDir + "/" + dirA + ".B" - err := os.Mkdir(dirB, 0700) - if err != nil { - t.Fatal(err) - } - dirC := test_helpers.TmpDir + "/" + dirA + ".C" - err = os.Mkdir(dirC, 0700) - if err != nil { - t.Fatal(err) - } - dirA = tmpFsPath + dirA - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-extpass", "echo test", opensslOpt) - c := dirB + "/gocryptfs.conf" - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-extpass", "echo test", opensslOpt) - checkExampleFSrw(t, dirC, false) - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) - - m := "e7fb8f0d-2a81df9e-26611e4b-5540b218-e48aa458-c2a623af-d0c82637-1466b5f2" - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-masterkey", m, - "-raw64=false", "-hkdf=false", opensslOpt) - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-aessiv", "-masterkey", m, - "-raw64=false", "-hkdf=false", opensslOpt) - checkExampleFSrw(t, dirC, false) - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) -} - -// gocryptfs v1.3 introduced HKDF -func TestExampleFSv13(t *testing.T) { - cDir := "v1.3" - pDir := test_helpers.TmpDir + "/" + cDir - cDir = tmpFsPath + cDir - err := os.Mkdir(pDir, 0777) - if err != nil { - t.Fatal(err) - } - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) - - pDir = pDir + "_m" - test_helpers.MountOrFatal(t, cDir, pDir, "-masterkey", - "fd890dab-86bf61cf-ec5ad460-ad3ed01f-9c52d546-2a31783d-a56b088d-3d05232e", - opensslOpt) - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) -} - -// Check that the masterkey=stdin cli option works. -func TestExampleFSv13MasterkeyStdin(t *testing.T) { - cDir := "v1.3" - pDir := test_helpers.TmpDir + "/TestExampleFSv13MasterkeyStdin.mnt" - cDir = tmpFsPath + cDir - err := os.Mkdir(pDir, 0777) - if err != nil { - t.Fatal(err) - } - args := []string{"-q", "-masterkey=stdin", opensslOpt, cDir, pDir} - cmd := exec.Command(test_helpers.GocryptfsBinary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - p, err := cmd.StdinPipe() - if err != nil { - t.Fatal(err) - } - err = cmd.Start() - if err != nil { - t.Error(err) - } - // Write masterkey to stdin - p.Write([]byte("fd890dab-86bf61cf-ec5ad460-ad3ed01f-9c52d546-2a31783d-a56b088d-3d05232e")) - p.Close() - err = cmd.Wait() - if err != nil { - t.Error(err) - } - // Check that the fs decrypts ok & unmount - checkExampleFSLongnames(t, pDir) - test_helpers.UnmountPanic(pDir) -} - -// gocryptfs v1.3 introduced HKDF. -// We check the md5 sum of the encrypted version of a file to make sure we don't -// accidentally change the ciphertext generation. -// Create a full crypto round-trip by mounting two times: -// dirA -> reverse mount -> dirB -> forward mount -> dirC -func TestExampleFSv13reverse(t *testing.T) { - var R_OK uint32 = 4 - // Prepare directories - dirA := "v1.3-reverse" - dirB := test_helpers.TmpDir + "/" + dirA + ".B" - err := os.Mkdir(dirB, 0700) - if err != nil { - t.Fatal(err) - } - dirC := test_helpers.TmpDir + "/" + dirA + ".C" - err = os.Mkdir(dirC, 0700) - if err != nil { - t.Fatal(err) - } - dirA = tmpFsPath + dirA - // Mount using password - // We pass "-wpanic=false" because the '..' and '.' tests deliverately trigger warnings - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-extpass", "echo test", "-wpanic=false", opensslOpt) - c := dirB + "/gocryptfs.conf" - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-extpass", "echo test", opensslOpt) - // Test - checkExampleFSrw(t, dirC, false) - // Access to encrypted version of '..' should fail - cPath := dirB + "/D8VwRPqWW8x7M5OEoMs0Eg" - err = syscall.Access(cPath, R_OK) - if err != syscall.ENOENT { - t.Errorf("want ENOENT, got: %v", err) - } - // Access to encrypted version of '.' should fail - cPath = dirB + "/kkmARPseVj4XQFW-EL42-w" - err = syscall.Access(cPath, R_OK) - if err != syscall.ENOENT { - t.Errorf("want ENOENT, got: %v", err) - } - // Encrypted version of dir1/dir2/file (10000 zero bytes) - cPath = dirB + "/zOsW1-BUX54hC2hmhu2EOw/4ZqrpGQdw5r07KR1qw2ZeQ/tfCm9Sp9J_Dvc-jD7J6p8g" - want := "9818501d214c5eb42ca2472caf6c82a1" - actual := test_helpers.Md5fn(cPath) - if actual != want { - t.Errorf("wrong md5") - } - // Unmount - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) - - // Mount using masterkey - m := "2290a7f4-3e1908fb-b006f7d9-261bdaf1-4b72bc38-3b24956c-db7d8a8d-d996076a" - test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-masterkey", m, opensslOpt) - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - test_helpers.MountOrFatal(t, dirB, dirC, "-aessiv", "-masterkey", m, opensslOpt) - // Test - checkExampleFSrw(t, dirC, false) - actual = test_helpers.Md5fn(cPath) - if actual != want { - t.Errorf("wrong md5") - } - // Unmmount - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) -} diff --git a/tests/example_filesystems/example_test_helpers.go b/tests/example_filesystems/example_test_helpers.go deleted file mode 100644 index e39f8d6..0000000 --- a/tests/example_filesystems/example_test_helpers.go +++ /dev/null @@ -1,80 +0,0 @@ -package example_filesystems - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -const statusTxtContent = "It works!\n" - -// checkExampleFS - verify that "dir" contains the expected test files -func checkExampleFS(t *testing.T, dir string, rw bool) { - // Read regular file - statusFile := filepath.Join(dir, "status.txt") - contentBytes, err := ioutil.ReadFile(statusFile) - if err != nil { - t.Error(err) - return - } - content := string(contentBytes) - if content != statusTxtContent { - t.Errorf("Unexpected content: %s\n", content) - } - // Read relative symlink - symlink := filepath.Join(dir, "rel") - target, err := os.Readlink(symlink) - if err != nil { - t.Error(err) - return - } - if target != "status.txt" { - t.Errorf("Unexpected link target: %s\n", target) - } - // Read absolute symlink - symlink = filepath.Join(dir, "abs") - target, err = os.Readlink(symlink) - if err != nil { - t.Error(err) - return - } - if target != "/a/b/c/d" { - t.Errorf("Unexpected link target: %s\n", target) - } - if rw { - // Test directory operations - test_helpers.TestRename(t, dir) - test_helpers.TestMkdirRmdir(t, dir) - } -} - -// checkExampleFSLongnames - verify that "dir" contains the expected test files -// plus the long file name test file. -// Also tests simple directory operations. -func checkExampleFSLongnames(t *testing.T, dir string) { - checkExampleFSrw(t, dir, true) -} - -// checkExampleFSrw is like checkExampleFSLongnames but gives the caller the -// choice if he wants to run tests that write to the FS. -func checkExampleFSrw(t *testing.T, dir string, rw bool) { - // regular tests - checkExampleFS(t, dir, rw) - // long name test file - longname := "longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + - "xxxxxxxxxxxxxxxxxxxxxxxx" - contentBytes, err := ioutil.ReadFile(filepath.Join(dir, longname)) - if err != nil { - t.Error(err) - return - } - content := string(contentBytes) - if content != statusTxtContent { - t.Errorf("longname_255: unexpected content: %s\n", content) - } -} diff --git a/tests/example_filesystems/v0.4/3-HZSwv99agoWgTErV0YFQ== b/tests/example_filesystems/v0.4/3-HZSwv99agoWgTErV0YFQ== deleted file mode 100644 index 5d0af82..0000000 Binary files a/tests/example_filesystems/v0.4/3-HZSwv99agoWgTErV0YFQ== and /dev/null differ diff --git a/tests/example_filesystems/v0.4/6hL2fPVB2aMSh4-UoDn5Kw== b/tests/example_filesystems/v0.4/6hL2fPVB2aMSh4-UoDn5Kw== deleted file mode 120000 index 31b9013..0000000 --- a/tests/example_filesystems/v0.4/6hL2fPVB2aMSh4-UoDn5Kw== +++ /dev/null @@ -1 +0,0 @@ -3-HZSwv99agoWgTErV0YFQ== \ No newline at end of file diff --git a/tests/example_filesystems/v0.4/TBIgdfhDKwkXVTnWLVzFSg== b/tests/example_filesystems/v0.4/TBIgdfhDKwkXVTnWLVzFSg== deleted file mode 120000 index 7a15694..0000000 --- a/tests/example_filesystems/v0.4/TBIgdfhDKwkXVTnWLVzFSg== +++ /dev/null @@ -1 +0,0 @@ -/tTXhw8tmmz4PK9YG21Whug==/Qe8z0HUArb5bZJjUqEo2Nw==/wv68UB9DLF9OfAcxgRKKtQ==/9No5n3deBUGa-BsvPRi3DQ== \ No newline at end of file diff --git a/tests/example_filesystems/v0.4/gocryptfs.conf b/tests/example_filesystems/v0.4/gocryptfs.conf deleted file mode 100644 index 354b4bb..0000000 --- a/tests/example_filesystems/v0.4/gocryptfs.conf +++ /dev/null @@ -1,12 +0,0 @@ -{ - "EncryptedKey": "He757VFOKOWbMJqJ7HBs67SMSi3Vu8/2vgWNI6j1tVo4JBlNvrQSw6KkCh0lGrHrh6ICbPv4MyoyFdGa", - "ScryptObject": { - "Salt": "MeHSsxsnJwngAwptNzuXQlj7JtF1b0uzZuWvVV3cH3w=", - "N": 65536, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": null -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.5/AOtl_i4xQWDyG0_zUqntOw== b/tests/example_filesystems/v0.5/AOtl_i4xQWDyG0_zUqntOw== deleted file mode 120000 index 7c52a28..0000000 --- a/tests/example_filesystems/v0.5/AOtl_i4xQWDyG0_zUqntOw== +++ /dev/null @@ -1 +0,0 @@ -LFInXW9Djd1p8VfnwbhBaQy7MowhfNUDhsPPXXEiAfrfaVar6Ec= \ No newline at end of file diff --git a/tests/example_filesystems/v0.5/Pf35wlWlf43N68EbhIgTcQ== b/tests/example_filesystems/v0.5/Pf35wlWlf43N68EbhIgTcQ== deleted file mode 120000 index 596cc3d..0000000 --- a/tests/example_filesystems/v0.5/Pf35wlWlf43N68EbhIgTcQ== +++ /dev/null @@ -1 +0,0 @@ -OrWiZIVoBo4qbbJdsPy1MCwlvGTE4t_ackP4lbcLdKiTA-Zf \ No newline at end of file diff --git a/tests/example_filesystems/v0.5/gocryptfs.conf b/tests/example_filesystems/v0.5/gocryptfs.conf deleted file mode 100644 index f839664..0000000 --- a/tests/example_filesystems/v0.5/gocryptfs.conf +++ /dev/null @@ -1,14 +0,0 @@ -{ - "EncryptedKey": "zIY8foMncKrAG8USA1/AQ+R8z+xRge3QZqDpGRIDAeNOkMeQQsnMsJzFJbZHcGlRbUye0CwRghR/UX4R", - "ScryptObject": { - "Salt": "BFQklFzt3j9ZDa8zcR9pwHfa8nDdLqyCzNp5kA+V6Y0=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "DirIV" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.5/gocryptfs.diriv b/tests/example_filesystems/v0.5/gocryptfs.diriv deleted file mode 100644 index 3670294..0000000 --- a/tests/example_filesystems/v0.5/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -é×Vë¹LÅ×lû×g‘k# \ No newline at end of file diff --git a/tests/example_filesystems/v0.5/j2BpGUT5kOtia20PWQ2rEA== b/tests/example_filesystems/v0.5/j2BpGUT5kOtia20PWQ2rEA== deleted file mode 100644 index 1ad2358..0000000 Binary files a/tests/example_filesystems/v0.5/j2BpGUT5kOtia20PWQ2rEA== and /dev/null differ diff --git a/tests/example_filesystems/v0.6-plaintextnames/abs b/tests/example_filesystems/v0.6-plaintextnames/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/v0.6-plaintextnames/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/v0.6-plaintextnames/gocryptfs.conf b/tests/example_filesystems/v0.6-plaintextnames/gocryptfs.conf deleted file mode 100644 index 257b7ee..0000000 --- a/tests/example_filesystems/v0.6-plaintextnames/gocryptfs.conf +++ /dev/null @@ -1,14 +0,0 @@ -{ - "EncryptedKey": "SoTMt+DMqVDia42c7cx8YW6KrnzF9EQVYIq5DGR1yFqNKxtOCBIuXEIKJHYSw1Z8VluKRQmkugTOvyTU", - "ScryptObject": { - "Salt": "83wR2p5eDPtozsP48vizN1rAbYeXOtksvwoAZ9Y0vn4=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "PlaintextNames" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.6-plaintextnames/rel b/tests/example_filesystems/v0.6-plaintextnames/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/v0.6-plaintextnames/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/v0.6-plaintextnames/status.txt b/tests/example_filesystems/v0.6-plaintextnames/status.txt deleted file mode 100644 index e5b62fb..0000000 Binary files a/tests/example_filesystems/v0.6-plaintextnames/status.txt and /dev/null differ diff --git a/tests/example_filesystems/v0.6/9pOs0yjJI5A67pv5CnqomQ== b/tests/example_filesystems/v0.6/9pOs0yjJI5A67pv5CnqomQ== deleted file mode 120000 index 11b0234..0000000 --- a/tests/example_filesystems/v0.6/9pOs0yjJI5A67pv5CnqomQ== +++ /dev/null @@ -1 +0,0 @@ -OoEsnmmWQzBSl3E471yZkI2t2vB4SteL_l1J60HYXZ7g0W3CkTM= \ No newline at end of file diff --git a/tests/example_filesystems/v0.6/G79Zdu41H3bgwdaQlrz-dg== b/tests/example_filesystems/v0.6/G79Zdu41H3bgwdaQlrz-dg== deleted file mode 120000 index b72a393..0000000 --- a/tests/example_filesystems/v0.6/G79Zdu41H3bgwdaQlrz-dg== +++ /dev/null @@ -1 +0,0 @@ -4IGGj21t4IYWI76F46v3gG-JwTcw_QxGDFMSk_19bJav2WNw \ No newline at end of file diff --git a/tests/example_filesystems/v0.6/RuYvQG_raW_-H_LcyJC4LQ== b/tests/example_filesystems/v0.6/RuYvQG_raW_-H_LcyJC4LQ== deleted file mode 100644 index 5821d87..0000000 Binary files a/tests/example_filesystems/v0.6/RuYvQG_raW_-H_LcyJC4LQ== and /dev/null differ diff --git a/tests/example_filesystems/v0.6/gocryptfs.conf b/tests/example_filesystems/v0.6/gocryptfs.conf deleted file mode 100644 index 1c72781..0000000 --- a/tests/example_filesystems/v0.6/gocryptfs.conf +++ /dev/null @@ -1,15 +0,0 @@ -{ - "EncryptedKey": "/PhLwDblkFRGfoIA0egXikG0ZSZTWrOOoFZJPPX0R8JgU5+XnT2M2rxUzHIKKeuGoqZN55phgJjhTu0J", - "ScryptObject": { - "Salt": "YSHRXpcWYp95npMxAy9cf27LoaPR3gvrFpk3Xhg2tM8=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "DirIV", - "EMENames" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.6/gocryptfs.diriv b/tests/example_filesystems/v0.6/gocryptfs.diriv deleted file mode 100644 index ec9f503..0000000 --- a/tests/example_filesystems/v0.6/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -éœ(ûò'<˜7§Q‹ \ No newline at end of file diff --git a/tests/example_filesystems/v0.7-plaintextnames/abs b/tests/example_filesystems/v0.7-plaintextnames/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/v0.7-plaintextnames/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/v0.7-plaintextnames/gocryptfs.conf b/tests/example_filesystems/v0.7-plaintextnames/gocryptfs.conf deleted file mode 100644 index 9b462a3..0000000 --- a/tests/example_filesystems/v0.7-plaintextnames/gocryptfs.conf +++ /dev/null @@ -1,15 +0,0 @@ -{ - "EncryptedKey": "13f9NLdlS20w26T0bukhVrqhumJOHhRyntEJb2y2BJK+K1kulklQGT6gxSWPsjDqw5514h9/euMiKMwc", - "ScryptObject": { - "Salt": "b2ZD+7sN6b/lchJbYT+4K73tscC6WwbGrdxHuFjhOT4=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "PlaintextNames" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.7-plaintextnames/rel b/tests/example_filesystems/v0.7-plaintextnames/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/v0.7-plaintextnames/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/v0.7-plaintextnames/status.txt b/tests/example_filesystems/v0.7-plaintextnames/status.txt deleted file mode 100644 index 86ae6dc..0000000 Binary files a/tests/example_filesystems/v0.7-plaintextnames/status.txt and /dev/null differ diff --git a/tests/example_filesystems/v0.7/4tRF1LdULRFLiXwfze671Q== b/tests/example_filesystems/v0.7/4tRF1LdULRFLiXwfze671Q== deleted file mode 120000 index f06d136..0000000 --- a/tests/example_filesystems/v0.7/4tRF1LdULRFLiXwfze671Q== +++ /dev/null @@ -1 +0,0 @@ -_IdSjAmPQOJW6QkskuyQJS9bFTjntqx9kdg4Z3y8EzKBnIb_Ihqz4w== \ No newline at end of file diff --git a/tests/example_filesystems/v0.7/RWPXmXkRFrWw1aOpq7C-NQ== b/tests/example_filesystems/v0.7/RWPXmXkRFrWw1aOpq7C-NQ== deleted file mode 100644 index 6ddcd1e..0000000 Binary files a/tests/example_filesystems/v0.7/RWPXmXkRFrWw1aOpq7C-NQ== and /dev/null differ diff --git a/tests/example_filesystems/v0.7/dwPcZNei4HN4qPA6FxoG_A== b/tests/example_filesystems/v0.7/dwPcZNei4HN4qPA6FxoG_A== deleted file mode 120000 index c0c731f..0000000 --- a/tests/example_filesystems/v0.7/dwPcZNei4HN4qPA6FxoG_A== +++ /dev/null @@ -1 +0,0 @@ -Ygqk_pYyxE_ac_ufVgxKCPxWHMGqQ8xUohIaHcmgeLU4uQB3_UmicPKB \ No newline at end of file diff --git a/tests/example_filesystems/v0.7/gocryptfs.conf b/tests/example_filesystems/v0.7/gocryptfs.conf deleted file mode 100644 index 80c2673..0000000 --- a/tests/example_filesystems/v0.7/gocryptfs.conf +++ /dev/null @@ -1,16 +0,0 @@ -{ - "EncryptedKey": "0crm+qEf00XPxQrc8NIMp/0rgfaLb8wzTj+3G1slSytjsLHctj/fOKkGJIFyBk7xzvnWdkhyxxvHgfMS", - "ScryptObject": { - "Salt": "yZn+QMjR2ENZ6MoiURpqEqr8mgnCX8WN87KJafgiXhU=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.7/gocryptfs.diriv b/tests/example_filesystems/v0.7/gocryptfs.diriv deleted file mode 100644 index 3adef3c..0000000 --- a/tests/example_filesystems/v0.7/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -ßiȤ·\?…Œ=ÑÎMc \ No newline at end of file diff --git a/tests/example_filesystems/v0.9/00msNUi5h5aKMX_f-4pBhA== b/tests/example_filesystems/v0.9/00msNUi5h5aKMX_f-4pBhA== deleted file mode 120000 index c717734..0000000 --- a/tests/example_filesystems/v0.9/00msNUi5h5aKMX_f-4pBhA== +++ /dev/null @@ -1 +0,0 @@ -5nI119EbCRtgT8AwTDPmxCuORvbGV4xdtmqnur7KK9ufir-ALyneV7Iy \ No newline at end of file diff --git a/tests/example_filesystems/v0.9/R83PhW-BBA_q4rPYD7dEMg== b/tests/example_filesystems/v0.9/R83PhW-BBA_q4rPYD7dEMg== deleted file mode 100644 index 1bc4a81..0000000 Binary files a/tests/example_filesystems/v0.9/R83PhW-BBA_q4rPYD7dEMg== and /dev/null differ diff --git a/tests/example_filesystems/v0.9/gocryptfs.conf b/tests/example_filesystems/v0.9/gocryptfs.conf deleted file mode 100644 index 4d9b089..0000000 --- a/tests/example_filesystems/v0.9/gocryptfs.conf +++ /dev/null @@ -1,17 +0,0 @@ -{ - "EncryptedKey": "sAB/dsiDbFBbMr7ppsB3Fu81hVr6BBxlcfY1wZYRHlRvRV2uwRdYAACNM39CDxLBHZuNjk9UyWh87McP", - "ScryptObject": { - "Salt": "3mphl9Hmhzd6exmc8Um0jOOCgR8hAYvbzbEpTnIEMPg=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v0.9/gocryptfs.diriv b/tests/example_filesystems/v0.9/gocryptfs.diriv deleted file mode 100644 index 47d97ee..0000000 --- a/tests/example_filesystems/v0.9/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -ÿ~HÕæá‡A|ÔÈã­ \ No newline at end of file diff --git a/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ= b/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ= deleted file mode 100644 index 78eb3ff..0000000 Binary files a/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ= and /dev/null differ diff --git a/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ=.name b/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ=.name deleted file mode 100644 index 535cee7..0000000 --- a/tests/example_filesystems/v0.9/gocryptfs.longname.y4J-w3LBX165Mn_pGdDRY7Gb6EgHcTrdWjME3WGu-CQ=.name +++ /dev/null @@ -1 +0,0 @@ -Py7wkyXYf1YXvFvHuizOqva6WWWYEQ-JYv1rOAvWWaARLyGdQdxuW-iBf1Vwd8orZjqkcIGgnxOfuRsarXKmn4-3L2MRIZKPhhx2QRqpPRtFylEABH1KwZ_2ZZnx5cpcO8TIoeVdL6NXnRw-WrT06zTUzVRioNPRLPa0J6c8_eb5QFb4EG5wPpn-XlJSedjAw31MUNvFxKYQku_UwJF0CvvXLCozVnNM_dDNWsgBevzB8VBySbfW7XgYMRPJRlJe3Pjeues9tyGJvAxGJVjfo4nZyWusMF2G4f9w06m3Bxjc7ladgJR6F6pyI4Z65DCIL7G6G2y__agmNcKtFwCS_Q== \ No newline at end of file diff --git a/tests/example_filesystems/v0.9/hwE1RKIXtF8hmQMvEXSTtg== b/tests/example_filesystems/v0.9/hwE1RKIXtF8hmQMvEXSTtg== deleted file mode 120000 index 4190a7e..0000000 --- a/tests/example_filesystems/v0.9/hwE1RKIXtF8hmQMvEXSTtg== +++ /dev/null @@ -1 +0,0 @@ -XRx7Nqxt_zuPNo7h8_j1LLVzqzIZg9qAYGRN9Iuq3XBc11Y7_RoQsg== \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-aessiv/MA0FDdmnXpmPJtS_AcAbqQ== b/tests/example_filesystems/v1.1-aessiv/MA0FDdmnXpmPJtS_AcAbqQ== deleted file mode 100644 index 6767b2a..0000000 Binary files a/tests/example_filesystems/v1.1-aessiv/MA0FDdmnXpmPJtS_AcAbqQ== and /dev/null differ diff --git a/tests/example_filesystems/v1.1-aessiv/Sjl6QXHm2IjuKwaKgJ5jig== b/tests/example_filesystems/v1.1-aessiv/Sjl6QXHm2IjuKwaKgJ5jig== deleted file mode 120000 index b3d31e3..0000000 --- a/tests/example_filesystems/v1.1-aessiv/Sjl6QXHm2IjuKwaKgJ5jig== +++ /dev/null @@ -1 +0,0 @@ -ozeZ1xXCP-Q904JCvkPk40enJd5zVL6FqBugkS6Y4tfcii_G1DOdDQ== \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-aessiv/gocryptfs.conf b/tests/example_filesystems/v1.1-aessiv/gocryptfs.conf deleted file mode 100644 index d16051a..0000000 --- a/tests/example_filesystems/v1.1-aessiv/gocryptfs.conf +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Creator": "gocryptfs v1.1-beta1-33-gf054353-dirty", - "EncryptedKey": "y2ldEXg3Ui0jwic99bqvvrvGRPRDB7gYzvOBwZxcmWqRgcp3BLMShhIXwx3Pewmst5TivqSrK2r9wUIL", - "ScryptObject": { - "Salt": "oEt1In6W5UD1Pe9CFSz21x5ptTRluU43mmshUtmSwAk=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames", - "AESSIV" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-aessiv/gocryptfs.diriv b/tests/example_filesystems/v1.1-aessiv/gocryptfs.diriv deleted file mode 100644 index 9ca19fd..0000000 --- a/tests/example_filesystems/v1.1-aessiv/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -‘ºqyæ@Œ¤0‰kY´] \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk= b/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk= deleted file mode 100644 index a5c444d..0000000 Binary files a/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk= and /dev/null differ diff --git a/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk=.name b/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk=.name deleted file mode 100644 index 1865eda..0000000 --- a/tests/example_filesystems/v1.1-aessiv/gocryptfs.longname.dDhdE3C5egl47Q4C4SuPNGPGkzyxuuHCP1efYMCaGqk=.name +++ /dev/null @@ -1 +0,0 @@ -8S9oaCrWGfWIF0_DTQsRvNARW78Vl5HcEYPZOwh3susDIHIbs8JiAF19oqWQz5HN1gpH2213kWqE4m1H1jVKslRHxSPxkQ5sDyaIm4PBZZg5-5djCYoQDLObvrgQv9HsN_NDb2rV8bmmH9SFArJ2SSKX5JdbMcraGr9Rj1AE89-9jIS0VTfKvpA_UgZEdR6IJ7V8VnD3eNo4KsBzJiL4G5wlpxvDLTy7mm7lxK_erV5gzKVHZGIz9Z-ehF--duIfY3x_h2hDNdocIKQltOEcxryHtcUqzcuFB_XkjW6BOTOYINHvLLA8CkLNSOXxLAqoeeu-8GwTgIDKrKhGnTTzgQ== \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-aessiv/jCGXyJJqu4sdxRLsDQNEtA== b/tests/example_filesystems/v1.1-aessiv/jCGXyJJqu4sdxRLsDQNEtA== deleted file mode 120000 index 20d2b58..0000000 --- a/tests/example_filesystems/v1.1-aessiv/jCGXyJJqu4sdxRLsDQNEtA== +++ /dev/null @@ -1 +0,0 @@ -GMqHOo4BNUhfLc-Vqi_R6J76C-OQhHLVgsBl5j9t-XFoq97KNlcuC1Vd \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse-plaintextnames/.gocryptfs.reverse.conf b/tests/example_filesystems/v1.1-reverse-plaintextnames/.gocryptfs.reverse.conf deleted file mode 100644 index e7ea1a8..0000000 --- a/tests/example_filesystems/v1.1-reverse-plaintextnames/.gocryptfs.reverse.conf +++ /dev/null @@ -1,17 +0,0 @@ -{ - "Creator": "gocryptfs v1.1-beta1-33-gf054353-dirty", - "EncryptedKey": "bMqEbjtvZek9yAGzhsTYmaDcqnE7wvR+1fWvy+YCMQTwtmvNbpKnfFH3wacPNKttQ7BcpFrOi4Ux+Bw+", - "ScryptObject": { - "Salt": "RgvSW4AxpA9z/Gb6RCCmKeA4A2vC+l0vu9DnEKIWQZU=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "PlaintextNames", - "AESSIV" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse-plaintextnames/abs b/tests/example_filesystems/v1.1-reverse-plaintextnames/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/v1.1-reverse-plaintextnames/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse-plaintextnames/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/example_filesystems/v1.1-reverse-plaintextnames/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.1-reverse-plaintextnames/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.1-reverse-plaintextnames/rel b/tests/example_filesystems/v1.1-reverse-plaintextnames/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/v1.1-reverse-plaintextnames/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse-plaintextnames/status.txt b/tests/example_filesystems/v1.1-reverse-plaintextnames/status.txt deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.1-reverse-plaintextnames/status.txt +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.1-reverse/.gocryptfs.reverse.conf b/tests/example_filesystems/v1.1-reverse/.gocryptfs.reverse.conf deleted file mode 100644 index 9095ef5..0000000 --- a/tests/example_filesystems/v1.1-reverse/.gocryptfs.reverse.conf +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Creator": "gocryptfs v1.1-beta1-33-gf054353-dirty", - "EncryptedKey": "GD7CQzhKMs4r8B/jc7eNNAffyMn4Z2A0tH9EC50y6v5y6amJdU6NQK5xLPWpWSc45si5L26VOVhT8dhz", - "ScryptObject": { - "Salt": "G/Cpk6TnscJzx1fae9t8guejwoPk1lsGkkcljIMjJdw=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames", - "AESSIV" - ] -} \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse/abs b/tests/example_filesystems/v1.1-reverse/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/v1.1-reverse/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/example_filesystems/v1.1-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.1-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.1-reverse/rel b/tests/example_filesystems/v1.1-reverse/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/v1.1-reverse/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/v1.1-reverse/status.txt b/tests/example_filesystems/v1.1-reverse/status.txt deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.1-reverse/status.txt +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.3-reverse/.gocryptfs.reverse.conf b/tests/example_filesystems/v1.3-reverse/.gocryptfs.reverse.conf deleted file mode 100644 index 4241280..0000000 --- a/tests/example_filesystems/v1.3-reverse/.gocryptfs.reverse.conf +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Creator": "gocryptfs v1.3", - "EncryptedKey": "o6yhOpoaToWqs7iZMgx2J+dmrRcL8TOjqd7ntlqy4Y/g/ygNRADJXGITtEIDukf7FbGyn2JNZtWs/4ZOgLNmYw==", - "ScryptObject": { - "Salt": "8a64zpm0vXFg9uretHuwbxijzQmx2QF4hKOYM0yK/S8=", - "N": 65536, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64", - "AESSIV" - ] -} diff --git a/tests/example_filesystems/v1.3-reverse/abs b/tests/example_filesystems/v1.3-reverse/abs deleted file mode 120000 index e1740fa..0000000 --- a/tests/example_filesystems/v1.3-reverse/abs +++ /dev/null @@ -1 +0,0 @@ -/a/b/c/d \ No newline at end of file diff --git a/tests/example_filesystems/v1.3-reverse/dir1/dir2/file b/tests/example_filesystems/v1.3-reverse/dir1/dir2/file deleted file mode 100644 index e64c723..0000000 Binary files a/tests/example_filesystems/v1.3-reverse/dir1/dir2/file and /dev/null differ diff --git a/tests/example_filesystems/v1.3-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/example_filesystems/v1.3-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.3-reverse/longname_255_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.3-reverse/rel b/tests/example_filesystems/v1.3-reverse/rel deleted file mode 120000 index 8279c75..0000000 --- a/tests/example_filesystems/v1.3-reverse/rel +++ /dev/null @@ -1 +0,0 @@ -status.txt \ No newline at end of file diff --git a/tests/example_filesystems/v1.3-reverse/status.txt b/tests/example_filesystems/v1.3-reverse/status.txt deleted file mode 100644 index 68300b8..0000000 --- a/tests/example_filesystems/v1.3-reverse/status.txt +++ /dev/null @@ -1 +0,0 @@ -It works! diff --git a/tests/example_filesystems/v1.3/gocryptfs.conf b/tests/example_filesystems/v1.3/gocryptfs.conf deleted file mode 100644 index e6b4aec..0000000 --- a/tests/example_filesystems/v1.3/gocryptfs.conf +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Creator": "gocryptfs v1.2.1-23-gd78a8d1-dirty", - "EncryptedKey": "WGhKfCvV/LBZdwpWz3Fs+9UFUJbtTooBiZMuthd8Hz3nq0g+zU7H+68ZkrCLdcC08PUNHVbvDdlGpRh0czbbyA==", - "ScryptObject": { - "Salt": "LkS43fRGN3SfcFbVhPLo3uKh3h+4LYLNlqEUf+JIWf4=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames", - "Raw64", - "HKDF" - ] -} diff --git a/tests/example_filesystems/v1.3/gocryptfs.diriv b/tests/example_filesystems/v1.3/gocryptfs.diriv deleted file mode 100644 index d507f03..0000000 --- a/tests/example_filesystems/v1.3/gocryptfs.diriv +++ /dev/null @@ -1,2 +0,0 @@ -N¦8‘mm$;ù¹;ó\ -6¶ \ No newline at end of file diff --git a/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs b/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs deleted file mode 100644 index e5c0a58..0000000 Binary files a/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs and /dev/null differ diff --git a/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs.name b/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs.name deleted file mode 100644 index c0aceae..0000000 --- a/tests/example_filesystems/v1.3/gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs.name +++ /dev/null @@ -1 +0,0 @@ -K9GWSIcjWZgvd3TpclEcrWUw_QmLRotdyEFxkXLyVDiLZlqC6oJ_LcouD_9ZTkFL72LaB3P0nx7dMeyjd9m1k_aLS1Mqbnj5F7PwiVSVnKugBsooIa7enIuH1x_riP9ppeDEUNPsDXtDlqESe75rc9dYptYmYC_MsG3ve8n78YCU5h8fUBL271v2yv8Tbgc0u7d5ygLqPgTYdBMXsSgOXxviMU73y9UlA3DWfDArb36N0FHpiiphXgu6_uzckiig9o-SFv-o2eyyKjHNClsWAP32opj-T4DuWU7Q_5858hiedJISv8zI0NTYYkeCluSZ_EkIXidzKB5vcswetGSJmg \ No newline at end of file diff --git a/tests/example_filesystems/v1.3/gv65k_g2NQyBsSv_5dzMVQ b/tests/example_filesystems/v1.3/gv65k_g2NQyBsSv_5dzMVQ deleted file mode 120000 index 79876d9..0000000 --- a/tests/example_filesystems/v1.3/gv65k_g2NQyBsSv_5dzMVQ +++ /dev/null @@ -1 +0,0 @@ -ra2NOzuRPOI9tj-Hc7RIYJcZNCJKWY1bo4681ABZi5eEMkK9iZCQ8A \ No newline at end of file diff --git a/tests/example_filesystems/v1.3/mGj2_hdnHe34Sp0iIQUwuw b/tests/example_filesystems/v1.3/mGj2_hdnHe34Sp0iIQUwuw deleted file mode 100644 index d653f78..0000000 Binary files a/tests/example_filesystems/v1.3/mGj2_hdnHe34Sp0iIQUwuw and /dev/null differ diff --git a/tests/example_filesystems/v1.3/uD4PVrDBY5y2k_qLKNOFvA b/tests/example_filesystems/v1.3/uD4PVrDBY5y2k_qLKNOFvA deleted file mode 120000 index d121261..0000000 --- a/tests/example_filesystems/v1.3/uD4PVrDBY5y2k_qLKNOFvA +++ /dev/null @@ -1 +0,0 @@ -pAes0cNmAncysGM-LxZ-jXvIpdLwc2qQNXvrEw0l1-dM5X74-kBXgF7P \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/6nGs4Ugr3EAHd0KzkyLZ-Q b/tests/fsck/broken_fs_v1.4/6nGs4Ugr3EAHd0KzkyLZ-Q deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/CMyUifVTjW5fsgXonWBT_RDkvLkdGrLttkZ45T3Oi3A b/tests/fsck/broken_fs_v1.4/CMyUifVTjW5fsgXonWBT_RDkvLkdGrLttkZ45T3Oi3A deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/Ef-68icxbQ-TuvmnWHuItB1BeLB92dNCXMXiz2M-zPI b/tests/fsck/broken_fs_v1.4/Ef-68icxbQ-TuvmnWHuItB1BeLB92dNCXMXiz2M-zPI deleted file mode 100644 index 84b9a70..0000000 Binary files a/tests/fsck/broken_fs_v1.4/Ef-68icxbQ-TuvmnWHuItB1BeLB92dNCXMXiz2M-zPI and /dev/null differ diff --git a/tests/fsck/broken_fs_v1.4/GUvJFSfy7S1AXUdy4pDRLw b/tests/fsck/broken_fs_v1.4/GUvJFSfy7S1AXUdy4pDRLw deleted file mode 120000 index 7bbd005..0000000 --- a/tests/fsck/broken_fs_v1.4/GUvJFSfy7S1AXUdy4pDRLw +++ /dev/null @@ -1 +0,0 @@ -RFPnVN8r1HjIrFVJ8PffC7ObzAIeBx3DQh8FbgvmbT8Ho8mU \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/K2m0E6qzIfoLkVZJanoUiQ/mWEr9JLch2FW40qhbnPgpg b/tests/fsck/broken_fs_v1.4/K2m0E6qzIfoLkVZJanoUiQ/mWEr9JLch2FW40qhbnPgpg deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/OtrNpznB8aMTKPi6bopM2g b/tests/fsck/broken_fs_v1.4/OtrNpznB8aMTKPi6bopM2g deleted file mode 100644 index dab7c69..0000000 Binary files a/tests/fsck/broken_fs_v1.4/OtrNpznB8aMTKPi6bopM2g and /dev/null differ diff --git a/tests/fsck/broken_fs_v1.4/PnkpLqHimGudw4C3jFY-Yw/_y58usbKXq_YRPMKfC3TNw b/tests/fsck/broken_fs_v1.4/PnkpLqHimGudw4C3jFY-Yw/_y58usbKXq_YRPMKfC3TNw deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/PnkpLqHimGudw4C3jFY-Yw/gocryptfs.diriv b/tests/fsck/broken_fs_v1.4/PnkpLqHimGudw4C3jFY-Yw/gocryptfs.diriv deleted file mode 100644 index 178763a..0000000 --- a/tests/fsck/broken_fs_v1.4/PnkpLqHimGudw4C3jFY-Yw/gocryptfs.diriv +++ /dev/null @@ -1,2 +0,0 @@ -f—`Êá -{g*@w¹6£ \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/V5DjvW5BXlGl1yCIJn4lPgdjdMvW_LUfc7G-R8W1cZ0 b/tests/fsck/broken_fs_v1.4/V5DjvW5BXlGl1yCIJn4lPgdjdMvW_LUfc7G-R8W1cZ0 deleted file mode 100644 index 6101efa..0000000 Binary files a/tests/fsck/broken_fs_v1.4/V5DjvW5BXlGl1yCIJn4lPgdjdMvW_LUfc7G-R8W1cZ0 and /dev/null differ diff --git a/tests/fsck/broken_fs_v1.4/b00sbnGXGToadr01GHZaYQn8tjyRhe1OXNBZoQtMlcQ b/tests/fsck/broken_fs_v1.4/b00sbnGXGToadr01GHZaYQn8tjyRhe1OXNBZoQtMlcQ deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/ejZ3FX0zlFTpSfv-FBJ2u3ojwSN1XSqpNpCHxa5VGWw b/tests/fsck/broken_fs_v1.4/ejZ3FX0zlFTpSfv-FBJ2u3ojwSN1XSqpNpCHxa5VGWw deleted file mode 100644 index f76dd23..0000000 Binary files a/tests/fsck/broken_fs_v1.4/ejZ3FX0zlFTpSfv-FBJ2u3ojwSN1XSqpNpCHxa5VGWw and /dev/null differ diff --git a/tests/fsck/broken_fs_v1.4/gocryptfs.conf b/tests/fsck/broken_fs_v1.4/gocryptfs.conf deleted file mode 100644 index cedf571..0000000 --- a/tests/fsck/broken_fs_v1.4/gocryptfs.conf +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Creator": "gocryptfs v1.4.4-13-ga4f3a7d-dirty", - "EncryptedKey": "yfnIx9uKv2ZX80KXOlfb4fWws3RNqvcjsx/Ajr0x4pRfg8NLqhWRpEUWGk8NSdVFXKWVDgdhSoYkbfVnFXl07g==", - "ScryptObject": { - "Salt": "R78m123zJxxO6uU1bg6/0azppry1FoGdH1/Op1xFq+4=", - "N": 65536, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64" - ] -} diff --git a/tests/fsck/broken_fs_v1.4/gocryptfs.diriv b/tests/fsck/broken_fs_v1.4/gocryptfs.diriv deleted file mode 100644 index d7bbcda..0000000 --- a/tests/fsck/broken_fs_v1.4/gocryptfs.diriv +++ /dev/null @@ -1,2 +0,0 @@ -å8]ÃjM -âPg¡çDóç \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/iI0MtUdzELPeOAZYwYZFee169hpGgd3l2PXQBcc9sl4 b/tests/fsck/broken_fs_v1.4/iI0MtUdzELPeOAZYwYZFee169hpGgd3l2PXQBcc9sl4 deleted file mode 120000 index 4b707cb..0000000 --- a/tests/fsck/broken_fs_v1.4/iI0MtUdzELPeOAZYwYZFee169hpGgd3l2PXQBcc9sl4 +++ /dev/null @@ -1 +0,0 @@ -%%%broken_symlink%%% \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/invalid_file_name.3 b/tests/fsck/broken_fs_v1.4/invalid_file_name.3 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/invalid_file_name_2 b/tests/fsck/broken_fs_v1.4/invalid_file_name_2 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/invalid_file_name____1 b/tests/fsck/broken_fs_v1.4/invalid_file_name____1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/broken_fs_v1.4/qOA8a4yuvgbMFpz7277R8A b/tests/fsck/broken_fs_v1.4/qOA8a4yuvgbMFpz7277R8A deleted file mode 100644 index 8621a03..0000000 --- a/tests/fsck/broken_fs_v1.4/qOA8a4yuvgbMFpz7277R8A +++ /dev/null @@ -1 +0,0 @@ -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/tests/fsck/broken_fs_v1.4/s-P7PcQDUcVkoeMDnC3EYA b/tests/fsck/broken_fs_v1.4/s-P7PcQDUcVkoeMDnC3EYA deleted file mode 120000 index 158f38a..0000000 --- a/tests/fsck/broken_fs_v1.4/s-P7PcQDUcVkoeMDnC3EYA +++ /dev/null @@ -1 +0,0 @@ -Qso5-4WJ2iAxF674mUarvuNbIMTLSJLqfEh3Chq3I_Rm2sY2 \ No newline at end of file diff --git a/tests/fsck/broken_fs_v1.4/trqecbMNXdzLqzpk7fSfKw/gocryptfs.diriv b/tests/fsck/broken_fs_v1.4/trqecbMNXdzLqzpk7fSfKw/gocryptfs.diriv deleted file mode 100644 index 41f0034..0000000 --- a/tests/fsck/broken_fs_v1.4/trqecbMNXdzLqzpk7fSfKw/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -Wc diff --git a/tests/fsck/broken_fs_v1.4/vDKs8a7UtM3PmEKk9wlPcA b/tests/fsck/broken_fs_v1.4/vDKs8a7UtM3PmEKk9wlPcA deleted file mode 100644 index 1dff1a1..0000000 Binary files a/tests/fsck/broken_fs_v1.4/vDKs8a7UtM3PmEKk9wlPcA and /dev/null differ diff --git a/tests/fsck/broken_fs_v1.4/yrwcjj2qoC4IYvhw9sbfRg/gocryptfs.diriv b/tests/fsck/broken_fs_v1.4/yrwcjj2qoC4IYvhw9sbfRg/gocryptfs.diriv deleted file mode 100644 index 29198ce..0000000 --- a/tests/fsck/broken_fs_v1.4/yrwcjj2qoC4IYvhw9sbfRg/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -LOã/;pl]Ù×n·ÌÙfooo diff --git a/tests/fsck/broken_fs_v1.4/yrwcjj2qoC4IYvhw9sbfRg/uC2yqKyQUXSJF-YF1Ya5nQ b/tests/fsck/broken_fs_v1.4/yrwcjj2qoC4IYvhw9sbfRg/uC2yqKyQUXSJF-YF1Ya5nQ deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fsck/fsck_test.go b/tests/fsck/fsck_test.go deleted file mode 100644 index 3aaba9e..0000000 --- a/tests/fsck/fsck_test.go +++ /dev/null @@ -1,128 +0,0 @@ -package fsck - -import ( - "encoding/base64" - "os" - "os/exec" - "runtime" - "strings" - "syscall" - "testing" - "time" - - "github.com/pkg/xattr" - - "github.com/rfjakob/gocryptfs/internal/exitcodes" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func dec64(in string) (out []byte) { - out, err := base64.RawURLEncoding.DecodeString(in) - if err != nil { - panic(err) - } - return out -} - -func TestBrokenFsV14(t *testing.T) { - // git does not save extended attributes, so we apply them here. - // xattr_good - xattr.Set("broken_fs_v1.4/6nGs4Ugr3EAHd0KzkyLZ-Q", - "user.gocryptfs.0a5e7yWl0SGUGeWB0Sy2Kg", - dec64("hxnZvXSkDicfwVS9w4r1yYkFF61Qou6NaL-VhObYEdu6kuM")) - // xattr_corrupt_name - xattr.Set("broken_fs_v1.4/CMyUifVTjW5fsgXonWBT_RDkvLkdGrLttkZ45T3Oi3A", - "user.gocryptfs.0a5e7yWl0SGUGeWB0Sy2K0", - dec64("QHUMDTgbnl8Sv_A2dFQic_G2vN4_gmDna3651JAhF7OZ-YI")) - // xattr_corrupt_value - xattr.Set("broken_fs_v1.4/b00sbnGXGToadr01GHZaYQn8tjyRhe1OXNBZoQtMlcQ", - "user.gocryptfs.0a5e7yWl0SGUGeWB0Sy2Kg", - dec64("A0hvCePeKpL8bCpijhDKtf7cIijXYQsPnEbNJ84M2ONW0dd")) - - cmd := exec.Command(test_helpers.GocryptfsBinary, "-fsck", "-extpass", "echo test", "broken_fs_v1.4") - outBin, err := cmd.CombinedOutput() - out := string(outBin) - t.Log(out) - code := test_helpers.ExtractCmdExitCode(err) - if code != exitcodes.FsckErrors { - t.Errorf("wrong exit code, have=%d want=%d", code, exitcodes.FsckErrors) - } -} - -func TestExampleFses(t *testing.T) { - dirfd, err := os.Open("../example_filesystems") - if err != nil { - t.Fatal(err) - } - var fsNames []string - entries, err := dirfd.Readdir(0) - if err != nil { - t.Fatal(err) - } - for _, e := range entries { - if !e.IsDir() { - continue - } - if strings.Contains(e.Name(), "reverse") { - continue - } - if e.Name() == "content" { - continue - } - fsNames = append(fsNames, e.Name()) - } - for _, n := range fsNames { - t.Logf("Checking %q", n) - path := "../example_filesystems/" + n - cmd := exec.Command(test_helpers.GocryptfsBinary, "-fsck", "-extpass", "echo test", path) - outBin, err := cmd.CombinedOutput() - out := string(outBin) - code := test_helpers.ExtractCmdExitCode(err) - if code == exitcodes.DeprecatedFS { - continue - } - if code != 0 { - t.Log(out) - t.Errorf("fsck returned code %d but fs should be clean", code) - } - } - dirfd.Close() -} - -// TestTerabyteFile verifies that fsck does something intelligent when it hits -// a 1-terabyte sparse file (trying to read the whole file is not intelligent). -func TestTerabyteFile(t *testing.T) { - if runtime.GOOS != "linux" { - t.Skipf("Only linux supports SEEK_DATA") - } - cDir := test_helpers.InitFS(t) - pDir := cDir + ".mnt" - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test") - defer test_helpers.UnmountErr(pDir) - veryBigFile := pDir + "/veryBigFile" - fd, err := os.Create(veryBigFile) - if err != nil { - t.Fatal(err) - } - defer fd.Close() - var oneTiB int64 = 1024 * 1024 * 1024 * 1024 - _, err = fd.WriteAt([]byte("foobar"), oneTiB) - if err != nil { - t.Fatal(err) - } - fi, err := fd.Stat() - if err != nil { - t.Fatal(err) - } - t.Logf("size=%d, running fsck", fi.Size()) - cmd := exec.Command(test_helpers.GocryptfsBinary, "-fsck", "-extpass", "echo test", cDir) - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - cmd.Start() - timer := time.AfterFunc(10*time.Second, func() { - t.Error("timeout, sending SIGINT") - syscall.Kill(cmd.Process.Pid, syscall.SIGINT) - }) - cmd.Wait() - timer.Stop() -} diff --git a/tests/fsck/run_fsck.bash b/tests/fsck/run_fsck.bash deleted file mode 100755 index 9637381..0000000 --- a/tests/fsck/run_fsck.bash +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec ../../gocryptfs -fsck -extpass "echo test" broken_fs_v1.4 diff --git a/tests/fuse-unmount.bash b/tests/fuse-unmount.bash deleted file mode 100755 index debae29..0000000 --- a/tests/fuse-unmount.bash +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -eu -# -# Compatibility wrapper around "fusermount" on Linux and "umount" on -# Mac OS X and friends. -# -# This script can be sourced or executed directly. -# -function fuse-unmount { - local MYNAME=$(basename "$BASH_SOURCE") - if [[ $# -eq 0 ]] ; then - echo "$MYNAME: missing argument" - exit 1 - fi - if [[ $OSTYPE == linux* ]] ; then - fusermount -u "$@" - else - # Mountpoint is in last argument, ignore anything else - # (like additional flags for fusermount). - local MNT=${@:$#} - umount "$MNT" - fi -} -# If the process name and the source file name is identical -# we have been executed, not sourced. -if [[ $(basename "$0") == $(basename "$BASH_SOURCE") ]] ; then - fuse-unmount "$@" -fi diff --git a/tests/hkdf_sanity/broken_content/gocryptfs.conf b/tests/hkdf_sanity/broken_content/gocryptfs.conf deleted file mode 100644 index 205f3ad..0000000 --- a/tests/hkdf_sanity/broken_content/gocryptfs.conf +++ /dev/null @@ -1,17 +0,0 @@ -{ - "Creator": "gocryptfs v1.2.1-32-g14038a1-dirty", - "EncryptedKey": "b3888jnQC5GYem+YGtUkOTS13/YCOfA6J0/bkftfEoNA9fZTN2xMGw4c+LK+emg4L6P2wGvm44RUqCfFfgowxw==", - "ScryptObject": { - "Salt": "7YnR8bF7TzYNP5mIwmpQ1qj4e/QZkbH92Hx7YQctIZQ=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "PlaintextNames" - ] -} diff --git a/tests/hkdf_sanity/broken_content/status.txt b/tests/hkdf_sanity/broken_content/status.txt deleted file mode 100644 index 30d42f7..0000000 Binary files a/tests/hkdf_sanity/broken_content/status.txt and /dev/null differ diff --git a/tests/hkdf_sanity/broken_names/L3yg-cJYAInDGg4TcjXrnw b/tests/hkdf_sanity/broken_names/L3yg-cJYAInDGg4TcjXrnw deleted file mode 100644 index 7ba2789..0000000 Binary files a/tests/hkdf_sanity/broken_names/L3yg-cJYAInDGg4TcjXrnw and /dev/null differ diff --git a/tests/hkdf_sanity/broken_names/gocryptfs.conf b/tests/hkdf_sanity/broken_names/gocryptfs.conf deleted file mode 100644 index f0b1509..0000000 --- a/tests/hkdf_sanity/broken_names/gocryptfs.conf +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Creator": "gocryptfs v1.2.1-32-g14038a1-dirty", - "EncryptedKey": "0ymk/BtKEN1KmRLMquLinLIzXDaf+GLuP2f9R4VbLOglim9nXd5WxkCFl0DQg0J2FtCEke9MQBaCfL5OTJdR4g==", - "ScryptObject": { - "Salt": "tCrF2o5GoOyQt0LAlCWk47hyJsF5K6ID9uPzjTSBbh8=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64" - ] -} diff --git a/tests/hkdf_sanity/broken_names/gocryptfs.diriv b/tests/hkdf_sanity/broken_names/gocryptfs.diriv deleted file mode 100644 index 24f3d28..0000000 --- a/tests/hkdf_sanity/broken_names/gocryptfs.diriv +++ /dev/null @@ -1 +0,0 @@ -ï%C´×xõ(E£!½dц \ No newline at end of file diff --git a/tests/hkdf_sanity/sanity_test.go b/tests/hkdf_sanity/sanity_test.go deleted file mode 100644 index b382861..0000000 --- a/tests/hkdf_sanity/sanity_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// We test two filesystems that have the "HKDF" feature flag in their config file -// set, but the actual file contents and names are encrypted with HKDF disabled. -// This test verifies that the "HKDF" feature flag in the config file takes effect. -package hkdf_sanity - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func TestBrokenContent(t *testing.T) { - cDir := "broken_content" - pDir := test_helpers.TmpDir + "/" + cDir - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", "-wpanic=false") - _, err := ioutil.ReadFile(pDir + "/status.txt") - if err == nil { - t.Error("this should fail") - } - test_helpers.UnmountPanic(pDir) -} - -func TestBrokenNames(t *testing.T) { - cDir := "broken_names" - pDir := test_helpers.TmpDir + "/" + cDir - test_helpers.MountOrFatal(t, cDir, pDir, "-extpass", "echo test", "-wpanic=false") - _, err := os.Stat(pDir + "/status.txt") - if err == nil { - t.Error("this should fail") - } - test_helpers.UnmountPanic(pDir) -} diff --git a/tests/len2elen.sh b/tests/len2elen.sh deleted file mode 100755 index 86f2119..0000000 --- a/tests/len2elen.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -eu -# -# Check plaintext file name length -> encrypted file name length relation -# -# Part of the gocryptfs test suite -# https://nuetzlich.net/gocryptfs/ - -NAME="x" -LEN=1 - -if [[ ! -f a/gocryptfs.conf ]] ; then - echo "fatal: must have gocryptfs dir 'a' mounted at 'b'" - exit 1 -fi -if ! mountpoint b > /dev/null ; then - echo "fatal: must have gocryptfs dir 'a' mounted at 'b'" - exit 1 -fi - -rm -f b/* - -while [[ $LEN -le 255 ]]; do - touch b/$NAME || break - ELEN=$(ls a | wc -L) - echo $LEN $ELEN - rm b/$NAME - NAME="${NAME}x" - LEN=${#NAME} -done diff --git a/tests/matrix/atime_darwin.go b/tests/matrix/atime_darwin.go deleted file mode 100644 index 5f89c69..0000000 --- a/tests/matrix/atime_darwin.go +++ /dev/null @@ -1,9 +0,0 @@ -package matrix - -import ( - "syscall" -) - -func extractAtimeMtime(st syscall.Stat_t) [2]syscall.Timespec { - return [2]syscall.Timespec{st.Atimespec, st.Mtimespec} -} diff --git a/tests/matrix/atime_linux.go b/tests/matrix/atime_linux.go deleted file mode 100644 index fb7b94f..0000000 --- a/tests/matrix/atime_linux.go +++ /dev/null @@ -1,9 +0,0 @@ -package matrix - -import ( - "syscall" -) - -func extractAtimeMtime(st syscall.Stat_t) [2]syscall.Timespec { - return [2]syscall.Timespec{st.Atim, st.Mtim} -} diff --git a/tests/matrix/concurrency_test.go b/tests/matrix/concurrency_test.go deleted file mode 100644 index 24d4578..0000000 --- a/tests/matrix/concurrency_test.go +++ /dev/null @@ -1,186 +0,0 @@ -package matrix - -import ( - "bytes" - "io" - "log" - "os" - "sync" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// https://github.com/rfjakob/gocryptfs/issues/363 -// -// Note: this test calls log.Fatal() instead of t.Fatal() because apparently, -// calling t.Fatal() from a goroutine hangs the test. -func TestConcurrentReadWrite(t *testing.T) { - var wg sync.WaitGroup - fn := test_helpers.DefaultPlainDir + "/TestConcurrentReadWrite" - if f, err := os.Create(fn); err != nil { - t.Fatal(err) - } else { - f.Close() - } - buf := make([]byte, 100) - content := []byte("1234567890") - threads := 10 - loops := 30 - for i := 0; i < threads; i++ { - // Reader thread - wg.Add(1) - go func() { - fRd, err := os.Open(fn) - if err != nil { - log.Fatal(err) - } - for j := 0; j < loops; j++ { - n, err := fRd.ReadAt(buf, 0) - if err != nil && err != io.EOF { - log.Fatal(err) - } - if n != 0 && n != 10 { - log.Fatalf("strange read length: %d", n) - } - } - fRd.Close() - wg.Done() - }() - - // Writer thread - wg.Add(1) - go func() { - fWr, err := os.OpenFile(fn, os.O_RDWR, 0700) - if err != nil { - log.Fatal(err) - } - for j := 0; j < loops; j++ { - err = fWr.Truncate(0) - if err != nil { - log.Fatal(err) - } - _, err = fWr.WriteAt(content, 0) - if err != nil { - log.Fatal(err) - } - } - fWr.Close() - wg.Done() - }() - } - wg.Wait() -} - -// https://github.com/rfjakob/gocryptfs/issues/363 -// -// Note: this test calls log.Fatal() instead of t.Fatal() because apparently, -// calling t.Fatal() from a goroutine hangs the test. -func TestConcurrentReadCreate(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/TestConcurrentReadCreate" - content := []byte("1234567890") - loops := 100 - var wg sync.WaitGroup - // "Create()" thread - wg.Add(1) - go func() { - for i := 0; i < loops; i++ { - f, err := os.Create(fn) - if err != nil { - log.Fatal(err) - } - _, err = f.Write(content) - if err != nil { - log.Fatal(err) - } - f.Close() - syscall.Unlink(fn) - } - wg.Done() - }() - // "Reader" thread - wg.Add(1) - go func() { - buf0 := make([]byte, 100) - for i := 0; i < loops; i++ { - f, err := os.Open(fn) - if err != nil { - i++ - continue - } - n, err := f.Read(buf0) - if err == io.EOF { - i++ - continue - } - if err != nil { - log.Fatal(err) - } - buf := buf0[:n] - if bytes.Compare(buf, content) != 0 { - log.Fatal("content mismatch") - } - f.Close() - } - wg.Done() - }() - wg.Wait() -} - -// TestInoReuse tries to uncover problems when a file gets replaced by -// a directory with the same inode number (and vice versa). -// -// So far, it only has triggered warnings like this -// -// go-fuse: warning: Inode.Path: inode i4201033 is orphaned, replacing segment with ".go-fuse.5577006791947779410/deleted" -// -// but none of the "blocked waiting for FORGET". -func TestInoReuse(t *testing.T) { - var wg sync.WaitGroup - fn := test_helpers.DefaultPlainDir + "/" + t.Name() - - wg.Add(1) - go func() { - for i := 0; i < 1000; i++ { - fd, err := syscall.Creat(fn, 0600) - if err == syscall.EISDIR { - continue - } - if err != nil { - t.Error(err) - break - } - var st syscall.Stat_t - syscall.Fstat(fd, &st) - if i%2 == 0 { - syscall.Close(fd) - syscall.Unlink(fn) - } else { - syscall.Unlink(fn) - syscall.Close(fd) - - } - } - wg.Done() - }() - - wg.Add(1) - go func() { - for i := 0; i < 1000; i++ { - err := syscall.Mkdir(fn, 0700) - if err == syscall.EEXIST { - continue - } - if err != nil { - t.Error(err) - break - } - var st syscall.Stat_t - syscall.Stat(fn, &st) - syscall.Rmdir(fn) - } - wg.Done() - }() - wg.Wait() -} diff --git a/tests/matrix/dir_test.go b/tests/matrix/dir_test.go deleted file mode 100644 index 2f7a034..0000000 --- a/tests/matrix/dir_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package matrix - -import ( - "fmt" - "os" - "os/exec" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// Test Mkdir and Rmdir -func TestMkdirRmdir(t *testing.T) { - test_helpers.TestMkdirRmdir(t, test_helpers.DefaultPlainDir) -} - -// Overwrite an empty directory with another directory -func TestDirOverwrite(t *testing.T) { - dir1 := test_helpers.DefaultPlainDir + "/DirOverwrite1" - dir2 := test_helpers.DefaultPlainDir + "/DirOverwrite2" - err := os.Mkdir(dir1, 0777) - if err != nil { - t.Fatal(err) - } - err = os.Mkdir(dir2, 0777) - if err != nil { - t.Fatal(err) - } - err = syscall.Rename(dir1, dir2) - if err != nil { - t.Fatal(err) - } -} - -// Test that we can create and remove a directory regardless of the permission it has -// https://github.com/rfjakob/gocryptfs/issues/354 -func TestRmdirPerms(t *testing.T) { - for _, perm := range []uint32{0000, 0100, 0200, 0300, 0400, 0500, 0600, 0700} { - dir := fmt.Sprintf("TestRmdir%#o", perm) - path := test_helpers.DefaultPlainDir + "/" + dir - err := syscall.Mkdir(path, perm) - if err != nil { - t.Fatalf("Mkdir %q: %v", dir, err) - } - err = syscall.Rmdir(path) - if err != nil { - t.Fatalf("Rmdir %q: %v", dir, err) - } - } -} - -// TestHaveDotdot checks that we have "." and ".." in a directory. -// (gocryptfs v2.0-beta1 did not!) -func TestHaveDotdot(t *testing.T) { - dir1 := test_helpers.DefaultPlainDir + "/TestHaveDotdot" - err := os.Mkdir(dir1, 0700) - if err != nil { - t.Fatal(err) - } - // All Go readdir functions filter out "." and "..". - // Fall back to "ls -a" which does not. - out, err := exec.Command("ls", "-a", dir1).CombinedOutput() - if err != nil { - t.Fatal(err) - } - have := string(out) - want := ".\n..\n" - if have != want { - t.Errorf("have=%q want=%q", have, want) - } -} diff --git a/tests/matrix/fallocate_test.go b/tests/matrix/fallocate_test.go deleted file mode 100644 index dde0685..0000000 --- a/tests/matrix/fallocate_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package matrix - -import ( - "os" - "runtime" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -const ( - // From man statfs - TMPFS_MAGIC = 0x01021994 - EXT4_SUPER_MAGIC = 0xef53 -) - -// isWellKnownFS decides if the backing filesystem is well-known. -// The expected allocated sizes are only valid on tmpfs and ext4. btrfs -// gives different results, but that's not an error. -func isWellKnownFS(fn string) bool { - var fs syscall.Statfs_t - err := syscall.Statfs(fn, &fs) - if err != nil { - panic(err) - } - if fs.Type == EXT4_SUPER_MAGIC || fs.Type == TMPFS_MAGIC { - return true - } - return false -} - -const FALLOC_DEFAULT = 0x00 -const FALLOC_FL_KEEP_SIZE = 0x01 - -func TestFallocate(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skipf("OSX does not support fallocate") - } - fn := test_helpers.DefaultPlainDir + "/fallocate" - file, err := os.Create(fn) - if err != nil { - t.FailNow() - } - defer file.Close() - wellKnown := isWellKnownFS(test_helpers.DefaultCipherDir) - fd := int(file.Fd()) - nBytes := test_helpers.Du(t, fd) - if nBytes != 0 { - t.Fatalf("Empty file has %d bytes", nBytes) - } - // Allocate 30 bytes, keep size - // gocryptfs || (0 blocks) - // ext4 | d | (1 block) - // ^ d = data block - err = syscallcompat.Fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 30) - if err != nil { - t.Error(err) - } - var want int64 - nBytes = test_helpers.Du(t, fd) - want = 4096 - if nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - test_helpers.VerifySize(t, fn, 0) - // Three ciphertext blocks. The middle one should be a file hole. - // gocryptfs | h | h | d| (1 block) - // ext4 | d | h | d | (2 blocks) - // ^ h = file hole - // (Note that gocryptfs blocks are slightly bigger than the ext4 blocks, - // but the last one is partial) - err = file.Truncate(9000) - if err != nil { - t.Fatal(err) - } - nBytes = test_helpers.Du(t, fd) - want = 2 * 4096 - if wellKnown && nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - if md5 := test_helpers.Md5fn(fn); md5 != "5420afa22f6423a9f59e669540656bb4" { - t.Errorf("Wrong md5 %s", md5) - } - // Allocate the whole file space - // gocryptfs | h | h | d| (1 block) - // ext4 | d | d | d | (3 blocks - err = syscallcompat.Fallocate(fd, FALLOC_DEFAULT, 0, 9000) - if err != nil { - t.Fatal(err) - } - nBytes = test_helpers.Du(t, fd) - want = 3 * 4096 - if nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - // Neither apparent size nor content should have changed - test_helpers.VerifySize(t, fn, 9000) - if md5 := test_helpers.Md5fn(fn); md5 != "5420afa22f6423a9f59e669540656bb4" { - t.Errorf("Wrong md5 %s", md5) - } - - // Partial block on the end. The first ext4 block is dirtied by the header. - // gocryptfs | h | h | d| (1 block) - // ext4 | d | h | d | (2 blocks) - file.Truncate(0) - file.Truncate(9000) - nBytes = test_helpers.Du(t, fd) - want = 2 * 4096 - if wellKnown && nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - // Allocate 10 bytes in the second block - // gocryptfs | h | h | d| (1 block) - // ext4 | d | d | d | (3 blocks) - syscallcompat.Fallocate(fd, FALLOC_DEFAULT, 5000, 10) - nBytes = test_helpers.Du(t, fd) - want = 3 * 4096 - if wellKnown && nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - // Neither apparent size nor content should have changed - test_helpers.VerifySize(t, fn, 9000) - if md5 := test_helpers.Md5fn(fn); md5 != "5420afa22f6423a9f59e669540656bb4" { - t.Errorf("Wrong md5 %s", md5) - } - // Grow the file to 4 blocks - // gocryptfs | h | h | d |d| (2 blocks) - // ext4 | d | d | d | d | (4 blocks) - syscallcompat.Fallocate(fd, FALLOC_DEFAULT, 15000, 10) - nBytes = test_helpers.Du(t, fd) - want = 4 * 4096 - if wellKnown && nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - test_helpers.VerifySize(t, fn, 15010) - if md5 := test_helpers.Md5fn(fn); md5 != "c4c44c7a41ab7798a79d093eb44f99fc" { - t.Errorf("Wrong md5 %s", md5) - } - // Shrinking a file using fallocate should have no effect - for _, off := range []int64{0, 10, 2000, 5000} { - for _, sz := range []int64{0, 1, 42, 6000} { - syscallcompat.Fallocate(fd, FALLOC_DEFAULT, off, sz) - test_helpers.VerifySize(t, fn, 15010) - if md5 := test_helpers.Md5fn(fn); md5 != "c4c44c7a41ab7798a79d093eb44f99fc" { - t.Errorf("Wrong md5 %s", md5) - } - } - } - // We used to allocate 18 bytes too much: - // https://github.com/rfjakob/gocryptfs/issues/311 - // - // 8110 bytes of plaintext should get us exactly 8192 bytes of ciphertext. - err = file.Truncate(0) - if err != nil { - t.Fatal(err) - } - err = syscallcompat.Fallocate(fd, FALLOC_DEFAULT, 0, 8110) - if err != nil { - t.Fatal(err) - } - nBytes = test_helpers.Du(t, fd) - want = 8192 - if nBytes != want { - t.Errorf("Expected %d allocated bytes, have %d", want, nBytes) - } - // Cleanup - syscall.Unlink(fn) - if !wellKnown { - // Even though most tests have been executed still, inform the user - // that some were disabled - t.Skipf("backing fs is not ext4 or tmpfs, skipped some disk-usage checks\n") - } -} diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go deleted file mode 100644 index 6622213..0000000 --- a/tests/matrix/matrix_test.go +++ /dev/null @@ -1,903 +0,0 @@ -// Tests run for (almost all) combinations of openssl, aessiv, plaintextnames. -package matrix - -// File reading, writing, modification, truncate -// -// Runs everything four times, for all combinations of -// "-plaintextnames" and "-openssl". -// -// Test Matrix: -// openssl=true openssl=false -// plaintextnames=false X X -// plaintextnames=true X X - -import ( - "bytes" - "flag" - "fmt" - "io/ioutil" - "math/rand" - "os" - "os/exec" - "path/filepath" - "runtime" - "sync" - "syscall" - "testing" - - "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/internal/stupidgcm" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// Several tests need to be aware if plaintextnames is active or not, so make this -// a global variable -var testcase testcaseMatrix - -type testcaseMatrix struct { - plaintextnames bool - openssl string - aessiv bool - raw64 bool - extraArgs []string -} - -var matrix = []testcaseMatrix{ - // Normal - {false, "auto", false, false, nil}, - {false, "true", false, false, nil}, - {false, "false", false, false, nil}, - // Plaintextnames - {true, "true", false, false, nil}, - {true, "false", false, false, nil}, - // AES-SIV (does not use openssl, no need to test permutations) - {false, "auto", true, false, nil}, - {true, "auto", true, false, nil}, - // Raw64 - {false, "auto", false, true, nil}, - // -serialize_reads - {false, "auto", false, false, []string{"-serialize_reads"}}, - {false, "auto", false, false, []string{"-sharedstorage"}}, -} - -// This is the entry point for the tests -func TestMain(m *testing.M) { - // Make "testing.Verbose()" return the correct value - flag.Parse() - for _, testcase = range matrix { - if testcase.openssl == "true" && stupidgcm.BuiltWithoutOpenssl { - continue - } - if testing.Verbose() { - fmt.Printf("matrix: testcase = %#v\n", testcase) - } - test_helpers.ResetTmpDir(!testcase.plaintextnames) - opts := []string{"-zerokey"} - //opts = append(opts, "-fusedebug") - opts = append(opts, fmt.Sprintf("-openssl=%v", testcase.openssl)) - opts = append(opts, fmt.Sprintf("-plaintextnames=%v", testcase.plaintextnames)) - opts = append(opts, fmt.Sprintf("-aessiv=%v", testcase.aessiv)) - opts = append(opts, fmt.Sprintf("-raw64=%v", testcase.raw64)) - opts = append(opts, testcase.extraArgs...) - test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, opts...) - before := test_helpers.ListFds(0, test_helpers.TmpDir) - r := m.Run() - // Catch fd leaks in the tests. NOTE: this does NOT catch leaks in - // the gocryptfs FUSE process, but only in the tests that access it! - // All fds that point outside TmpDir are not interesting (the Go test - // infrastucture creates temporary log files we don't care about). - after := test_helpers.ListFds(0, test_helpers.TmpDir) - if len(before) != len(after) { - fmt.Printf("fd leak in test process? before, after:\n%v\n%v\n", before, after) - os.Exit(1) - } - test_helpers.UnmountPanic(test_helpers.DefaultPlainDir) - if r != 0 { - os.Exit(r) - } - } - os.Exit(0) -} - -// Write `n` random bytes to filename `fn`, read again, compare hash -func testWriteN(t *testing.T, fn string, n int) string { - file, err := os.Create(test_helpers.DefaultPlainDir + "/" + fn) - if err != nil { - t.Fatal(err) - } - - d := make([]byte, n) - for i := range d { - // Fill with pattern - d[i] = byte(rand.Int()) - } - _, err = file.Write(d) - if err != nil { - t.Fatal(err) - } - err = file.Close() - if err != nil { - t.Fatal(err) - } - - test_helpers.VerifySize(t, test_helpers.DefaultPlainDir+"/"+fn, n) - - hashWant := test_helpers.Md5hex(d) - - hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + "/" + fn) - - if hashActual != hashWant { - t.Errorf("Wrong content, hashWant=%s hashActual=%s", hashWant, hashActual) - } - - return hashActual -} - -func TestWrite10(t *testing.T) { - testWriteN(t, "10", 10) -} - -func TestWrite100(t *testing.T) { - testWriteN(t, "100", 100) -} - -func TestWrite1M(t *testing.T) { - testWriteN(t, "1M", 1024*1024) -} - -func TestWrite100x100(t *testing.T) { - hashWant := testWriteN(t, "100x100", 100) - // Read and check 100 times to catch race conditions - var i int - for i = 0; i < 100; i++ { - hashActual := test_helpers.Md5fn(test_helpers.DefaultPlainDir + "/100x100") - if hashActual != hashWant { - fmt.Printf("Read corruption in loop #%d: have=%s want=%s\n", i, hashActual, hashWant) - t.FailNow() - } else { - //fmt.Print(".") - } - } -} - -func TestWrite10Tight(t *testing.T) { - path := test_helpers.DefaultPlainDir + "/TestWrite10Tight" - content := make([]byte, 10) - buf := make([]byte, 100) - for i := 0; i < 100; i++ { - file, err := os.Create(path) - if err != nil { - t.Fatal(err) - } - _, err = file.Write(content) - if err != nil { - t.Fatal(err) - } - err = file.Close() - if err != nil { - t.Fatal(err) - } - file, err = os.Open(path) - if err != nil { - t.Fatal(err) - } - n, err := file.Read(buf) - if err != nil { - t.Fatal(err) - } - if n != 10 { - t.Fatalf("want 10 bytes, got %d", n) - } - err = file.Close() - if err != nil { - t.Fatal(err) - } - err = os.Remove(path) - if err != nil { - t.Fatal() - } - } -} - -// Hint for calculating reference md5sums: -// dd if=/dev/zero count=1 bs=XYZ | md5sum -func TestTruncate(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/truncate" - file, err := os.Create(fn) - if err != nil { - t.FailNow() - } - defer file.Close() - // Grow to two blocks - file.Truncate(7000) - test_helpers.VerifySize(t, fn, 7000) - if md5 := test_helpers.Md5fn(fn); md5 != "95d4ec7038e3e4fdbd5f15c34c3f0b34" { - t.Errorf("Wrong md5 %s", md5) - } - // Shrink - needs RMW - file.Truncate(6999) - test_helpers.VerifySize(t, fn, 6999) - if md5 := test_helpers.Md5fn(fn); md5 != "35fd15873ec6c35380064a41b9b9683b" { - t.Errorf("Wrong md5 %s", md5) - } - // Shrink to one partial block - file.Truncate(465) - test_helpers.VerifySize(t, fn, 465) - if md5 := test_helpers.Md5fn(fn); md5 != "a1534d6e98a6b21386456a8f66c55260" { - t.Errorf("Wrong md5 %s", md5) - } - // Grow to exactly one block - file.Truncate(4096) - test_helpers.VerifySize(t, fn, 4096) - if md5 := test_helpers.Md5fn(fn); md5 != "620f0b67a91f7f74151bc5be745b7110" { - t.Errorf("Wrong md5 %s", md5) - } - // Truncate to zero - file.Truncate(0) - test_helpers.VerifySize(t, fn, 0) - // Grow to 10MB (creates file holes) - var sz int - sz = 10 * 1024 * 1024 - file.Truncate(int64(sz)) - test_helpers.VerifySize(t, fn, sz) - if md5 := test_helpers.Md5fn(fn); md5 != "f1c9645dbc14efddc7d8a322685f26eb" { - t.Errorf("Wrong md5 %s", md5) - } - // Grow to 10MB + 100B (partial block on the end) - sz = 10*1024*1024 + 100 - file.Truncate(int64(sz)) - test_helpers.VerifySize(t, fn, sz) - if md5 := test_helpers.Md5fn(fn); md5 != "c23ea79b857b91a7ff07c6ecf185f1ca" { - t.Errorf("Wrong md5 %s", md5) - } - // Grow to 20MB (creates file holes, partial block on the front) - sz = 20 * 1024 * 1024 - file.Truncate(int64(sz)) - test_helpers.VerifySize(t, fn, sz) - if md5 := test_helpers.Md5fn(fn); md5 != "8f4e33f3dc3e414ff94e5fb6905cba8c" { - t.Errorf("Wrong md5 %s", md5) - } -} - -func TestAppend(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/append" - file, err := os.Create(fn) - if err != nil { - t.FailNow() - } - defer file.Close() - data := []byte("testdata123456789") // length 17 - var buf bytes.Buffer - var hashWant string - for i := 0; i <= 500; i++ { - file.Write(data) - buf.Write(data) - hashWant = test_helpers.Md5hex(buf.Bytes()) - hashActual := test_helpers.Md5fn(fn) - if hashWant != hashActual { - t.FailNow() - } - } - - // Overwrite with the same data - // Hash must stay the same - file.Seek(0, 0) - for i := 0; i <= 500; i++ { - file.Write(data) - hashActual := test_helpers.Md5fn(fn) - if hashWant != hashActual { - t.FailNow() - } - } -} - -// Create a file with holes by writing to offset 0 (block #0) and -// offset 4096 (block #1). -func TestFileHoles(t *testing.T) { - fn := test_helpers.DefaultPlainDir + "/fileholes" - file, err := os.Create(fn) - if err != nil { - t.Errorf("file create failed") - } - defer file.Close() - foo := []byte("foo") - file.Write(foo) - file.WriteAt(foo, 4096) - _, err = ioutil.ReadFile(fn) - if err != nil { - t.Error(err) - } -} - -// sContains - does the slice of strings "haystack" contain "needle"? -func sContains(haystack []string, needle string) bool { - for _, element := range haystack { - if element == needle { - return true - } - } - return false -} - -func TestRmwRace(t *testing.T) { - - runtime.GOMAXPROCS(10) - - fn := test_helpers.DefaultPlainDir + "/rmwrace" - f1, err := os.Create(fn) - if err != nil { - t.Fatalf("file create failed") - } - defer f1.Close() - f2, err := os.Create(fn) - if err != nil { - t.Fatalf("file create failed") - } - defer f2.Close() - - oldBlock := bytes.Repeat([]byte("o"), 4096) - - newBlock := bytes.Repeat([]byte("n"), 4096) - - shortBlock := bytes.Repeat([]byte("s"), 16) - - mergedBlock := make([]byte, 4096) - copy(mergedBlock, newBlock) - copy(mergedBlock[4080:], shortBlock) - - goodMd5 := make(map[string]int) - - for i := 0; i < 1000; i++ { - // Reset to [ooooooooo] - _, err = f1.WriteAt(oldBlock, 0) - if err != nil { - t.Fatalf("Write failed") - } - - var wg sync.WaitGroup - wg.Add(2) - - // Write to the end of the file, [....ssss] - go func() { - f1.WriteAt(shortBlock, 4080) - wg.Done() - }() - - // Overwrite to [nnnnnnn] - go func() { - f2.WriteAt(newBlock, 0) - wg.Done() - }() - - wg.Wait() - - // The file should be either: - // [nnnnnnnnnn] (md5: 6c1660fdabccd448d1359f27b3db3c99) or - // [nnnnnnssss] (md5: da885006a6a284530a427c73ce1e5c32) - // but it must not be - // [oooooossss] - - buf, _ := ioutil.ReadFile(fn) - m := test_helpers.Md5hex(buf) - goodMd5[m] = goodMd5[m] + 1 - - /* - if m == "6c1660fdabccd448d1359f27b3db3c99" { - fmt.Println(hex.Dump(buf)) - t.FailNow() - } - */ - } -} - -// With "--plaintextnames", the name "/gocryptfs.conf" is reserved. -// Otherwise there should be no restrictions. -func TestFiltered(t *testing.T) { - filteredFile := test_helpers.DefaultPlainDir + "/gocryptfs.conf" - file, err := os.Create(filteredFile) - if testcase.plaintextnames && err == nil { - t.Errorf("should have failed but didn't") - } else if !testcase.plaintextnames && err != nil { - t.Error(err) - } - file.Close() - - err = os.Remove(filteredFile) - if testcase.plaintextnames && err == nil { - t.Errorf("should have failed but didn't") - } else if !testcase.plaintextnames && err != nil { - t.Error(err) - } -} - -func TestFilenameEncryption(t *testing.T) { - file, err := os.Create(test_helpers.DefaultPlainDir + "/TestFilenameEncryption.txt") - file.Close() - if err != nil { - t.Fatal(err) - } - _, err = os.Stat(test_helpers.DefaultCipherDir + "/TestFilenameEncryption.txt") - if testcase.plaintextnames && err != nil { - t.Errorf("plaintextnames not working: %v", err) - } else if !testcase.plaintextnames && err == nil { - t.Errorf("file name encryption not working") - } -} - -// Test Rename -func TestRename(t *testing.T) { - test_helpers.TestRename(t, test_helpers.DefaultPlainDir) -} - -// Test that names of all lengths work -func TestNameLengths(t *testing.T) { - f, err := os.Open(test_helpers.DefaultPlainDir) - if err != nil { - t.Fatal(err) - } - entries, err := f.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - f.Close() - cnt1 := len(entries) - - wd := test_helpers.DefaultPlainDir + "/" - name := "x" - for len(name) < 2000 { - f, err := os.Create(wd + name + "x") - if err != nil { - break - } - name = name + "x" - f.Close() - f, err = os.Open(test_helpers.DefaultPlainDir) - if err != nil { - t.Fatal(err) - } - // In v1.7-rc2, we had a bug that allowed creation of too-long names. - // This threw errors in like this in READDIR: - // - // OpenDir ".": invalid entry "gocryptfs.longname.wrE-izsR9ciEkP7JSCFDrk_d_Nj4mQo1dGY6hjuixAU=": - // Could not read .name: ReadLongName: size=345 > limit=344 - // - entries, err = f.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - f.Close() - cnt2 := len(entries) - if cnt2 != cnt1+1 { - t.Fatalf("len=%d: expected %d dir entries, have %d: %v", len(name), cnt1+1, cnt2, entries) - } - err = syscall.Unlink(wd + name) - if err != nil { - t.Fatal(err) - } - } - if len(name) != 255 { - t.Errorf("maxlen=%d", len(name)) - } -} - -func TestLongNames(t *testing.T) { - fi, err := ioutil.ReadDir(test_helpers.DefaultCipherDir) - if err != nil { - t.Fatal(err) - } - cnt1 := len(fi) - wd := test_helpers.DefaultPlainDir + "/" - // Create file with long name - n255x := string(bytes.Repeat([]byte("x"), 255)) - f, err := os.Create(wd + n255x) - if err != nil { - t.Fatalf("Could not create n255x: %v", err) - } - f.Close() - if !test_helpers.VerifyExistence(t, wd+n255x) { - t.Errorf("n255x is not in directory listing") - } - // Rename long to long (target does not exist) - n255y := string(bytes.Repeat([]byte("y"), 255)) - err = os.Rename(wd+n255x, wd+n255y) - if err != nil { - t.Fatalf("Could not rename n255x to n255y: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+n255y) { - t.Errorf("n255y is not in directory listing") - } - // Rename long to long (target exists) - f, err = os.Create(wd + n255x) - if err != nil { - t.Fatalf("Could not create n255x: %v", err) - } - f.Close() - err = os.Rename(wd+n255x, wd+n255y) - if err != nil { - t.Fatalf("Could not rename n255x to n255y: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+n255y) { - t.Errorf("n255y is not in directory listing") - } - // Rename long to short (target does not exist) - err = os.Rename(wd+n255y, wd+"short") - if err != nil { - t.Fatalf("Could not rename n255y to short: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+"short") { - t.Errorf("short is not in directory listing") - } - // Rename long to short (target exists) - f, err = os.Create(wd + n255y) - if err != nil { - t.Fatalf("Could not create n255y: %v", err) - } - f.Close() - err = os.Rename(wd+n255y, wd+"short") - if err != nil { - t.Fatalf("Could not rename n255y to short: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+"short") { - t.Errorf("short is not in directory listing") - } - // Rename short to long (target does not exist) - err = os.Rename(wd+"short", wd+n255x) - if err != nil { - t.Fatalf("Could not rename short to n255x: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+n255x) { - t.Errorf("255x is not in directory listing II") - } - // Rename short to long (target exists) - f, err = os.Create(wd + "short") - if err != nil { - t.Fatalf("Could not create short: %v", err) - } - f.Close() - err = os.Rename(wd+"short", wd+n255x) - if err != nil { - t.Fatalf("Could not rename short to n255x: %v", err) - } - if !test_helpers.VerifyExistence(t, wd+n255x) { - t.Errorf("n255x is not in directory listing") - } - // Unlink - err = syscall.Unlink(wd + n255x) - if err != nil { - t.Fatalf("Could not unlink n255x: %v", err) - } - if test_helpers.VerifyExistence(t, wd+n255x) { - t.Errorf("n255x still there after unlink") - } - // Long symlink - n255s := string(bytes.Repeat([]byte("s"), 255)) - err = os.Symlink("/", wd+n255s) - if err != nil { - t.Fatal(err) - } - if !test_helpers.VerifyExistence(t, wd+n255s) { - t.Errorf("n255s is not in directory listing") - } - err = syscall.Unlink(wd + n255s) - if err != nil { - t.Error(err) - } - // Long dir - n255d := string(bytes.Repeat([]byte("d"), 255)) - err = os.Mkdir(wd+n255d, 0777) - if err != nil { - t.Fatal(err) - } - err = syscall.Rmdir(wd + n255d) - if err != nil { - t.Error(err) - } - // Check for orphaned files - fi, err = ioutil.ReadDir(test_helpers.DefaultCipherDir) - if err != nil { - t.Fatal(err) - } - cnt2 := len(fi) - if cnt1 != cnt2 { - t.Errorf("Leftover files, cnt1=%d cnt2=%d", cnt1, cnt2) - } -} - -// Create hard link with long name. -// This was broken up to v1.2. -func TestLongLink(t *testing.T) { - wd := test_helpers.DefaultPlainDir + "/" - target := wd + "TestLongLink.target" - f, err := os.Create(target) - if err != nil { - t.Fatalf("%v", err) - } - f.Close() - l255 := string(bytes.Repeat([]byte("l"), 255)) - err = os.Link(target, wd+l255) - if err != nil { - t.Error(err) - } -} - -func TestLchown(t *testing.T) { - name := test_helpers.DefaultPlainDir + "/symlink" - err := os.Symlink("/target/does/not/exist", name) - if err != nil { - t.Fatal(err) - } - err = os.Chown(name, os.Getuid(), os.Getgid()) - if err == nil { - t.Error("Chown on dangling symlink should fail") - } - err = os.Lchown(name, os.Getuid(), os.Getgid()) - if err != nil { - t.Error(err) - } -} - -// Set nanoseconds by path, symlink -func TestUtimesNanoSymlink(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skipf("MacOS \"touch\" does not support \"--no-dereference\"") - } - path := test_helpers.DefaultPlainDir + "/utimesnano_symlink" - err := os.Symlink("/some/nonexisting/file", path) - if err != nil { - t.Fatal(err) - } - // syscall.UtimesNano does not provide a way to pass AT_SYMLINK_NOFOLLOW, - // so we call the external utility "touch", which does. - cmd := exec.Command("touch", "--no-dereference", path) - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - err = cmd.Run() - if err != nil { - t.Error(err) - } -} - -type utimesTestcaseStruct struct { - // Input atime and mtime - in [2]syscall.Timespec - // Expected output atime and mtime - out [2]syscall.Timespec -} - -// compareTimespec return true if the two passed Timespec are identical. -func compareTimespec(want syscall.Timespec, actual syscall.Timespec) bool { - if want.Sec != actual.Sec { - return false - } - if want.Nsec != actual.Nsec { - return false - } - return true -} - -const _UTIME_OMIT = ((1 << 30) - 2) - -// doTestUtimesNano verifies that setting nanosecond-precision times on "path" -// works correctly. Pass "/proc/self/fd/N" to test a file descriptor. -func doTestUtimesNano(t *testing.T, path string) { - utimeTestcases := []utimesTestcaseStruct{ - { - in: [2]syscall.Timespec{{Sec: 50, Nsec: 0}, {Sec: 51, Nsec: 0}}, - out: [2]syscall.Timespec{{Sec: 50, Nsec: 0}, {Sec: 51, Nsec: 0}}, - }, - { - in: [2]syscall.Timespec{{Sec: 1, Nsec: 2}, {Sec: 3, Nsec: 4}}, - out: [2]syscall.Timespec{{Sec: 1, Nsec: 2}, {Sec: 3, Nsec: 4}}, - }, - { - in: [2]syscall.Timespec{{Sec: 7, Nsec: 8}, {Sec: 99, Nsec: _UTIME_OMIT}}, - out: [2]syscall.Timespec{{Sec: 7, Nsec: 8}, {Sec: 3, Nsec: 4}}, - }, - { - in: [2]syscall.Timespec{{Sec: 99, Nsec: _UTIME_OMIT}, {Sec: 5, Nsec: 6}}, - out: [2]syscall.Timespec{{Sec: 7, Nsec: 8}, {Sec: 5, Nsec: 6}}, - }, - } - if runtime.GOOS == "darwin" { - // darwin neither supports UTIME_OMIT nor nanoseconds (!?) - utimeTestcases = utimeTestcases[:1] - } - for i, tc := range utimeTestcases { - err := syscall.UtimesNano(path, tc.in[:]) - if err != nil { - t.Fatalf("%q: %v", path, err) - } - var st syscall.Stat_t - err = syscall.Stat(path, &st) - if err != nil { - t.Fatal(err) - } - want := tc.out - have := extractAtimeMtime(st) - if !compareTimespec(want[0], have[0]) { - t.Errorf("Testcase %d: atime: want=%+v, have=%+v", i, want[0], have[0]) - } - if !compareTimespec(want[1], have[1]) { - t.Errorf("Testcase %d: mtime: want=%+v, have=%+v", i, want[1], have[1]) - } - } -} - -// Set nanoseconds by path, normal file -func TestUtimesNano(t *testing.T) { - path := test_helpers.DefaultPlainDir + "/utimesnano" - err := ioutil.WriteFile(path, []byte("foobar"), 0600) - if err != nil { - t.Fatal(err) - } - doTestUtimesNano(t, path) -} - -// Set nanoseconds by fd -func TestUtimesNanoFd(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skipf("MacOS does not have /proc") - } - path := test_helpers.DefaultPlainDir + "/utimesnanofd" - f, err := os.Create(path) - if err != nil { - t.Fatal(err) - } - defer f.Close() - procPath := fmt.Sprintf("/proc/self/fd/%d", f.Fd()) - doTestUtimesNano(t, procPath) -} - -// Make sure the Mknod call works by creating a fifo (named pipe) -func TestMkfifo(t *testing.T) { - path := test_helpers.DefaultPlainDir + "/fifo1" - err := syscall.Mkfifo(path, 0700) - if err != nil { - t.Fatal(err) - } - path = test_helpers.DefaultPlainDir + "/gocryptfs.longname.XXX" - err = syscall.Mkfifo(path, 0700) - if err != nil { - t.Fatal(err) - } - err = os.Remove(path) - if err != nil { - t.Fatal(err) - } -} - -// TestMagicNames verifies that "magic" names are handled correctly -// https://github.com/rfjakob/gocryptfs/issues/174 -func TestMagicNames(t *testing.T) { - names := []string{"warmup1", "warmup2", "gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs", "gocryptfs.diriv"} - for _, n := range names { - t.Logf("Testing n=%q", n) - p := test_helpers.DefaultPlainDir + "/" + n - // Create file - err := ioutil.WriteFile(p, []byte("xxxxxxx"), 0200) - if err != nil { - t.Fatalf("creating file %q failed: %v", n, err) - } - // Rename magic to normal - err = os.Rename(p, test_helpers.DefaultPlainDir+"/x") - if err != nil { - t.Fatalf("rename 1 failed: %v", err) - } - // Rename normal to magic - err = os.Rename(test_helpers.DefaultPlainDir+"/x", p) - if err != nil { - t.Fatalf("rename 2 failed: %v", err) - } - // Unlink - err = syscall.Unlink(p) - if err != nil { - t.Fatal(err) - } - // Mkdir - err = os.Mkdir(p, 0700) - if err != nil { - t.Fatal(err) - } - // Rmdir - err = syscall.Rmdir(p) - if err != nil { - t.Fatal(err) - } - // Symlink - err = syscall.Symlink("xxxyyyyzzz", p) - if err != nil { - t.Fatal(err) - } - syscall.Unlink(p) - // Link - target := test_helpers.DefaultPlainDir + "/linktarget" - err = ioutil.WriteFile(target, []byte("yyyyy"), 0600) - if err != nil { - t.Fatal(err) - } - err = syscall.Link(target, p) - if err != nil { - t.Fatal(err) - } - } -} - -// Test that chmod works correctly -func TestChmod(t *testing.T) { - path := test_helpers.DefaultPlainDir + "/" + t.Name() - file, err := os.Create(path) - if err != nil { - t.Fatal(err) - } - file.Close() - modes := []os.FileMode{0777, 0707, 0606, 0666, 0444, 0000, 0111, 0123, 0321} - for _, modeWant := range modes { - fi, err := os.Stat(path) - if err != nil { - t.Fatal(err) - } - err = syscall.Chmod(path, uint32(modeWant)) - if err != nil { - t.Errorf("chmod %03o -> %03o failed: %v", fi.Mode(), modeWant, err) - continue - } - fi, err = os.Stat(path) - if err != nil { - t.Fatal(err) - } - modeHave := fi.Mode() - if modeHave != modeWant { - t.Errorf("modeHave %#o != modeWant %#o", modeHave, modeWant) - } - } -} - -// Test that access(2) works correctly -func TestAccess(t *testing.T) { - path := test_helpers.DefaultPlainDir + "/" + t.Name() - file, err := os.Create(path) - if err != nil { - t.Fatal(err) - } - defer file.Close() - - err = unix.Access(path, unix.F_OK) - if err != nil { - t.Error(err) - } - err = unix.Access(path, unix.R_OK) - if err != nil { - t.Error(err) - } - err = unix.Access(path, unix.X_OK) - if err == nil { - t.Error("X_OK should have failed") - } -} - -func TestStatfs(t *testing.T) { - var st syscall.Statfs_t - syscall.Statfs(test_helpers.DefaultPlainDir, &st) - if st.Bsize == 0 { - t.Errorf("statfs reports size zero: %#v", st) - } -} - -// gocryptfs 2.0 reported the ciphertext size on symlink creation, causing -// confusion: https://github.com/rfjakob/gocryptfs/issues/574 -func TestSymlinkSize(t *testing.T) { - p := filepath.Join(test_helpers.DefaultPlainDir, t.Name()) - // SYMLINK reports the size to the kernel - if err := syscall.Symlink("foo", p); err != nil { - t.Fatal(err) - } - // Kernel serves us this value from the attr cache - var st syscall.Stat_t - if err := syscall.Lstat(p, &st); err != nil { - t.Fatal(err) - } - if st.Size != 3 { - t.Errorf("wrong size: have %d, want %d", st.Size, 3) - } -} diff --git a/tests/maxlen.bash b/tests/maxlen.bash deleted file mode 100755 index fb133e0..0000000 --- a/tests/maxlen.bash +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -eu -# -# Find out the maximum supported filename length and print it. -# -# Part of the gocryptfs test suite -# https://nuetzlich.net/gocryptfs/ - -NAME="maxlen." -LEN=0 - -while [ $LEN -le 10000 ]; do - touch $NAME 2> /dev/null || break - rm $NAME - LEN=${#NAME} - NAME="${NAME}x" -done - -echo $LEN diff --git a/tests/plaintextnames/file_holes_test.go b/tests/plaintextnames/file_holes_test.go deleted file mode 100644 index 5de0152..0000000 --- a/tests/plaintextnames/file_holes_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package plaintextnames - -import ( - "fmt" - "math/rand" - "os" - "os/exec" - "syscall" - "testing" - "time" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" - - "github.com/rfjakob/gocryptfs/contrib/findholes/holes" -) - -func findHolesPretty(t *testing.T, path string) string { - f, err := os.Open(path) - if err != nil { - t.Fatal(err) - } - defer f.Close() - - segments, err := holes.Find(int(f.Fd())) - if err != nil { - t.Fatal(err) - } - - return holes.PrettyPrint(segments) -} - -func doTestFileHoleCopy(t *testing.T, name string, writeOffsets []int64) { - n := "TestFileHoleCopy." + name - pPath := []string{pDir + "/" + n} - cPath := []string{cDir + "/" + n} - - os.Remove(pPath[0]) - holes.Create(pPath[0]) - - // expected md6 - md5 := test_helpers.Md5fn(pPath[0]) - - pSegments := []string{findHolesPretty(t, pPath[0])} - cSegments := []string{findHolesPretty(t, cPath[0])} - - // create 5 more copies - for i := 1; i < 5; i++ { - pPath = append(pPath, fmt.Sprintf("%s.%d", pPath[0], i)) - cPath = append(cPath, fmt.Sprintf("%s.%d", cPath[0], i)) - - out, err := exec.Command("cp", "--sparse=auto", pPath[i-1], pPath[i]).CombinedOutput() - if err != nil { - t.Fatal(string(out)) - } - - tmp := test_helpers.Md5fn(pPath[0]) - if tmp != md5 { - t.Errorf("pPath[%d]: wrong md5, have %s, want %s", i, tmp, md5) - } - - pSegments = append(pSegments, findHolesPretty(t, pPath[i])) - cSegments = append(cSegments, findHolesPretty(t, cPath[i])) - } - - // "cp --sparse=auto" checks of the file has fewer blocks on disk than it - // should have for its size. Only then it will try to create a sparse copy. - var st syscall.Stat_t - err := syscall.Stat(pPath[0], &st) - if err != nil { - t.Fatal(err) - } - // convert 512 byte blocks to 4k blocks - blocks4k := st.Blocks / 8 - // For more than a few fragments, ext4 allocates one extra block - blocks4k++ - if blocks4k >= (st.Size+4095)/4096 { - t.Logf("file will look non-sparse to cp, skipping segment check") - return - } - - // Check that size on disk stays the same across copies - var st0 syscall.Stat_t - if err := syscall.Stat(pPath[0], &st0); err != nil { - t.Fatal(err) - } - for i := range pSegments { - var st syscall.Stat_t - if err := syscall.Stat(pPath[i], &st); err != nil { - t.Fatal(err) - } - // Size on disk fluctuates by +-4kB due to different number of extents - // (looking at "filefrag -v", it seems like ext4 needs 4kB extra once - // you have >=4 extents) - if st.Blocks != st0.Blocks && st.Blocks != st0.Blocks-8 && st.Blocks != st0.Blocks+8 { - t.Errorf("size changed: st0.Blocks=%d st%d.Blocks=%d", st0.Blocks, i, st.Blocks) - } - } - - // Check that hole/data segments stays the same across copies - out := "" - same := true - for i := range pSegments { - out += fmt.Sprintf("pSegments[%d]:\n%s\n", i, pSegments[i]) - if i < len(pSegments)-1 { - if pSegments[i+1] != pSegments[i] { - same = false - t.Errorf("error: pSegments[%d] is different than pSegments[%d]!", i, i+1) - } - } - } - out += "------------------------------------\n" - for i := range cSegments { - out += fmt.Sprintf("cSegments[%d]:\n%s\n", i, cSegments[i]) - if i < len(pSegments)-1 { - if cSegments[i+1] != cSegments[i] { - same = false - t.Errorf("error: cSegments[%d] is different than cSegments[%d]!", i, i+1) - } - } - } - if !same { - t.Log(out) - } -} - -// TestFileHoleCopy creates a sparse times, copies it a few times, and check if -// the copies are the same (including the location of holes and data sections). -// -// The test runs with -plaintextnames because that makes it easier to manipulate -// cipherdir directly. -func TestFileHoleCopy(t *testing.T) { - // | hole | x | hole | x | hole | - // truncate -s 50000 foo && dd if=/dev/zero of=foo bs=1 seek=10000 count=1 conv=notrunc && dd if=/dev/zero of=foo bs=1 seek=30000 count=1 conv=notrunc - name := "c0" - c0 := []int64{10000, 30000} - if !t.Run("c0", func(t *testing.T) { doTestFileHoleCopy(t, name, c0) }) { - t.Log("aborting further subtests") - return - } - - rand.Seed(time.Now().UnixNano()) - for k := 0; k < 100; k++ { - c1 := make([]int64, 10) - for i := range c1 { - c1[i] = int64(rand.Int31n(60000)) - } - name := fmt.Sprintf("k%d", k) - if !t.Run(name, func(t *testing.T) { doTestFileHoleCopy(t, name, c1) }) { - t.Log("aborting further subtests") - return - } - } -} diff --git a/tests/plaintextnames/plaintextnames_test.go b/tests/plaintextnames/plaintextnames_test.go deleted file mode 100644 index e3cf953..0000000 --- a/tests/plaintextnames/plaintextnames_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package plaintextnames - -// integration tests that target plaintextnames specifically - -import ( - "fmt" - "io/ioutil" - "os" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/internal/configfile" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var cDir string -var pDir string - -var testPw = []byte("test") - -// Create and mount "-plaintextnames" fs -func TestMain(m *testing.M) { - cDir = test_helpers.InitFS(nil, "-plaintextnames") - pDir = cDir + ".mnt" - test_helpers.MountOrExit(cDir, pDir, "-extpass", "echo test") - r := m.Run() - test_helpers.UnmountPanic(pDir) - os.Exit(r) -} - -// Only the PlaintextNames feature flag should be set -func TestFlags(t *testing.T) { - _, cf, err := configfile.LoadAndDecrypt(cDir+"/gocryptfs.conf", testPw) - if err != nil { - t.Fatal(err) - } - if !cf.IsFeatureFlagSet(configfile.FlagPlaintextNames) { - t.Error("PlaintextNames flag should be set but isn't") - } - if cf.IsFeatureFlagSet(configfile.FlagEMENames) || cf.IsFeatureFlagSet(configfile.FlagDirIV) { - t.Error("FlagEMENames and FlagDirIV should be not set") - } -} - -// gocryptfs.diriv should NOT be created -func TestDirIV(t *testing.T) { - _, err := os.Stat(cDir + "/gocryptfs.diriv") - if err == nil { - t.Errorf("gocryptfs.diriv should not be created in the top directory") - } - err = os.Mkdir(pDir+"/dir1", 0777) - if err != nil { - t.Error(err) - } - _, err = os.Stat(pDir + "/dir1/gocryptfs.diriv") - if err == nil { - t.Errorf("gocryptfs.diriv should not be created in a subdirectory") - } -} - -// With "-plaintextnames", the name "/gocryptfs.conf" is reserved, but everything -// else should work. -func TestFiltered(t *testing.T) { - filteredFile := pDir + "/gocryptfs.conf" - err := ioutil.WriteFile(filteredFile, []byte("foo"), 0777) - if err == nil { - t.Errorf("should have failed but didn't") - } - err = os.Remove(filteredFile) - if err == nil { - t.Errorf("should have failed but didn't") - } - err = ioutil.WriteFile(pDir+"/gocryptfs.diriv", []byte("foo"), 0777) - if err != nil { - t.Error(err) - } - subDir, err := ioutil.TempDir(pDir, "") - if err != nil { - t.Fatal(err) - } - fd, err := os.Create(subDir + "/gocryptfs.conf") - if err != nil { - t.Error(err) - } else { - fd.Close() - } -} - -// TestInoReuseEvil makes it appear that a directory and a file share the -// same inode number. -// Only works on filesystems that recycle inode numbers (ext4 does), -// and then the test causes a hang with these messages: -// -// go-fuse: blocked for 5 seconds waiting for FORGET on i4329366 -// go-fuse: blocked for 11 seconds waiting for FORGET on i4329366 -// go-fuse: blocked for 17 seconds waiting for FORGET on i4329366 -// [...] -// -// The test runs with -plaintextnames because that makes it easier to manipulate -// cipherdir directly. -func TestInoReuseEvil(t *testing.T) { - for i := 0; i < 2; i++ { - n := fmt.Sprintf("%s.%d", t.Name(), i) - pPath := pDir + "/" + n - cPath := cDir + "/" + n - if err := syscall.Mkdir(pPath, 0700); err != nil { - t.Fatal(err) - } - var st syscall.Stat_t - syscall.Stat(pPath, &st) - t.Logf("dir ino = %d", st.Ino) - // delete the dir "behind our back" - if err := syscall.Rmdir(cPath); err != nil { - t.Fatal(err) - } - // create a new file that will likely get the same inode number - pPath2 := pPath + "2" - fd, err := syscall.Creat(pPath2, 0600) - if err != nil { - t.Fatal(err) - } - defer syscall.Close(fd) - syscall.Fstat(fd, &st) - t.Logf("file ino = %d", st.Ino) - } -} diff --git a/tests/reverse/correctness_test.go b/tests/reverse/correctness_test.go deleted file mode 100644 index 9d7a1c8..0000000 --- a/tests/reverse/correctness_test.go +++ /dev/null @@ -1,297 +0,0 @@ -package reverse_test - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "syscall" - "testing" - - "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/ctlsock" - "github.com/rfjakob/gocryptfs/internal/syscallcompat" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -// TestLongnameStat checks that file names of all sizes (1 to 255) show up in -// the decrypted reverse view (dirC, mounted in TestMain). -func TestLongnameStat(t *testing.T) { - for i := 1; i <= 255; i++ { - name := string(bytes.Repeat([]byte("x"), i)) - fd, err := os.Create(dirA + "/" + name) - if err != nil { - t.Fatal(err) - } - fd.Close() - path := dirC + "/" + name - if !test_helpers.VerifyExistence(t, path) { - t.Fatalf("failed to verify %q", path) - } - test_helpers.VerifySize(t, path, 0) - // A large number of longname files is a performance problem in - // reverse mode. Move the file out of the way once we are done with it - // to speed up the test (2 seconds -> 0.2 seconds). - // We do NOT unlink it because ext4 reuses inode numbers immediately, - // which will cause "Found linked inode, but Nlink == 1" warnings and - // file not found errors. - // TODO: This problem should be handled at the go-fuse level. - syscall.Rename(dirA+"/"+name, test_helpers.TmpDir+"/"+fmt.Sprintf("x%d", i)) - } -} - -func TestSymlinks(t *testing.T) { - target := "/" - os.Symlink(target, dirA+"/symlink") - cSymlink := dirC + "/symlink" - _, err := os.Lstat(cSymlink) - if err != nil { - t.Errorf("Lstat: %v", err) - } - _, err = os.Stat(cSymlink) - if err != nil { - t.Errorf("Stat: %v", err) - } - actualTarget, err := os.Readlink(cSymlink) - if err != nil { - t.Fatal(err) - } - if target != actualTarget { - t.Errorf("wrong symlink target: want=%q have=%q", target, actualTarget) - } -} - -// Symbolic link dentry sizes should be set to the length of the string -// that contains the target path. -func TestSymlinkDentrySize(t *testing.T) { - if plaintextnames { - t.Skip("this only tests encrypted names") - } - symlink := "a_symlink" - - mnt, err := ioutil.TempDir(test_helpers.TmpDir, "reverse_mnt_") - if err != nil { - t.Fatal(err) - } - - sock := mnt + ".sock" - test_helpers.MountOrFatal(t, "ctlsock_reverse_test_fs", mnt, "-reverse", "-extpass", "echo test", "-ctlsock="+sock) - defer test_helpers.UnmountPanic(mnt) - - req := ctlsock.RequestStruct{EncryptPath: symlink} - symlinkResponse := test_helpers.QueryCtlSock(t, sock, req) - if symlinkResponse.ErrNo != 0 { - t.Errorf("Encrypt: %q ErrNo=%d ErrText=%s", symlink, symlinkResponse.ErrNo, symlinkResponse.ErrText) - } - - fi, err := os.Lstat(mnt + "/" + symlinkResponse.Result) - if err != nil { - t.Fatalf("Lstat: %v", err) - } - - target, err := os.Readlink(mnt + "/" + symlinkResponse.Result) - if err != nil { - t.Errorf("Readlink: %v", err) - } - - if fi.Size() != int64(len(target)) { - t.Errorf("Lstat reports that symbolic link %q's dentry size is %d, but this does not "+ - "match the length of the string returned by readlink, which is %d.", - symlink, fi.Size(), len(target)) - } -} - -// .gocryptfs.reverse.conf in the plaintext dir should be visible as -// gocryptfs.conf -func TestConfigMapping(t *testing.T) { - c := dirB + "/gocryptfs.conf" - if !test_helpers.VerifyExistence(t, c) { - t.Errorf("%s missing", c) - } - data, err := ioutil.ReadFile(c) - if err != nil { - t.Fatal(err) - } - if len(data) == 0 { - t.Errorf("empty file") - } -} - -// Check that the access() syscall works on virtual files -func TestAccessVirtual(t *testing.T) { - if plaintextnames { - t.Skip("test makes no sense for plaintextnames") - } - var R_OK uint32 = 4 - var W_OK uint32 = 2 - var X_OK uint32 = 1 - fn := dirB + "/gocryptfs.diriv" - err := syscall.Access(fn, R_OK) - if err != nil { - t.Errorf("%q should be readable, but got error: %v", fn, err) - } - err = syscall.Access(fn, W_OK) - if err == nil { - t.Errorf("should NOT be writeable") - } - err = syscall.Access(fn, X_OK) - if err == nil { - t.Errorf("should NOT be executable") - } -} - -// Check that the access() syscall works on regular files -func TestAccess(t *testing.T) { - f, err := os.Create(dirA + "/testaccess1") - if err != nil { - t.Fatal(err) - } - f.Close() - f, err = os.Open(dirB) - if err != nil { - t.Fatal(err) - } - defer f.Close() - names, err := f.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - for _, n := range names { - // Check if file exists - this should never fail - err = syscallcompat.Faccessat(unix.AT_FDCWD, dirB+"/"+n, unix.F_OK) - if err != nil { - t.Errorf("%s: %v", n, err) - } - // Check if file is readable - err = syscallcompat.Faccessat(unix.AT_FDCWD, dirB+"/"+n, unix.R_OK) - if err != nil { - t.Logf("%s: %v", n, err) - } - } -} - -// Opening a nonexistent file name should return ENOENT -// and not EBADMSG or EIO or anything else. -func TestEnoent(t *testing.T) { - fn := dirB + "/TestEnoent" - _, err := syscall.Open(fn, syscall.O_RDONLY, 0) - if err != syscall.ENOENT { - t.Errorf("want ENOENT, got: %v", err) - } -} - -// If the symlink target gets too long due to base64 encoding, we should -// return ENAMETOOLONG instead of having the kernel reject the data and -// returning an I/O error to the user. -// https://github.com/rfjakob/gocryptfs/issues/167 -func TestTooLongSymlink(t *testing.T) { - var err error - var l int - fn := dirA + "/TooLongSymlink" - // Try 4000 first (works on ext4 and tmpfs), then retry with 1000 (XFS and - // Darwin have a limit of about 1024) - for _, l = range []int{4000, 1000} { - target := string(bytes.Repeat([]byte("x"), l)) - err = os.Symlink(target, fn) - if err == nil { - break - } - } - if err != nil { - t.Fatal(err) - } - // save later tests the trouble of dealing with ENAMETOOLONG errors - defer func() { - os.Remove(fn) - // immediately create a new symlink so the inode number is not - // reused for something else - os.Symlink("/tmp", fn) - }() - t.Logf("Created symlink of length %d", l) - _, err = os.Readlink(dirC + "/TooLongSymlink") - if err == nil { - return - } - err2 := err.(*os.PathError) - if err2.Err != syscall.ENAMETOOLONG { - t.Errorf("Expected %q error, got %q instead", syscall.ENAMETOOLONG, - err2.Err) - } -} - -// Test that we can traverse a directory with 0100 permissions -// (execute but no read). This used to be a problem as OpenDirNofollow opened -// all directories in the path with O_RDONLY. Now it uses O_PATH, which only needs -// the executable bit. -func Test0100Dir(t *testing.T) { - dir := dirA + "/" + t.Name() - err := os.Mkdir(dir, 0700) - if err != nil { - t.Fatal(err) - } - file := dir + "/hello" - err = ioutil.WriteFile(file, []byte("hello"), 0600) - if err != nil { - t.Fatal(err) - } - err = os.Chmod(dir, 0100) - if err != nil { - t.Fatal(err) - } - - fileReverse := dirC + "/" + t.Name() + "/hello" - fd, err := os.Open(fileReverse) - // Make sure the dir can be removed after the test is done - os.Chmod(dir, 0700) - if err != nil { - t.Fatal(err) - } - fd.Close() -} - -func TestStatfs(t *testing.T) { - var st syscall.Statfs_t - syscall.Statfs(dirB, &st) - if st.Bsize == 0 { - t.Errorf("statfs reports size zero: %#v", st) - } -} - -// TestSeekData tests that fs.FileLseeker is implemented -func TestSeekData(t *testing.T) { - if !plaintextnames { - t.Skip() - } - - fn := filepath.Join(dirA, t.Name()) - f, err := os.Create(fn) - if err != nil { - t.Fatal(err) - } - var oneTiB int64 = 1024 * 1024 * 1024 * 1024 - if _, err = f.Seek(oneTiB, 0); err != nil { - t.Fatal(err) - } - if _, err = f.Write([]byte("foo")); err != nil { - t.Fatal(err) - } - f.Close() - - const SEEK_DATA = 3 - - fn2 := filepath.Join(dirB, t.Name()) - f, err = os.Open(fn2) - if err != nil { - t.Fatal(err) - } - off, err := f.Seek(1024*1024, SEEK_DATA) - if err != nil { - t.Fatal(err) - } - if off < oneTiB-1024*1024 { - t.Errorf("off=%d, expected=%d\n", off, oneTiB) - } - f.Close() -} diff --git a/tests/reverse/ctlsock_reverse_test_fs/.gocryptfs.reverse.conf b/tests/reverse/ctlsock_reverse_test_fs/.gocryptfs.reverse.conf deleted file mode 100644 index 9bd9259..0000000 --- a/tests/reverse/ctlsock_reverse_test_fs/.gocryptfs.reverse.conf +++ /dev/null @@ -1,19 +0,0 @@ -{ - "Creator": "gocryptfs v1.1.1-16-g75ebb28-dirty", - "EncryptedKey": "cE5bhCZl1iL1tn0dNLh8aQy8n55NMbojmmkwM8iM8/y0uChO0CGaK16sNHffAKJ++qH287JlCpk/BFyi", - "ScryptObject": { - "Salt": "yUxEmtl4KeUkCxL8b6aYcEGVtFe2NAlwy0WsFLt8p+Y=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "DirIV", - "EMENames", - "LongNames", - "AESSIV" - ] -} diff --git a/tests/reverse/ctlsock_reverse_test_fs/a_symlink b/tests/reverse/ctlsock_reverse_test_fs/a_symlink deleted file mode 120000 index 06ed148..0000000 --- a/tests/reverse/ctlsock_reverse_test_fs/a_symlink +++ /dev/null @@ -1 +0,0 @@ -dir/dir/file \ No newline at end of file diff --git a/tests/reverse/ctlsock_reverse_test_fs/dir/dir/file b/tests/reverse/ctlsock_reverse_test_fs/dir/dir/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_reverse_test_fs/dir/file b/tests/reverse/ctlsock_reverse_test_fs/dir/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_reverse_test_fs/dir/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/ctlsock_reverse_test_fs/dir/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_reverse_test_fs/file b/tests/reverse/ctlsock_reverse_test_fs/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_reverse_test_fs/longdir.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file b/tests/reverse/ctlsock_reverse_test_fs/longdir.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_reverse_test_fs/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/ctlsock_reverse_test_fs/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/ctlsock_test.go b/tests/reverse/ctlsock_test.go deleted file mode 100644 index ecb0b96..0000000 --- a/tests/reverse/ctlsock_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package reverse_test - -import ( - "io/ioutil" - "syscall" - "testing" - - "github.com/rfjakob/gocryptfs/ctlsock" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var ctlSockTestCases = [][]string{ - {"4RQq1dJlfvQPaVU5Xypf0w==", "file"}, - {"gocryptfs.longname.ZQCAoi5li3xvDZRO8McBV0L_kzJc4IcAOEzuW-2S1Y4=", "longfile." + x240}, - {"v6puXntoQOk7Mhl8zJ4Idg==", "dir"}, - {"v6puXntoQOk7Mhl8zJ4Idg==/UVy2gV0RQTUC8AE4wYoMwg==", "dir/file"}, - {"v6puXntoQOk7Mhl8zJ4Idg==/fvHFLHlxHCQ7EpVMJu0AZg==", "dir/dir"}, - {"v6puXntoQOk7Mhl8zJ4Idg==/fvHFLHlxHCQ7EpVMJu0AZg==/_4uudIGniACke55JoDsqDA==", "dir/dir/dir"}, - {"v6puXntoQOk7Mhl8zJ4Idg==/fvHFLHlxHCQ7EpVMJu0AZg==/QvPahkkeVRKTw2kdZFZxwQ==", "dir/dir/file"}, - {"v6puXntoQOk7Mhl8zJ4Idg==/gocryptfs.longname.y6rxCn6Id8hIZL2t_STpdLZpu-aE2HpprJR25xD60mk=", "dir/longfile." + x240}, - {"gocryptfs.longname.cvRximo1ATRJVEzw_V9MZieHFlod9y2iv2Sug1kbiTE=", "longdir." + x240}, - {"gocryptfs.longname.cvRximo1ATRJVEzw_V9MZieHFlod9y2iv2Sug1kbiTE=/-LMdFgFt6UxO-z5iJvuC9w==", "longdir." + x240 + "/dir"}, - {"gocryptfs.longname.cvRximo1ATRJVEzw_V9MZieHFlod9y2iv2Sug1kbiTE=/rBPJYAzcHWLdPj1T8kgh8A==", "longdir." + x240 + "/file"}, -} - -// Test DecryptPath and EncryptPath -func TestCtlSockPathOps(t *testing.T) { - if plaintextnames { - t.Skip("this only tests encrypted names") - } - mnt, err := ioutil.TempDir(test_helpers.TmpDir, "reverse_mnt_") - if err != nil { - t.Fatal(err) - } - sock := mnt + ".sock" - test_helpers.MountOrFatal(t, "ctlsock_reverse_test_fs", mnt, "-reverse", "-extpass", "echo test", "-ctlsock="+sock) - defer test_helpers.UnmountPanic(mnt) - var req ctlsock.RequestStruct - var response ctlsock.ResponseStruct - for i, tc := range ctlSockTestCases { - // Decrypt - req = ctlsock.RequestStruct{DecryptPath: tc[0]} - response = test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != 0 { - t.Errorf("Testcase %d Decrypt: %q ErrNo=%d ErrText=%s", i, tc[0], response.ErrNo, response.ErrText) - } else if response.Result != tc[1] { - t.Errorf("Testcase %d Decrypt: Want %q got %q", i, tc[1], response.Result) - } - // Encrypt - req = ctlsock.RequestStruct{EncryptPath: tc[1]} - response = test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != 0 { - t.Errorf("Testcase %d Encrypt: %q ErrNo=%d ErrText=%s", i, tc[0], response.ErrNo, response.ErrText) - } else if response.Result != tc[0] { - t.Errorf("Testcase %d Encrypt: Want %q got %q", i, tc[1], response.Result) - } - } - // At this point the longname parent cache should be populated. - // Check that we do not mix up information for different directories. - req = ctlsock.RequestStruct{DecryptPath: "gocryptfs.longname.y6rxCn6Id8hIZL2t_STpdLZpu-aE2HpprJR25xD60mk="} - response = test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != int32(syscall.ENOENT) { - t.Errorf("File should not exist: ErrNo=%d ErrText=%s", response.ErrNo, response.ErrText) - } - req = ctlsock.RequestStruct{DecryptPath: "v6puXntoQOk7Mhl8zJ4Idg==/gocryptfs.longname.ZQCAoi5li3xvDZRO8McBV0L_kzJc4IcAOEzuW-2S1Y4="} - response = test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != int32(syscall.ENOENT) { - t.Errorf("File should not exist: ErrNo=%d ErrText=%s", response.ErrNo, response.ErrText) - } -} - -// We should not panic when somebody feeds requests that make no sense -func TestCtlSockCrash(t *testing.T) { - if plaintextnames { - t.Skip("this only tests encrypted names") - } - mnt, err := ioutil.TempDir(test_helpers.TmpDir, "reverse_mnt_") - if err != nil { - t.Fatal(err) - } - sock := mnt + ".sock" - test_helpers.MountOrFatal(t, "ctlsock_reverse_test_fs", mnt, "-reverse", "-extpass", "echo test", "-ctlsock="+sock, - "-wpanic=0", "-nosyslog=0") - defer test_helpers.UnmountPanic(mnt) - // Try to crash it - req := ctlsock.RequestStruct{DecryptPath: "gocryptfs.longname.XXX_TestCtlSockCrash_XXX.name"} - test_helpers.QueryCtlSock(t, sock, req) -} diff --git a/tests/reverse/exclude_test.go b/tests/reverse/exclude_test.go deleted file mode 100644 index c493d95..0000000 --- a/tests/reverse/exclude_test.go +++ /dev/null @@ -1,157 +0,0 @@ -package reverse_test - -import ( - "io/ioutil" - "path/filepath" - "testing" - - "github.com/rfjakob/gocryptfs/ctlsock" - "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -const xxx = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -/* -tree exclude_test_fs -exclude_test_fs/ -├── bkp1~ -├── dir1 -│ ├── file1 -│ ├── file2 -│ ├── exclude -│ ├── longbkp1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx~ -│ ├── longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ ├── longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ ├── longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ └── subdir1 -│ ├── exclude -│ └── subdir2 -│ └── exclude -├── dir2 -│ ├── file -│ ├── longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ │ └── file -│ ├── longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ └── subdir -│ └── file -├── file1 -├── file2 -├── longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ └── file1 -├── longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -│ ├── bkp~ -│ └── file -├── longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -├── longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -└── longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -*/ - -func ctlsockEncryptPath(t *testing.T, sock string, path string) string { - req := ctlsock.RequestStruct{EncryptPath: path} - response := test_helpers.QueryCtlSock(t, sock, req) - if response.ErrNo != 0 { - t.Fatal(response) - } - return response.Result -} - -func testExclude(t *testing.T, flag string) { - pPatterns := []string{ - "file1", // matches file1 anywhere - "!longdir1" + xxx + "/file1", // ! includes an otherwise file - "file2/", // a trailing slash matches only a directory - "dir1/file2", // matches file2 inside dir1 anywhere - "#file2", // comments are ignored - "dir2", // excludes the whole directory - "longfile2" + xxx, // matches longfile2 anywhere - "/longfile3" + xxx, // a leading / anchors the match at the root - "*~", // wildcards are supported - "dir1/**/exclude", // ** matches any number of directories - } - pOk := []string{ - "file2", - "dir1/longfile1" + xxx, - "dir1/longfile3" + xxx, - "longdir1" + xxx, - "longdir1" + xxx + "/file1", - "longdir2" + xxx + "/file", - "longfile1" + xxx, - } - pExclude := []string{ - "bkp1~", - "dir1/file1", - "dir1/file2", - "dir1/exclude", - "dir1/longbkp1" + xxx + "~", - "dir1/longfile2" + xxx, - "dir1/subdir1/exclude", - "dir1/subdir1/subdir2/exclude", - "dir2", - "dir2/file", - "dir2/longdir1" + xxx + "/file", - "dir2/longfile." + xxx, - "dir2/subdir", - "dir2/subdir/file", - "file1", - "longdir2" + xxx + "/bkp~", - "longfile2" + xxx, - "longfile3" + xxx, - } - // Mount reverse fs - mnt, err := ioutil.TempDir(test_helpers.TmpDir, "TestExclude") - if err != nil { - t.Fatal(err) - } - sock := mnt + ".sock" - cliArgs := []string{"-reverse", "-extpass", "echo test", "-ctlsock", sock} - for _, v := range pPatterns { - cliArgs = append(cliArgs, flag, v) - } - if plaintextnames { - cliArgs = append(cliArgs, "-config", "exclude_test_fs/.gocryptfs.reverse.conf.plaintextnames") - } - test_helpers.MountOrFatal(t, "exclude_test_fs", mnt, cliArgs...) - defer test_helpers.UnmountPanic(mnt) - // Get encrypted version of "ok" and "excluded" paths - cOk := encryptExcludeTestPaths(t, sock, pOk) - cExclude := encryptExcludeTestPaths(t, sock, pExclude) - // Check that "excluded" paths are not there and "ok" paths are there - for _, v := range cExclude { - t.Logf("File %q should be invisible", v) - if test_helpers.VerifyExistence(t, mnt+"/"+v) { - t.Errorf("File %q is visible, but should be excluded", v) - } - if nametransform.IsLongContent(filepath.Base(v)) { - - } - } - for _, v := range cOk { - t.Logf("File %q should be visible", v) - if !test_helpers.VerifyExistence(t, mnt+"/"+v) { - t.Errorf("File %q is hidden, but should be visible", v) - } - } -} - -// encryptExcludeTestPaths is used by testExclude() to encrypt the lists of -// testcase paths -func encryptExcludeTestPaths(t *testing.T, socket string, pRelPaths []string) (out []string) { - for _, pRelPath := range pRelPaths { - cRelPath := ctlsockEncryptPath(t, socket, pRelPath) - out = append(out, cRelPath) - if !plaintextnames && nametransform.IsLongContent(filepath.Base(cRelPath)) { - // If we exclude - // gocryptfs.longname.3vZ_r3eDPb1_fL3j5VA4rd_bcKWLKT9eaxOVIGK5HFA - // we should also exclude - // gocryptfs.longname.3vZ_r3eDPb1_fL3j5VA4rd_bcKWLKT9eaxOVIGK5HFA.name - out = append(out, cRelPath+nametransform.LongNameSuffix) - } - } - return out -} - -func TestExclude(t *testing.T) { - testExclude(t, "-exclude-wildcard") - testExclude(t, "-ew") -} diff --git a/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf b/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf deleted file mode 100644 index 835d11c..0000000 --- a/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Creator": "gocryptfs v1.5-41-gf48b731-dirty", - "EncryptedKey": "FkACqloUeFZesem0UzRD3ezLXtPl8wIAxEHoIEfZxFdLMQeWOxqtw5xopJagDWE/GI1VFSUIrJIIIwwgMipmYA==", - "ScryptObject": { - "Salt": "UVfIgV31uj/voHWI4GqGwsTcbVKyYDOWvbleqJKhZbk=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "DirIV", - "EMENames", - "LongNames", - "Raw64", - "AESSIV" - ] -} diff --git a/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf.plaintextnames b/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf.plaintextnames deleted file mode 100644 index 9cb762c..0000000 --- a/tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf.plaintextnames +++ /dev/null @@ -1,18 +0,0 @@ -{ - "Creator": "gocryptfs v1.5-41-gf48b731-dirty", - "EncryptedKey": "wAmckZb7QsIv/GCdkhb5ep8TwJa44qhnswn5tbER6Tifk8TbUmkwBTceaTtYfHAnTQ48q9mnIlcN9cfbNe5oPw==", - "ScryptObject": { - "Salt": "o5XJ78TgG85zZXRnU55ZqHhKLbPge6jsyDiqrLvSqe0=", - "N": 1024, - "R": 8, - "P": 1, - "KeyLen": 32 - }, - "Version": 2, - "FeatureFlags": [ - "GCMIV128", - "HKDF", - "PlaintextNames", - "AESSIV" - ] -} diff --git a/tests/reverse/exclude_test_fs/bkp1~ b/tests/reverse/exclude_test_fs/bkp1~ deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/exclude b/tests/reverse/exclude_test_fs/dir1/exclude deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/file1 b/tests/reverse/exclude_test_fs/dir1/file1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/file2 b/tests/reverse/exclude_test_fs/dir1/file2 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/longbkp1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx~ b/tests/reverse/exclude_test_fs/dir1/longbkp1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx~ deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/dir1/longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/dir1/longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/dir1/longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/subdir1/exclude b/tests/reverse/exclude_test_fs/dir1/subdir1/exclude deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir1/subdir1/subdir2/exclude b/tests/reverse/exclude_test_fs/dir1/subdir1/subdir2/exclude deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir2/file b/tests/reverse/exclude_test_fs/dir2/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir2/longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file b/tests/reverse/exclude_test_fs/dir2/longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir2/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/dir2/longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/dir2/subdir/file b/tests/reverse/exclude_test_fs/dir2/subdir/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/file1 b/tests/reverse/exclude_test_fs/file1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/file2 b/tests/reverse/exclude_test_fs/file2 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file1 b/tests/reverse/exclude_test_fs/longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/bkp~ b/tests/reverse/exclude_test_fs/longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/bkp~ deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file b/tests/reverse/exclude_test_fs/longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/file deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/exclude_test_fs/longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx b/tests/reverse/exclude_test_fs/longfile3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx deleted file mode 100644 index e69de29..0000000 diff --git a/tests/reverse/inomap_test.go b/tests/reverse/inomap_test.go deleted file mode 100644 index e6fc525..0000000 --- a/tests/reverse/inomap_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package reverse_test - -import ( - "bytes" - "os" - "strings" - "syscall" - "testing" -) - -// findIno looks for the file having inode number `ino` in `dir`. -// Returns "" if not found. -func findIno(dir string, ino uint64) string { - fd, err := os.Open(dir) - if err != nil { - return "" - } - dirents, err := fd.Readdirnames(0) - if err != nil { - return "" - } - fd.Close() - for _, entry := range dirents { - var st syscall.Stat_t - err = syscall.Lstat(dir+"/"+entry, &st) - if err != nil { - continue - } - if ino == st.Ino { - return entry - } - } - return "" -} - -// TestVirtualFileIno creates a directory tree like this: -// -// TestVirtualFileIno <---- parent -// └── xxxxxxx[...] <---- child -// -// Which looks like this encrypted: -// -// OLUKdPMg6l87EiKVlufgwIkQL8MD6JdUgOR3a8nEZ-w <---- parent -// ├── gocryptfs.diriv <---- diriv -// ├── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50 <---- child -// └── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50.name <---- name -// -// It verifies that the inode numbers match what we expect. -func TestVirtualFileIno(t *testing.T) { - if plaintextnames { - t.Skip("plaintextnames mode does not have virtual files") - } - - type inoTable struct { - parent uint64 - diriv uint64 - child uint64 - name uint64 - } - var origInos inoTable - var cipherInos inoTable - - parent := dirA + "/TestVirtualFileIno" - name := string(bytes.Repeat([]byte("x"), 240)) - err := os.MkdirAll(parent+"/"+name, 0700) - if err != nil { - t.Fatal(err) - } - var st syscall.Stat_t - err = syscall.Lstat(parent+"/"+name, &st) - if err != nil { - t.Fatal(err) - } - origInos.child = st.Ino - // get inode number of plain parent - err = syscall.Lstat(parent, &st) - if err != nil { - t.Fatal(err) - } - origInos.parent = st.Ino - // find it in encrypted `dirB` - fd, err := os.Open(dirB) - if err != nil { - t.Fatal(err) - } - dirents, err := fd.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - fd.Close() - encryptedParent := findIno(dirB, origInos.parent) - if encryptedParent == "" { - t.Fatalf("could not find ino %d in %q", origInos.parent, dirB) - } - encryptedParent = dirB + "/" + encryptedParent - err = syscall.Stat(encryptedParent, &st) - if err != nil { - t.Fatal(err) - } - cipherInos.parent = st.Ino - fd, err = os.Open(encryptedParent) - if err != nil { - t.Fatal(err) - } - dirents, err = fd.Readdirnames(0) - if err != nil { - t.Fatal(err) - } - fd.Close() - for _, entry := range dirents { - var st2 syscall.Stat_t - err = syscall.Lstat(encryptedParent+"/"+entry, &st2) - if err != nil { - t.Errorf("stat %q: %v", entry, err) - continue - } - if entry == "gocryptfs.diriv" { - cipherInos.diriv = st2.Ino - } else if strings.HasSuffix(entry, ".name") { - cipherInos.name = st2.Ino - } else { - cipherInos.child = st2.Ino - } - } - if origInos.parent != cipherInos.parent { - t.Errorf("parent ino mismatch: %d != %d", origInos.parent, cipherInos.parent) - } - if origInos.parent == cipherInos.diriv { - t.Errorf("diriv ino collision: %d == %d", origInos.parent, cipherInos.diriv) - } - // Lower 48 bits should come from the backing file - const mask = 0xffffffffffff - if origInos.parent&mask != cipherInos.diriv&mask { - t.Errorf("diriv ino mismatch: %#x vs %#x", origInos.parent, cipherInos.diriv) - } - if origInos.child != cipherInos.child { - t.Errorf("child ino mismatch: %d vs %d", origInos.child, cipherInos.child) - } - if origInos.child == cipherInos.name { - t.Errorf("name ino collision: %d == %d", origInos.child, cipherInos.name) - } - if origInos.child&mask != cipherInos.name&mask { - t.Errorf("name ino mismatch: %#x vs %#x", origInos.child, cipherInos.name) - } -} diff --git a/tests/reverse/linux-tarball-test.bash b/tests/reverse/linux-tarball-test.bash deleted file mode 100755 index 26bbb6c..0000000 --- a/tests/reverse/linux-tarball-test.bash +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -eu - -cd "$(dirname "$0")" -MD5="$PWD/../stress_tests/linux-3.0.md5sums" -MYNAME=$(basename "$0") -source ../fuse-unmount.bash - -# Setup dirs -../dl-linux-tarball.bash -cd /tmp -WD=$(mktemp -d /tmp/$MYNAME.XXX) - -# Cleanup trap -trap "set +u; cd /; fuse-unmount -z $WD/c; fuse-unmount -z $WD/b; rm -rf $WD" EXIT - -cd $WD -mkdir a b c -echo "Extracting tarball" -tar -x -f /tmp/linux-3.0.tar.gz -C a -echo "Mounting a -> b -> c chain" -# Init "a" -gocryptfs -q -extpass="echo test" -reverse -init -scryptn=10 a -# Reverse-mount "a" on "b" -gocryptfs -q -extpass="echo test" -reverse a b -# Forward-mount "b" on "c" -gocryptfs -q -extpass="echo test" b c -# Check md5 sums -cd c -echo "Checking md5 sums" -set -o pipefail -md5sum -c $MD5 | pv -l -s 36782 -N "files checked" | (grep -v ": OK" || true) diff --git a/tests/reverse/longname_perf_test.go b/tests/reverse/longname_perf_test.go deleted file mode 100644 index 1707cea..0000000 --- a/tests/reverse/longname_perf_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package reverse_test - -import ( - "fmt" - "os" - "testing" -) - -func genName(i int, postfix string) string { - return fmt.Sprintf("%04d.%s", i, postfix) -} - -// Create 10000 files with long names -func generateLongnameFiles(dir string) { - for i := 0; i < 100000; i++ { - n := genName(i, x240) - f, err := os.Create(dir + "/" + n) - if err != nil { - panic(err) - } - f.Close() - } -} - -func BenchmarkLongnameStat(b *testing.B) { - // Setup - generateLongnameFiles(dirA) - dirFd, err := os.Open(dirB) - if err != nil { - b.Fatal(err) - } - encryptedNames, err := dirFd.Readdirnames(-1) - if err != nil { - b.Fatal(err) - } - l := len(encryptedNames) - dirFd.Close() - // Benchmark - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := os.Stat(dirB + "/" + encryptedNames[i%l]) - if err != nil { - b.Fatal(err) - } - } - // Cleanup - b.StopTimer() - os.RemoveAll(dirA) - os.Mkdir(dirA, 0700) -} diff --git a/tests/reverse/main_test.go b/tests/reverse/main_test.go deleted file mode 100644 index 3425289..0000000 --- a/tests/reverse/main_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package reverse_test - -import ( - "bytes" - "os" - "testing" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var x240 = string(bytes.Repeat([]byte("x"), 240)) -var plaintextnames bool - -// dirA is a normal directory -var dirA string - -// dirB is the reverse mount backed by dirA -var dirB string - -// dirC is a forward mount backed by dirB -var dirC string - -// Create directory "dirA", mount it reverse to "dirB", mount it forward -// to "dirC". -func TestMain(m *testing.M) { - var r int - for _, plaintextnames = range []bool{false, true} { - argsA := []string{"-reverse"} - if plaintextnames { - argsA = append(argsA, "-plaintextnames") - } - dirA = test_helpers.InitFS(nil, argsA...) - dirB = test_helpers.TmpDir + "/b" - dirC = test_helpers.TmpDir + "/c" - if err := os.Mkdir(dirB, 0700); err != nil { - panic(err) - } - if err := os.Mkdir(dirC, 0700); err != nil { - panic(err) - } - test_helpers.MountOrExit(dirA, dirB, "-reverse", "-extpass", "echo test") - test_helpers.MountOrExit(dirB, dirC, "-extpass", "echo test") - r = m.Run() - test_helpers.UnmountPanic(dirC) - test_helpers.UnmountPanic(dirB) - - os.RemoveAll(dirA) - os.RemoveAll(dirB) - os.RemoveAll(dirC) - - if r != 0 { - os.Exit(r) - } - } - os.Exit(r) -} diff --git a/tests/reverse/xattr_test.go b/tests/reverse/xattr_test.go deleted file mode 100644 index 8002604..0000000 --- a/tests/reverse/xattr_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package reverse_test - -import ( - "fmt" - "io/ioutil" - "path/filepath" - "syscall" - "testing" - - "github.com/pkg/xattr" -) - -func xattrSupported(path string) bool { - _, err := xattr.LGet(path, "user.xattrSupported-dummy-value") - if err == nil { - return true - } - err2 := err.(*xattr.Error) - if err2.Err == syscall.EOPNOTSUPP { - return false - } - return true -} - -func TestXattrList(t *testing.T) { - t.Skip("TODO: not implemented yet in reverse mode") - - if !xattrSupported(dirA) { - t.Skip() - } - fnA := filepath.Join(dirA, t.Name()) - err := ioutil.WriteFile(fnA, nil, 0700) - if err != nil { - t.Fatalf("creating empty file failed: %v", err) - } - val := []byte("xxxxxxxxyyyyyyyyyyyyyyyzzzzzzzzzzzzz") - num := 20 - var namesA map[string]string - for i := 1; i <= num; i++ { - attr := fmt.Sprintf("user.TestXattrList.%02d", i) - err = xattr.LSet(fnA, attr, val) - if err != nil { - t.Fatal(err) - } - namesA[attr] = string(val) - } - fnC := filepath.Join(dirC, t.Name()) - tmp, err := xattr.LList(fnC) - if err != nil { - t.Fatal(err) - } - var namesC map[string]string - for _, n := range tmp { - namesC[n] = string(val) - } - if len(namesA) != len(namesC) { - t.Errorf("wrong number of names, want=%d have=%d", len(namesA), len(namesC)) - } - for i := range namesC { - valA := namesA[i] - valC := namesC[i] - if valC != valA { - t.Errorf("mismatch on attr %q: valA = %q, valC = %q", i, valA, valC) - } - } -} diff --git a/tests/root_test/root_test.go b/tests/root_test/root_test.go deleted file mode 100644 index 8547e4e..0000000 --- a/tests/root_test/root_test.go +++ /dev/null @@ -1,313 +0,0 @@ -// Package root_test contains tests that need root -// permissions to run -package root_test - -import ( - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "sync" - "syscall" - "testing" - - "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -func asUser(uid int, gid int, supplementaryGroups []int, f func() error) error { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err := unix.Setgroups(supplementaryGroups) - if err != nil { - return err - } - defer func() { - err = unix.Setgroups(nil) - if err != nil { - panic(err) - } - }() - err = unix.Setregid(-1, gid) - if err != nil { - return err - } - defer func() { - err = unix.Setregid(-1, 0) - if err != nil { - panic(err) - } - }() - err = unix.Setreuid(-1, uid) - if err != nil { - return err - } - defer func() { - err = unix.Setreuid(-1, 0) - if err != nil { - panic(err) - } - }() - - ret := f() - - // Also reset the saved user id (suid) and saved group id (sgid) to prevent - // bizarre failures in later tests. - // - // Yes, the kernel checks that *all of them* match: - // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/dir.c?h=v5.12-rc2#n1193 - // - // How to check: - // ps -o tid,pid,euid,ruid,suid,egid,rgid,sgid,cmd -eL - err = unix.Setresuid(0, 0, 0) - if err != nil { - panic(err) - } - err = unix.Setresgid(0, 0, 0) - if err != nil { - panic(err) - } - - return ret -} - -func TestSupplementaryGroups(t *testing.T) { - if os.Getuid() != 0 { - t.Skip("must run as root") - } - cDir := test_helpers.InitFS(t) - os.Chmod(cDir, 0755) - pDir := cDir + ".mnt" - test_helpers.MountOrFatal(t, cDir, pDir, "-allow_other", "-extpass=echo test") - defer test_helpers.UnmountPanic(pDir) - - // We need an unrestricted umask - syscall.Umask(0000) - - dir1 := pDir + "/dir1" - err := os.Mkdir(dir1, 0770) - if err != nil { - t.Fatal(err) - } - err = os.Chown(dir1, 0, 1234) - if err != nil { - t.Fatal(err) - } - - err = asUser(1235, 1235, []int{1234}, func() error { return os.Mkdir(dir1+"/dir2", 0700) }) - if err != nil { - t.Error(err) - } - - err = asUser(1235, 1235, []int{1234}, func() error { - f, err := os.Create(dir1 + "/file1") - if err == nil { - f.Close() - } - return err - }) - if err != nil { - t.Error(err) - } -} - -func writeTillFull(t *testing.T, path string) (int, syscall.Errno) { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - fd, err := syscall.Creat(path, 0600) - if err != nil { - return 0, err.(syscall.Errno) - } - defer syscall.Close(fd) - // Write in 100.000 byte-blocks, which is not aligend to the - // underlying block size - buf := make([]byte, 100000) - var sz int - for { - n, err := syscall.Write(fd, buf) - if err != nil { - return sz, err.(syscall.Errno) - } - sz += n - } - return sz, 0 -} - -// TestDiskFull needs root permissions because it creates a loop disk -func TestDiskFull(t *testing.T) { - if os.Getuid() != 0 { - t.Skip("must run as root") - } - - // Create 10 MB file full of zeros - ext4img := filepath.Join(test_helpers.TmpDir, t.Name()+".ext4") - f, err := os.Create(ext4img) - if err != nil { - t.Fatal(err) - } - defer f.Close() - err = f.Truncate(10 * 1024 * 1024) - if err != nil { - t.Fatal(err) - } - - // Format as ext4 - cmd := exec.Command("mkfs.ext4", ext4img) - out, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - // Mount ext4 - ext4mnt := ext4img + ".mnt" - err = os.Mkdir(ext4mnt, 0600) - if err != nil { - t.Fatal(err) - } - cmd = exec.Command("mount", ext4img, ext4mnt) - out, err = cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Fatal(err) - } - defer syscall.Unlink(ext4img) - defer syscall.Unmount(ext4mnt, 0) - - // gocryptfs -init - cipherdir := ext4mnt + "/a" - if err = os.Mkdir(cipherdir, 0600); err != nil { - t.Fatal(err) - } - cmd = exec.Command(test_helpers.GocryptfsBinary, "-q", "-init", "-extpass", "echo test", "-scryptn=10", cipherdir) - out, err = cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - // Mount gocryptfs - mnt := ext4mnt + "/b" - test_helpers.MountOrFatal(t, cipherdir, mnt, "-extpass", "echo test") - defer test_helpers.UnmountPanic(mnt) - - // Write till we get ENOSPC - var err1, err2 error - var sz1, sz2 int - var wg sync.WaitGroup - wg.Add(2) - go func() { - sz1, err1 = writeTillFull(t, mnt+"/foo1") - wg.Done() - }() - go func() { - sz2, err2 = writeTillFull(t, mnt+"/foo2") - wg.Done() - }() - wg.Wait() - if err1 != syscall.ENOSPC || err2 != syscall.ENOSPC { - t.Fatalf("err1=%v, err2=%v", err1, err2) - } - t.Logf("sz1=%d, sz2=%d", sz1, sz2) - - foo1, err := ioutil.ReadFile(mnt + "/foo1") - if err != nil { - t.Fatal(err) - } - if len(foo1) != sz1 { - t.Fail() - } - - foo2, err := ioutil.ReadFile(mnt + "/foo2") - if err != nil { - t.Fatal(err) - } - if len(foo2) != sz2 { - t.Fail() - } -} - -func TestAcl(t *testing.T) { - if os.Getuid() != 0 { - t.Skip("must run as root") - } - cDir := test_helpers.InitFS(t) - os.Chmod(cDir, 0755) - pDir := cDir + ".mnt" - test_helpers.MountOrFatal(t, cDir, pDir, "-allow_other", "-acl", "-extpass=echo test") - defer test_helpers.UnmountPanic(pDir) - - f1 := pDir + "/f1" - if err := ioutil.WriteFile(f1, []byte("hello world\n"), 000); err != nil { - t.Fatal(err) - } - - openUser1234 := func(rwMode int) error { - return asUser(1234, 1234, nil, func() error { - fd, err := syscall.Open(f1, rwMode, 0) - if err != nil { - return err - } - defer syscall.Close(fd) - buf := make([]byte, 100) - if rwMode == syscall.O_RDONLY || rwMode == syscall.O_RDWR { - _, err = syscall.Read(fd, buf) - if err != nil { - return err - } - } - if rwMode == syscall.O_WRONLY || rwMode == syscall.O_RDWR { - _, err = syscall.Write(fd, buf) - if err != nil { - return err - } - } - return err - }) - } - - dumpAcl := func() { - out, err := exec.Command("getfacl", f1).CombinedOutput() - if err != nil { - t.Fatal(err) - } - t.Log(string(out)) - } - - if err := openUser1234(syscall.O_RDONLY); err == nil { - t.Error("this should have failed") - dumpAcl() - } - - // Allow read - out, err := exec.Command("setfacl", "-m", "u:1234:r", f1).CombinedOutput() - if err != nil { - t.Fatal(string(out)) - } - if err := openUser1234(syscall.O_RDONLY); err != nil { - t.Errorf("O_RDONLY should have worked, but got error: %v", err) - dumpAcl() - } - if err := openUser1234(syscall.O_WRONLY); err == nil { - t.Error("O_WRONLY should have failed") - dumpAcl() - } - - // Allow write - out, err = exec.Command("setfacl", "-m", "u:1234:w", f1).CombinedOutput() - if err != nil { - t.Fatal(string(out)) - } - if err := openUser1234(syscall.O_WRONLY); err != nil { - t.Errorf("O_WRONLY should have worked, but got error: %v", err) - dumpAcl() - } - if err := openUser1234(syscall.O_RDONLY); err == nil { - t.Error("O_RDONLY should have failed") - dumpAcl() - } -} diff --git a/tests/sharedstorage/sharedstorage_test.go b/tests/sharedstorage/sharedstorage_test.go deleted file mode 100644 index 8f46c0d..0000000 --- a/tests/sharedstorage/sharedstorage_test.go +++ /dev/null @@ -1,142 +0,0 @@ -// test gocryptfs cipherdir mounted multiple times at the same time -package sharedstorage - -import ( - "fmt" - "os" - "testing" - "time" - - "golang.org/x/sys/unix" - - "github.com/rfjakob/gocryptfs/tests/test_helpers" -) - -var flagSharestorage bool - -// EntryTimeout is 1 second, give the kernel 1.1 second to actually -// expire an entry. The tests fail sometime with 1.0 second! -const waitForExpire = time.Second + 100*time.Millisecond - -func TestMain(m *testing.M) { - ret := 0 - flagSharestorage = false - ret += m.Run() - flagSharestorage = true - ret += m.Run() - os.Exit(ret) -} - -type testCase struct { - t *testing.T - - cipherdir string - mnt1 string - mnt2 string -} - -func newTestCase(t *testing.T) *testCase { - tc := testCase{} - tc.cipherdir = test_helpers.InitFS(t) - tc.mnt1 = tc.cipherdir + ".mnt1" - tc.mnt2 = tc.cipherdir + ".mnt2" - mountSharedstorage(t, tc.cipherdir, tc.mnt1) - mountSharedstorage(t, tc.cipherdir, tc.mnt2) - t.Logf("newTestCase: sharedstorage=%v cipherdir=%q", flagSharestorage, tc.cipherdir) - return &tc -} - -func (tc *testCase) cleanup() { - for _, mnt := range []string{tc.mnt1, tc.mnt2} { - err := test_helpers.UnmountErr(mnt) - if err != nil { - tc.t.Error(err) - } - } -} - -// mountSharedstorage mounts `cipherdir` on `mnt` with or without the -// `-sharedstorage` flag, depending on the global var `flagSharestorage`. -func mountSharedstorage(t *testing.T, cipherdir string, mnt string) { - args := []string{"-extpass=echo test"} - if flagSharestorage { - args = append(args, "-sharedstorage") - } - test_helpers.MountOrFatal(t, cipherdir, mnt, args...) -} - -func TestDirUnlink(t *testing.T) { - tc := newTestCase(t) - defer tc.cleanup() - - // Create dir via mnt1 - if err := unix.Mkdir(tc.mnt1+"/foo", 0700); err != nil { - t.Fatal(err) - } - // Replace dir with file via mnt2 - if err := unix.Rmdir(tc.mnt2 + "/foo"); err != nil { - t.Fatal(err) - } - if fd, err := unix.Creat(tc.mnt2+"/foo", 0600); err != nil { - t.Fatal(err) - } else { - unix.Close(fd) - } - // Try to unlink via mnt1 - if err := unix.Unlink(tc.mnt1 + "/foo"); err != nil { - // Must work with -sharedstorage - if flagSharestorage { - t.Fatal(err) - } else { - // Must always work after cache timeout - time.Sleep(waitForExpire) - if err := unix.Unlink(tc.mnt1 + "/foo"); err != nil { - t.Fatal(err) - } - } - } -} - -// TestStaleHardlinks always failed before -// https://review.gerrithub.io/c/hanwen/go-fuse/+/513646/2 -func TestStaleHardlinks(t *testing.T) { - tc := newTestCase(t) - defer tc.cleanup() - - link0 := tc.mnt1 + "/link0" - if fd, err := unix.Creat(link0, 0600); err != nil { - t.Fatal(err) - } else { - unix.Close(fd) - } - // Create hardlinks via mnt1 - for i := 1; i < 20; i++ { - linki := fmt.Sprintf(tc.mnt1+"/link%d", i) - if err := unix.Link(link0, linki); err != nil { - t.Fatal(err) - } - } - // Delete hardlinks via mnt2 - for i := 1; i < 20; i++ { - linki := fmt.Sprintf(tc.mnt2+"/link%d", i) - if err := unix.Unlink(linki); err != nil { - t.Fatal(err) - } - } - // Open link0 via mnt1 - fd, err := unix.Open(link0, unix.O_RDONLY, 0) - if err != nil { - // Must work with -sharedstorage - if flagSharestorage { - t.Fatal(err) - } else { - // Must always work after cache timeout - time.Sleep(waitForExpire) - fd, err = unix.Open(link0, unix.O_RDONLY, 0) - if err != nil { - t.Fatal(err) - } - } - } - unix.Close(fd) -} diff --git a/tests/sshfs-benchmark.bash b/tests/sshfs-benchmark.bash deleted file mode 100755 index 13c7a0f..0000000 --- a/tests/sshfs-benchmark.bash +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash - -set -eu - -function cleanup { - cd "$LOCAL_TMP" - fusermount -u gocryptfs.mnt - rm -Rf "$SSHFS_TMP" - fusermount -u sshfs.mnt - cd / - rm -Rf "$LOCAL_TMP" -} - -function prepare_mounts { - LOCAL_TMP=$(mktemp -d -t "$MYNAME.XXX") - cd $LOCAL_TMP - echo "working directory: $PWD" - mkdir sshfs.mnt gocryptfs.mnt - sshfs $HOST:/tmp sshfs.mnt - echo "sshfs mounted: $HOST:/tmp -> sshfs.mnt" - trap cleanup EXIT - SSHFS_TMP=$(mktemp -d "sshfs.mnt/$MYNAME.XXX") - mkdir $SSHFS_TMP/gocryptfs.crypt - gocryptfs -q -init -extpass "echo test" -scryptn=10 $SSHFS_TMP/gocryptfs.crypt - gocryptfs -q -extpass "echo test" $SSHFS_TMP/gocryptfs.crypt gocryptfs.mnt - echo "gocryptfs mounted: $SSHFS_TMP/gocryptfs.crypt -> gocryptfs.mnt" -} - -function etime { - T=$(/usr/bin/time -f %e -o /dev/stdout "$@") - LC_ALL=C printf %20.2f "$T" -} - -MYNAME=$(basename "$0") -HOST=$1 - -prepare_mounts - -echo -echo "$MYNAME: sshfs gocryptfs-on-sshfs" -echo -n "git init " -etime git init -q "$SSHFS_TMP/git1" -etime git init -q gocryptfs.mnt/git1 -echo - -git init -q git2 -echo -n "rsync " -etime rsync -a --no-group git2 "$SSHFS_TMP" -etime rsync -a --no-group git2 gocryptfs.mnt -echo - -echo -n "rm -R " -etime rm -R "$SSHFS_TMP/git1" "$SSHFS_TMP/git2" -etime rm -R gocryptfs.mnt/git1 gocryptfs.mnt/git2 -echo - -echo -n "mkdir " -pushd "$SSHFS_TMP" > /dev/null -etime mkdir $(seq 1 20) -popd > /dev/null -cd gocryptfs.mnt -etime mkdir $(seq 1 20) -cd .. -echo - -echo -n "rmdir " -pushd "$SSHFS_TMP" > /dev/null -etime rmdir $(seq 1 20) -popd > /dev/null -cd gocryptfs.mnt -etime rmdir $(seq 1 20) -cd .. -echo - -echo -n "touch " -pushd "$SSHFS_TMP" > /dev/null -etime touch $(seq 101 120) -popd > /dev/null -cd gocryptfs.mnt -etime touch $(seq 101 120) -cd .. -echo - -echo -n "rm " -pushd "$SSHFS_TMP" > /dev/null -etime rm $(seq 101 120) -popd > /dev/null -cd gocryptfs.mnt -etime rm $(seq 101 120) -cd .. -echo diff --git a/tests/stress_tests/extractloop.bash b/tests/stress_tests/extractloop.bash deleted file mode 100755 index cdd0c25..0000000 --- a/tests/stress_tests/extractloop.bash +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/bash -# -# Mount a gocryptfs filesystem somewhere on /tmp, then run two parallel -# infinite loops inside that do the following: -# 1) Extract linux-3.0.tar.gz -# 2) Verify the md5sums -# 3) Delete, go to (1) -# -# This test is good at discovering inode-related memory leaks because it creates -# huge numbers of files. -# -# See Documentation/extractloop.md for example output. - -if [[ -z $TMPDIR ]]; then - TMPDIR=/var/tmp - export TMPDIR -fi - -set -eu - -# Run at low priority to not annoy the user too much -renice 19 $$ - -cd "$(dirname "$0")" -MD5="$PWD/linux-3.0.md5sums" -MYNAME=$(basename "$0") -source ../fuse-unmount.bash - -# Setup dirs -../dl-linux-tarball.bash -cd $TMPDIR -EXTRACTLOOP_TMPDIR=$TMPDIR/extractloop_tmpdir -mkdir -p $EXTRACTLOOP_TMPDIR -CRYPT=$(mktemp -d $EXTRACTLOOP_TMPDIR/XXX) -CSV=$CRYPT.csv -MNT=$CRYPT.mnt -mkdir $MNT - -function check_md5sums { - if command -v md5sum > /dev/null ; then - md5sum --status -c $1 - else - # MacOS / darwin which do not have the md5sum utility - # installed by default - echo "Skipping md5sum (not installed). Hint: brew install md5sha1sum" - fi -} - -# Mount -FSPID=0 -FS="" -if [ $# -eq 1 ] && [ "$1" == "-encfs" ]; then - FS=encfs - echo "Testing EncFS" - encfs --extpass="echo test" --standard $CRYPT $MNT > /dev/null -elif [ $# -eq 1 ] && [ "$1" == "-loopback" ]; then - FS=loopback - echo "Testing go-fuse loopback" - rm -f /tmp/loopback*.memprof - loopback -memprofile=/tmp/loopback $MNT $CRYPT & - FSPID=$(jobs -p) - disown -else - FS=gocryptfs - echo "Testing gocryptfs" - gocryptfs -q -init -extpass="echo test" -scryptn=10 $CRYPT - gocryptfs -q -extpass="echo test" -nosyslog -fg $CRYPT $MNT & - FSPID=$(jobs -p) - disown - #gocryptfs -q -extpass="echo test" -nosyslog -memprofile /tmp/extractloop-mem $CRYPT $MNT -fi -echo "Test dir: $CRYPT" -# Sleep to make sure the FS is already mounted on MNT -sleep 1 -cd $MNT - -ln -v -sTf $CSV /tmp/extractloop.csv 2> /dev/null || true # fails on MacOS, ignore - -# Cleanup trap -# Note: gocryptfs may have already umounted itself because bash relays SIGINT -# Just ignore unmount errors. -trap cleanup_exit EXIT - -function cleanup_exit { - if [[ $FS == loopback ]]; then - # SIGUSR1 causes loopback to write the memory profile to disk - kill -USR1 $FSPID - fi - cd / - rm -Rf $CRYPT - fuse-unmount -z $MNT || true - rmdir $MNT -} - -function loop { - ID=$1 - mkdir $ID - cd $ID - - echo "[looper $ID] Starting" - - N=1 - RSS=0 - while true - do - t1=$SECONDS - tar xf /tmp/linux-3.0.tar.gz --exclude linux-3.0/arch/microblaze/boot/dts/system.dts - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # Exclude the one symlink in the tarball - causes problems on MacOS: "Can't set permissions to 0755" - check_md5sums $MD5 - rm -R linux-3.0 - t2=$SECONDS - delta=$((t2-t1)) - if [[ $FSPID -gt 0 && -d /proc ]]; then - RSS=$(grep VmRSS /proc/$FSPID/status | tr -s ' ' | cut -f2 -d ' ') - echo "$N,$SECONDS,$RSS,$delta" >> $CSV - fi - echo "[looper $ID] Iteration $N done, $delta seconds, RSS $RSS kiB" - let N=$N+1 - done -} - -function memprof { - while true; do - kill -USR1 $FSPID - sleep 60 - done -} - -loop 1 & -loop 2 & -if [[ $FS == loopback ]]; then - memprof & -fi -wait diff --git a/tests/stress_tests/extractloop_plot_csv.m b/tests/stress_tests/extractloop_plot_csv.m deleted file mode 100755 index be80656..0000000 --- a/tests/stress_tests/extractloop_plot_csv.m +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/octave - -r=csvread('/tmp/extractloop.csv'); -figure('Position',[100,100,1600,800]); -[hAx,hLine1,hLine2] = plotyy(r(:,2), r(:,3)/1024, r(:,2), r(:,4)); -xlabel('Runtime (seconds)') -set(hLine1, 'LineWidth', 1, 'Marker', 'o', 'MarkerSize', 10) -% LineWidth also sets the marker drawing thickness -set(hLine2, 'LineWidth', 1, 'LineStyle', 'none', 'Marker', '*', 'MarkerSize', 10) -ylabel(hAx(1), 'RSS (MiB)') -ylabel(hAx(2), 'Iteration Time (seconds)') -grid on; -drawnow; -disp('press enter to exit'); -input(''); diff --git a/tests/stress_tests/fsstress-encfs.bash b/tests/stress_tests/fsstress-encfs.bash deleted file mode 120000 index 139d4ec..0000000 --- a/tests/stress_tests/fsstress-encfs.bash +++ /dev/null @@ -1 +0,0 @@ -fsstress-gocryptfs.bash \ No newline at end of file diff --git a/tests/stress_tests/fsstress-gocryptfs.bash b/tests/stress_tests/fsstress-gocryptfs.bash deleted file mode 100755 index 26e7bc0..0000000 --- a/tests/stress_tests/fsstress-gocryptfs.bash +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -# -# Mount a go-fuse loopback filesystem in /tmp and run fsstress against it -# in an infinite loop, only exiting on errors. -# -# When called as "fsstress-gocryptfs.bash", a gocryptfs filesystem is tested -# instead. -# -# This test used to fail on older go-fuse versions after a few iterations with -# errors like this: -# "rm: cannot remove ‘/tmp/b/fsstress.2/pd/d1XXX/f4a’: No such file or directory" -# -# Nowadays it should pass an indefinite number of iterations. - -set -eu - -# Init variables to default values if unset or empty -export TMPDIR=${TMPDIR:-/var/tmp} -DEBUG=${DEBUG:-0} - -cd "$(dirname "$0")" -MYNAME=$(basename $0) -source ../fuse-unmount.bash - -# fsstress binary -FSSTRESS=$HOME/fuse-xfstests/ltp/fsstress -if [[ ! -x $FSSTRESS ]] -then - echo "$MYNAME: fsstress binary not found at $FSSTRESS" - echo "Please clone and compile https://github.com/rfjakob/fuse-xfstests" - exit 1 -fi - -# Backing directory -DIR=$(mktemp -d $TMPDIR/$MYNAME.XXX) -# Mountpoint -MNT="$DIR.mnt" -mkdir $MNT - -# Set the GOPATH variable to the default if it is empty -GOPATH=$(go env GOPATH) - -# Clean up old mounts -for i in $(mount | cut -d" " -f3 | grep $TMPDIR/$MYNAME) ; do - fusermount -u $i -done - -# FS-specific compile and mount -if [[ $MYNAME = fsstress-loopback.bash ]]; then - echo -n "Recompile go-fuse loopback: " - cd $GOPATH/src/github.com/hanwen/go-fuse/example/loopback - git describe - go build && go install - OPTS="-q" - if [[ $DEBUG -eq 1 ]]; then - OPTS="-debug" - fi - $GOPATH/bin/loopback $OPTS "$MNT" "$DIR" & - disown -elif [[ $MYNAME = fsstress-gocryptfs.bash ]]; then - echo "Recompile gocryptfs" - cd $GOPATH/src/github.com/rfjakob/gocryptfs - ./build.bash # also prints the version - $GOPATH/bin/gocryptfs -q -init -extpass "echo test" -scryptn=10 $DIR - $GOPATH/bin/gocryptfs -q -extpass "echo test" -nosyslog -fusedebug=$DEBUG $DIR $MNT -elif [[ $MYNAME = fsstress-encfs.bash ]]; then - encfs --extpass "echo test" --standard $DIR $MNT -else - echo Unknown mode: $MYNAME - exit 1 -fi - -sleep 0.5 -echo -n "Waiting for mount: " -while ! grep "$(basename $MNT) fuse" /proc/self/mounts > /dev/null -do - sleep 1 - echo -n x -done -echo " ok: $MNT" - -# Cleanup trap -trap "kill %1 ; cd / ; fuse-unmount -z $MNT ; rm -rf $DIR $MNT" EXIT - -echo "Starting fsstress loop" -N=1 -while true -do - echo "$N ................................. $(date)" - mkdir $MNT/fsstress.1 - echo -n " fsstress.1 " - $FSSTRESS -r -m 8 -n 1000 -d $MNT/fsstress.1 & - wait - - mkdir $MNT/fsstress.2 - echo -n " fsstress.2 " - $FSSTRESS -p 20 -r -m 8 -n 1000 -d $MNT/fsstress.2 & - wait - - mkdir $MNT/fsstress.3 - echo -n " fsstress.3 " - $FSSTRESS -p 4 -z -f rmdir=10 -f link=10 -f creat=10 -f mkdir=10 \ - -f rename=30 -f stat=30 -f unlink=30 -f truncate=20 -m 8 \ - -n 1000 -d $MNT/fsstress.3 & - wait - - echo " rm" - rm -Rf $MNT/* - - let N=$N+1 -done - diff --git a/tests/stress_tests/fsstress-loopback.bash b/tests/stress_tests/fsstress-loopback.bash deleted file mode 120000 index 139d4ec..0000000 --- a/tests/stress_tests/fsstress-loopback.bash +++ /dev/null @@ -1 +0,0 @@ -fsstress-gocryptfs.bash \ No newline at end of file diff --git a/tests/stress_tests/fsstress.collect-crashes.sh b/tests/stress_tests/fsstress.collect-crashes.sh deleted file mode 100755 index f315e2e..0000000 --- a/tests/stress_tests/fsstress.collect-crashes.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -cd ~/go/src/github.com/rfjakob/gocryptfs/tests/stress_tests || exit 1 -export TMPDIR=/mnt/ext4-ramdisk -# Check that TMPDIR is writeable -touch "$TMPDIR/$$" || exit 1 -rm "$TMPDIR/$$" -LOGDIR=/tmp/$$ -mkdir "$LOGDIR" || exit 1 -echo "Logging to LOGDIR=$LOGDIR, TMPDIR=$TMPDIR" -for i in $(seq 1 1000) ; do - set -x - LOG="$LOGDIR/fsstress.log.$(date --iso).$i" - if [[ -e $LOG ]]; then - continue - fi - rm -Rf "$TMPDIR"/fsstress* - # 100000 lines ...... ~7 MB - # 1000000 lines ..... ~70 MB - # 10000000 lines .... ~700 MB - DEBUG=1 ./fsstress-loopback.bash 2>&1 | tail -1000000 > "$LOG" -done diff --git a/tests/stress_tests/linux-3.0.md5sums b/tests/stress_tests/linux-3.0.md5sums deleted file mode 100644 index 2cf6349..0000000 --- a/tests/stress_tests/linux-3.0.md5sums +++ /dev/null @@ -1,36782 +0,0 @@ -8a44756de487a56f758ee3dc5d8b1a3f linux-3.0/virt/kvm/kvm_main.c -11b17bdc92061b7b96f7bc3e3653db86 linux-3.0/virt/kvm/irq_comm.c -b806e1725ecc18c4c54c8286e75b86a9 linux-3.0/virt/kvm/iommu.c -89287c0ee08927ac145b6bbbff6973ae linux-3.0/virt/kvm/iodev.h -78b06af814b09a40205250e7ce006bc2 linux-3.0/virt/kvm/ioapic.h -260e5541c3ecfff787430025a115d26d linux-3.0/virt/kvm/ioapic.c -6a6ca7e99fb6a24f1c24d7a9d481c26f linux-3.0/virt/kvm/eventfd.c -fb14b17966783d02a91fc3fc14fb3a6d linux-3.0/virt/kvm/coalesced_mmio.h -55b7c8870ea82a5fbbf54b605acb1187 linux-3.0/virt/kvm/coalesced_mmio.c -335cd037b29751033a198be10597227b linux-3.0/virt/kvm/async_pf.h -25e3d49cb7854c78e00d206a9419d817 linux-3.0/virt/kvm/async_pf.c -2b5dd9a77921b3988322581c663db4bf linux-3.0/virt/kvm/assigned-dev.c -5482920d7d3d151945a4df62a1c7f024 linux-3.0/virt/kvm/Kconfig -047de60ac631660198bdf5ffbe6bb62f linux-3.0/usr/initramfs_data.S -4f8151ebfa1693b19858c5856b43660a linux-3.0/usr/gen_init_cpio.c -f9e1fdbf7a3ade26cd9842cc8506dad9 linux-3.0/usr/Makefile -01eef3783a737e087b97664ecd5faaa9 linux-3.0/usr/Kconfig -530ec264818fd9d7f0810479b3b4e360 linux-3.0/usr/.gitignore -683865743f1dc3997fc7a987a2998a1b linux-3.0/tools/virtio/virtio_test.c -db868860cf4da73eb6499489cc4e096a linux-3.0/tools/virtio/vhost_test/vhost_test.c -e6486bef9d9d891d8532d19c2581d3d8 linux-3.0/tools/virtio/vhost_test/Makefile -9b0e58084141e0dea3340bc3b1211b00 linux-3.0/tools/virtio/linux/virtio.h -50bec7f312c5d26b3db056275ffd7341 linux-3.0/tools/virtio/linux/slab.h -b0c3aee60e5132c53c2ad6b29b93fd49 linux-3.0/tools/virtio/linux/device.h -965a7f7e18ba6d2c0825285c5b58e0d1 linux-3.0/tools/virtio/Makefile -c987e0eec87236de3c1ee9df2f65bc28 linux-3.0/tools/usb/testusb.c -9f629e683ca39333b7f69d727ea9e0c6 linux-3.0/tools/usb/hcd-tests.sh -391b77acfb70985d3f670788f9ebd031 linux-3.0/tools/usb/ffs-test.c -092ccf63c2f76a4ce671981e0a4b3ecc linux-3.0/tools/usb/Makefile -1651035169ef26caf3f4f71ac3ae4f3d linux-3.0/tools/testing/ktest/sample.conf -34162d5a48aba4f15c3e89c22f54aa2e linux-3.0/tools/testing/ktest/ktest.pl -111e72b075bd0f17158cffaf3c445748 linux-3.0/tools/testing/ktest/compare-ktest-sample.pl -c2f4988d33bdf8710c3a83371f3cfecc linux-3.0/tools/slub/slabinfo.c -f9744712354b26eda999e4e751cbbbef linux-3.0/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c -fc632a92f1476cc2e69e3c4149ed0925 linux-3.0/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 -a5c7116b041fb4818b47af6df1396bf6 linux-3.0/tools/power/x86/x86_energy_perf_policy/Makefile -40337533c5345608c113c70fd8ba84e7 linux-3.0/tools/power/x86/turbostat/turbostat.c -90016eabb766a9edf4f8a8e3a33bce3f linux-3.0/tools/power/x86/turbostat/turbostat.8 -5d75eddb064a1b28956d05bf3dea82bd linux-3.0/tools/power/x86/turbostat/Makefile -f8214f548f349d425897fbfe65be6318 linux-3.0/tools/perf/util/xyarray.h -90c2dc70343ff978cceeb59787b6cd2b linux-3.0/tools/perf/util/xyarray.c -9d6feb3843bd718f8bc953e411fc15d2 linux-3.0/tools/perf/util/wrapper.c -27c4f08d17f80653d99432fa4613f03f linux-3.0/tools/perf/util/values.h -1ccbd280b50970cc1a6303b7e28189d0 linux-3.0/tools/perf/util/values.c -aaf94ff39fc686ce6b49d26691177775 linux-3.0/tools/perf/util/util.h -1cd2c147d326b4b1e0541afc937a254a linux-3.0/tools/perf/util/util.c -b2cd2a25ff8f913820e85230ead5de32 linux-3.0/tools/perf/util/usage.c -ae0f8e45c132c5d81e4e932186d280f5 linux-3.0/tools/perf/util/ui/util.h -16087df9dd67dd7cc945c92bf43c3db0 linux-3.0/tools/perf/util/ui/util.c -fe12940dfcf064637eaf8ef196821d71 linux-3.0/tools/perf/util/ui/ui.h -eed13ffa4256757394482782814626bb linux-3.0/tools/perf/util/ui/setup.c -e2ce908f0214c7c33194071232a24cbc linux-3.0/tools/perf/util/ui/progress.h -b4869f9fc603e9e7411356e19c523c17 linux-3.0/tools/perf/util/ui/progress.c -065c7a777cca0a1371b4c250cb8773b1 linux-3.0/tools/perf/util/ui/libslang.h -89472959a3ab96609acb44fd68c2fcdb linux-3.0/tools/perf/util/ui/helpline.h -9d8240be045ca8686583f27e31f1286f linux-3.0/tools/perf/util/ui/helpline.c -071fa1511cbb5b647298dea89b526b05 linux-3.0/tools/perf/util/ui/browsers/top.c -b6787c67527164c3627d03c46f599ab2 linux-3.0/tools/perf/util/ui/browsers/map.h -71490d5f10e2fef12862d0a8f97fe5f6 linux-3.0/tools/perf/util/ui/browsers/map.c -8bbe9afc81156c13620bdcb717632d66 linux-3.0/tools/perf/util/ui/browsers/hists.c -34bdee201a1830e5daaf388e1d5d4dbd linux-3.0/tools/perf/util/ui/browsers/annotate.c -ca7f4a70d8621b36e09b8ae13eeafa33 linux-3.0/tools/perf/util/ui/browser.h -38488cf8d4eded0d4a052cac606fbdb9 linux-3.0/tools/perf/util/ui/browser.c -f152c7fa179e1b64508583f82fe81b3e linux-3.0/tools/perf/util/types.h -8255bedda876262117c36d4ebfabeee0 linux-3.0/tools/perf/util/trace-event.h -a11a6b4989f700d5d750f68da4cf37f5 linux-3.0/tools/perf/util/trace-event-scripting.c -ec45047d29cb48d51fb78b73be936120 linux-3.0/tools/perf/util/trace-event-read.c -3b7d01975bb448392e7c1bd109547688 linux-3.0/tools/perf/util/trace-event-parse.c -3b76ac45bbfcd6577d312a86b11fb428 linux-3.0/tools/perf/util/trace-event-info.c -a338904b2f4241175c31ef880070f5c5 linux-3.0/tools/perf/util/top.h -edfc85fdd104d33b71be7e78dcd7a7c2 linux-3.0/tools/perf/util/top.c -95d594627a9567524cad3c5f1a19a963 linux-3.0/tools/perf/util/thread_map.h -54e1fee3778469f862fc2071393d2bf6 linux-3.0/tools/perf/util/thread_map.c -5d8b4a93366d6c09847df3167c41daa0 linux-3.0/tools/perf/util/thread.h -f2566439d697770ee419a515f17cc870 linux-3.0/tools/perf/util/thread.c -4353817e9444200f8daafe4cc336245b linux-3.0/tools/perf/util/symbol.h -ed6bbcf665cb44265fd42c7da152c8fb linux-3.0/tools/perf/util/symbol.c -0930549b78d76bfeb2e6b1f3fd1d992a linux-3.0/tools/perf/util/svghelper.h -967d2f0168866591ea0fee83d68b76a9 linux-3.0/tools/perf/util/svghelper.c -6a70054800a47878263641ad3bd27f13 linux-3.0/tools/perf/util/strlist.h -b44f063cf1c8b3853df04c493222cdd9 linux-3.0/tools/perf/util/strlist.c -677719d9975a83e5961e3f2e9a4fd0a9 linux-3.0/tools/perf/util/string.c -3e453c2e89cdd10a967beb599ff4f5ab linux-3.0/tools/perf/util/strfilter.h -683288a8170da2ada41629585f01b442 linux-3.0/tools/perf/util/strfilter.c -0f24c529687cc306396ffdd4c74f4eba linux-3.0/tools/perf/util/strbuf.h -d8594be92a6cb36c0795a11b73035738 linux-3.0/tools/perf/util/strbuf.c -bf70243cf567a7b94022bce1751d0c53 linux-3.0/tools/perf/util/sort.h -c90256d7afb14587eeb8e58f646ac2f6 linux-3.0/tools/perf/util/sort.c -fbfebd61f4582411743caa639d1e6475 linux-3.0/tools/perf/util/sigchain.h -97611192bf70902c9aa1d7d8ec7fb791 linux-3.0/tools/perf/util/sigchain.c -bb39fad37100d36a84bedd73b5089c7a linux-3.0/tools/perf/util/setup.py -33b1a24a4e7fccb8b21a545244b13123 linux-3.0/tools/perf/util/session.h -ad787ecfe904fcdcb55492a4040b495c linux-3.0/tools/perf/util/session.c -f2a7e52e215780cb13de593eeec8780d linux-3.0/tools/perf/util/scripting-engines/trace-event-python.c -963c73397343bc8743906d7930b52f21 linux-3.0/tools/perf/util/scripting-engines/trace-event-perl.c -00a03b81b63f62997cf3e7c5e325a481 linux-3.0/tools/perf/util/run-command.h -6c13c4929ac7ed3682daad3a8fecf560 linux-3.0/tools/perf/util/run-command.c -8005e383cb16095095ad5722149cd395 linux-3.0/tools/perf/util/quote.h -fb53d259350a7b6fc10953415140efaa linux-3.0/tools/perf/util/quote.c -2b20cbcf39c0cb1f8ac745185b0c1229 linux-3.0/tools/perf/util/python.c -4e31e03166484444f238c8ebacb7fba1 linux-3.0/tools/perf/util/pstack.h -763f707263c68cb567d23e7b9c55e00c linux-3.0/tools/perf/util/pstack.c -5e6ceff892a7f172359ca61ea0607850 linux-3.0/tools/perf/util/probe-finder.h -50822b01a2c7fb20820776e0e8c0c83c linux-3.0/tools/perf/util/probe-finder.c -e1b8d87748fe2b2a5219da819110f814 linux-3.0/tools/perf/util/probe-event.h -d876320c52c0c2610b454099a2f141fc linux-3.0/tools/perf/util/probe-event.c -59cb18def9d8bd1b5b04d0a9a1677404 linux-3.0/tools/perf/util/path.c -911bde63991515b7608fe1e4c3eaf59f linux-3.0/tools/perf/util/parse-options.h -695e64d67dd04ea610dfc73957c141dc linux-3.0/tools/perf/util/parse-options.c -f1b81f7dace88fa8a12715b3a41c943f linux-3.0/tools/perf/util/parse-events.h -aac4d09d352f98cc58d979a46a5e841c linux-3.0/tools/perf/util/parse-events.c -dc856e507c1105eb3f2e4660a356a693 linux-3.0/tools/perf/util/pager.c -97130129524daf59c274427fa928afa7 linux-3.0/tools/perf/util/map.h -94efd228d9c019de996c47fd8040832a linux-3.0/tools/perf/util/map.c -cc33a420384a78c0ed8737724fc67410 linux-3.0/tools/perf/util/levenshtein.h -4488ae93a303f331fc6e679cd3589985 linux-3.0/tools/perf/util/levenshtein.c -a807dd338e16a75a16f4da08349a1b94 linux-3.0/tools/perf/util/include/linux/types.h -69d15c31527f01f99796d1e1a414e38f linux-3.0/tools/perf/util/include/linux/string.h -d9335a229992b0225cd12fd1b706705a linux-3.0/tools/perf/util/include/linux/rbtree.h -d29a0d3558d2e321bacfa9c4c403052f linux-3.0/tools/perf/util/include/linux/prefetch.h -bf0f255442e21bfe6021af139e91aa5a linux-3.0/tools/perf/util/include/linux/poison.h -3560c691066e59a53b8f980fc40a350c linux-3.0/tools/perf/util/include/linux/module.h -4215523f252c8e229bab367633362869 linux-3.0/tools/perf/util/include/linux/list.h -b006060ab731a89573b378aa95227a14 linux-3.0/tools/perf/util/include/linux/linkage.h -919a2056fc880f1e6549e28b8f1a2683 linux-3.0/tools/perf/util/include/linux/kernel.h -47ede60d0dd00b0669e4329fb859a7d3 linux-3.0/tools/perf/util/include/linux/hash.h -cf687f1506e6035c235c998141752bbc linux-3.0/tools/perf/util/include/linux/ctype.h -34e07f1daa502377dccafc130e567c93 linux-3.0/tools/perf/util/include/linux/const.h -e11894eaf87b9762a2d4956a9f7d6456 linux-3.0/tools/perf/util/include/linux/compiler.h -5b3702641c0a2779723e19d6d18408ac linux-3.0/tools/perf/util/include/linux/bitops.h -2c31af15add0e60b8b8880fdd83be745 linux-3.0/tools/perf/util/include/linux/bitmap.h -331e4ed3b5453ad70a7a24c23b8d4a20 linux-3.0/tools/perf/util/include/dwarf-regs.h -8ced7bfa99ec38686579bd464da28ebc linux-3.0/tools/perf/util/include/asm/uaccess.h -a863ef5f1c11831afdaf974a863a0a63 linux-3.0/tools/perf/util/include/asm/system.h -7b21b66ba6e9d79afaedf7ae0a17c827 linux-3.0/tools/perf/util/include/asm/swab.h -fdc86d546a33c1348a6b5fd0c5004c9e linux-3.0/tools/perf/util/include/asm/hweight.h -156543607cb7712d966590df378d99d6 linux-3.0/tools/perf/util/include/asm/dwarf2.h -a07a2ee4966f34f01011a77d7a78b154 linux-3.0/tools/perf/util/include/asm/cpufeature.h -89e4ca58025f5ec28310df44486bf510 linux-3.0/tools/perf/util/include/asm/byteorder.h -a5fb921d1d3bb430277b56af9cdf367d linux-3.0/tools/perf/util/include/asm/bug.h -7b21b66ba6e9d79afaedf7ae0a17c827 linux-3.0/tools/perf/util/include/asm/asm-offsets.h -26a809d7880dbdbf03e6664e7adaf183 linux-3.0/tools/perf/util/include/asm/alternative-asm.h -356d340d692d8afce0ddbf5731ab599d linux-3.0/tools/perf/util/hweight.c -a734133f6603d2002854d12532f5c6c9 linux-3.0/tools/perf/util/hist.h -278df634ca2e7ff2b8983bd3f42b2f1f linux-3.0/tools/perf/util/hist.c -eef7f3308b426fcf3a5511acd7f3a585 linux-3.0/tools/perf/util/help.h -f2fef39347d1ee80b98d1b737a26f135 linux-3.0/tools/perf/util/help.c -c8e006fa8c4ccffeed19f0572bf45a38 linux-3.0/tools/perf/util/header.h -1484d479d77752f7d0407ac688734713 linux-3.0/tools/perf/util/header.c -b70c1502642732639df06e50395838c2 linux-3.0/tools/perf/util/generate-cmdlist.sh -5d4d9dfee7c28134a3a24bc45166a71d linux-3.0/tools/perf/util/exec_cmd.h -a1f608c75c66822e6860e954649bcd34 linux-3.0/tools/perf/util/exec_cmd.c -25540eed5eba2cc5b055e722b9d5ebfb linux-3.0/tools/perf/util/evsel.h -7f9bb25644756342ad1ba0b5daee8f8d linux-3.0/tools/perf/util/evsel.c -c4dd1742b7c4ce8a0ceb7346a285d579 linux-3.0/tools/perf/util/evlist.h -d3978a55fb5ac4e922f551d55f264fb0 linux-3.0/tools/perf/util/evlist.c -d23e210dc8bdbc9280955f33a6c20811 linux-3.0/tools/perf/util/event.h -0a1301317c452bf3f74a8cf64eee208a linux-3.0/tools/perf/util/event.c -942dd3cd3bc14d3098fa1d8ecbe46a79 linux-3.0/tools/perf/util/environment.c -70c24620d29d81c8bca3d99367737572 linux-3.0/tools/perf/util/debugfs.h -7560f5c45ac1e89517d317a7e1d5538c linux-3.0/tools/perf/util/debugfs.c -93bb182dbc81d2ae2e542e8726c1750d linux-3.0/tools/perf/util/debug.h -4349c0faba1298273bca8d1f23702fae linux-3.0/tools/perf/util/debug.c -a94bafafc732ff16a7625aab71e53a16 linux-3.0/tools/perf/util/ctype.c -febe42237319d2802e38f6f49082a726 linux-3.0/tools/perf/util/cpumap.h -97fd10ab554d8f516e90328636a8e39e linux-3.0/tools/perf/util/cpumap.c -47d3dde38b91a1f829bcab154041e77e linux-3.0/tools/perf/util/config.c -cb83a74f6422b4ab0839da201862778a linux-3.0/tools/perf/util/color.h -186a3744f5176b63fef77922e6c84e00 linux-3.0/tools/perf/util/color.c -5bd4ed1243f792b66d0fc37d95f761a9 linux-3.0/tools/perf/util/cgroup.h -81d6bb6cec2a9098daf1f70ff798867f linux-3.0/tools/perf/util/cgroup.c -83ec1ebe9255598be889ef5649d2f5d2 linux-3.0/tools/perf/util/callchain.h -a4551bdfd47931396babbfa57f99df3e linux-3.0/tools/perf/util/callchain.c -d675a402ebf5b067448aaa0f42d5a828 linux-3.0/tools/perf/util/cache.h -01663d41bbd5ec2ab76e6d24fd9b9e9c linux-3.0/tools/perf/util/build-id.h -98e3e09e5b508d9fdb0178b36df52802 linux-3.0/tools/perf/util/build-id.c -fd0fa57669c128e50b2805884812c97e linux-3.0/tools/perf/util/bitmap.c -74489edf6a4de9abfc6288599fe27391 linux-3.0/tools/perf/util/annotate.h -051b18ebe1bbea9fa5a999596a032ec3 linux-3.0/tools/perf/util/annotate.c -7847df3719476d031225307476351c8b linux-3.0/tools/perf/util/alias.c -32421cca4eaacfc02ec3f50f8de32417 linux-3.0/tools/perf/util/abspath.c -47ac78c4d9144f8ab2fe4e431e062320 linux-3.0/tools/perf/util/PERF-VERSION-GEN -481c4fd645bd4c1d7ae2469f60fd0197 linux-3.0/tools/perf/scripts/python/syscall-counts.py -d6cc12bb444eb2798e1c9117d56ece12 linux-3.0/tools/perf/scripts/python/syscall-counts-by-pid.py -1dedfc25e63aed3849b8d2632b9f25f5 linux-3.0/tools/perf/scripts/python/sctop.py -eb6947be1ce66560795eeae0a6eb729c linux-3.0/tools/perf/scripts/python/sched-migration.py -f9b0b1011c1e6ebc032b148dd4ecbea2 linux-3.0/tools/perf/scripts/python/netdev-times.py -358c2cc8ea7f55856beb5a7ecf33c2ed linux-3.0/tools/perf/scripts/python/futex-contention.py -8bfed65ef51a1c54ca72aacbe2dd9d26 linux-3.0/tools/perf/scripts/python/failed-syscalls-by-pid.py -cf557a785ef7546e18c0c851d6e4e774 linux-3.0/tools/perf/scripts/python/check-perf-trace.py -7c6887d5738be8c92f9fd119af690e96 linux-3.0/tools/perf/scripts/python/bin/syscall-counts-report -61a81145b068412612ded7691a4d2330 linux-3.0/tools/perf/scripts/python/bin/syscall-counts-record -c6b25fa68c7d4b360fae3c801e746573 linux-3.0/tools/perf/scripts/python/bin/syscall-counts-by-pid-report -61a81145b068412612ded7691a4d2330 linux-3.0/tools/perf/scripts/python/bin/syscall-counts-by-pid-record -8ff62ed8c6eef5f07f0b067bb89e083a linux-3.0/tools/perf/scripts/python/bin/sctop-report -61a81145b068412612ded7691a4d2330 linux-3.0/tools/perf/scripts/python/bin/sctop-record -cded78feb4f7110a7a371d694e51697a linux-3.0/tools/perf/scripts/python/bin/sched-migration-report -ac9fa2d6d25fd94236de21b9b6b1f2eb linux-3.0/tools/perf/scripts/python/bin/sched-migration-record -c6326c54c275cc9657d7df097deae0a0 linux-3.0/tools/perf/scripts/python/bin/netdev-times-report -439e3fee34ecef92d106a5639f7a1372 linux-3.0/tools/perf/scripts/python/bin/netdev-times-record -bb6878c428ec3b49bbcdb8935af4c70d linux-3.0/tools/perf/scripts/python/bin/futex-contention-report -06326a949892ef3d1a7e0d1c2558ccb6 linux-3.0/tools/perf/scripts/python/bin/futex-contention-record -3010bda11c72c3905a21a51c37ecac34 linux-3.0/tools/perf/scripts/python/bin/failed-syscalls-by-pid-report -29ad806ebf367d8955f920696aae0a3b linux-3.0/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record -05a0d525cb7b9fe466b6c33d984da6e7 linux-3.0/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py -cf3ab1af1b3edd9f30763a5abf1c9c7d linux-3.0/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py -c7a6239273f8989b7d1bd1e0f0ec0b6b linux-3.0/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py -e70accb6d24004c11aac13f06e2c8a3e linux-3.0/tools/perf/scripts/python/Perf-Trace-Util/Context.c -ac89ba60a8aad3826379e0aaf48fc5fc linux-3.0/tools/perf/scripts/perl/workqueue-stats.pl -af17763cbaa4079cff62ec1af1113dcc linux-3.0/tools/perf/scripts/perl/wakeup-latency.pl -80b48530e606a997390f869bc0701493 linux-3.0/tools/perf/scripts/perl/rwtop.pl -d473861fd7e73a1abc384f7a25867c37 linux-3.0/tools/perf/scripts/perl/rw-by-pid.pl -46513fc784eec1ca19c127a4280ac81e linux-3.0/tools/perf/scripts/perl/rw-by-file.pl -8d96f07ac80eb59ee37a48cbde2c215e linux-3.0/tools/perf/scripts/perl/failed-syscalls.pl -abd172f98b33ff8ae16f2c1e069bc3cb linux-3.0/tools/perf/scripts/perl/check-perf-trace.pl -f53739635695af80288ffdbe001e75fb linux-3.0/tools/perf/scripts/perl/bin/workqueue-stats-report -e9c224481bfa6353d92d96a700488b46 linux-3.0/tools/perf/scripts/perl/bin/workqueue-stats-record -04640f0efa55f5aa8f5b5df9fb5e14d0 linux-3.0/tools/perf/scripts/perl/bin/wakeup-latency-report -8f6c86f33c059dae01df5fbd26fb8828 linux-3.0/tools/perf/scripts/perl/bin/wakeup-latency-record -fe30bfbb976bb370aec28df22a78a22f linux-3.0/tools/perf/scripts/perl/bin/rwtop-report -5f66d67da405bdfb8d4be7fd7df9bd52 linux-3.0/tools/perf/scripts/perl/bin/rwtop-record -05569524632208cb2a585aeb56750756 linux-3.0/tools/perf/scripts/perl/bin/rw-by-pid-report -5f66d67da405bdfb8d4be7fd7df9bd52 linux-3.0/tools/perf/scripts/perl/bin/rw-by-pid-record -7a3282ec87197de664bdc3a64efa43ed linux-3.0/tools/perf/scripts/perl/bin/rw-by-file-report -4f5329582c4f5632ea91002bdce7b07b linux-3.0/tools/perf/scripts/perl/bin/rw-by-file-record -e8de6f7f10fb8024a73427db4943a8e2 linux-3.0/tools/perf/scripts/perl/bin/failed-syscalls-report -29ad806ebf367d8955f920696aae0a3b linux-3.0/tools/perf/scripts/perl/bin/failed-syscalls-record -0d1e56bd0e7fbe04a1df9cbfc5ac8b3b linux-3.0/tools/perf/scripts/perl/bin/check-perf-trace-record -002f01b29ee46d7838c43d3a03c02799 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/typemap -ddf3a679721c41d678d642c7fa324ab6 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm -39dd8463a0f410d526a4f56c1d0b596b linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm -1684dc43ade3aeb89219ef5ba826b528 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm -df94b9d697ebf63f94e038177b79ad31 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/README -79c62345857aff7f890fec80e70d01ac linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL -68890c4d69fde7b0aea586404dbba0d8 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs -d12be9b8d9b2924ff05edbe515d4d686 linux-3.0/tools/perf/scripts/perl/Perf-Trace-Util/Context.c -9bf5153914d71d035d769a51622e9200 linux-3.0/tools/perf/python/twatch.py -adbcd9183fbce860a52d483e012365ac linux-3.0/tools/perf/perf.h -4b369f06efeda5180b0394902b5d6282 linux-3.0/tools/perf/perf.c -3b78dfa24b5976337033eff60d81b818 linux-3.0/tools/perf/perf-archive.sh -befa13ef6d09a7ab5bd51b01040a1045 linux-3.0/tools/perf/design.txt -9c1005db312825114dac05a84a6b4538 linux-3.0/tools/perf/config/utilities.mak -714102ed9321e5c14b73c39d2ff02a43 linux-3.0/tools/perf/config/feature-tests.mak -dd6d00111244feb2ea7d61727a3582c0 linux-3.0/tools/perf/command-list.txt -19f4ef68eab22eea73bc9f74917d9f60 linux-3.0/tools/perf/builtin.h -9a33e7ec6cb3268636ce98873fe14a09 linux-3.0/tools/perf/builtin-top.c -5ee019068da739beb54bfbff615876f9 linux-3.0/tools/perf/builtin-timechart.c -59ea86b65ee276b7e75a6d75ad41a09d linux-3.0/tools/perf/builtin-test.c -d70d11ee98c0e79040658cc565f4a3e3 linux-3.0/tools/perf/builtin-stat.c -52c39c8eb6e6a5dc68c6fe809d471583 linux-3.0/tools/perf/builtin-script.c -c0db5dc4afe875906bc0fa4e443b266c linux-3.0/tools/perf/builtin-sched.c -369ceec454813c43f04c411f1c4c7f99 linux-3.0/tools/perf/builtin-report.c -14f2247687e5b47084b5628abb71d849 linux-3.0/tools/perf/builtin-record.c -bbc85358a2914ba425c67735bfa4787d linux-3.0/tools/perf/builtin-probe.c -9089968321ea3bb1c63aec792a139ed6 linux-3.0/tools/perf/builtin-lock.c -1b0be23b7ecadb935890a63d5668380d linux-3.0/tools/perf/builtin-list.c -07418f6e009013f2f601b41ee0c1fc52 linux-3.0/tools/perf/builtin-kvm.c -dc6d0e2de313431f98d3fb7f2069f509 linux-3.0/tools/perf/builtin-kmem.c -d8c388b47e1ba901a9f9502d16e99747 linux-3.0/tools/perf/builtin-inject.c -47f22592e969e26b1d225ec44b017d74 linux-3.0/tools/perf/builtin-help.c -e75bb45a9513d57f22a4c77da696c6c6 linux-3.0/tools/perf/builtin-evlist.c -81f2449168f104652b0facfc37414b0c linux-3.0/tools/perf/builtin-diff.c -cc9a982718fb9e49de911d16c357d92a linux-3.0/tools/perf/builtin-buildid-list.c -b3f8a4494000510505f075f6b43efbab linux-3.0/tools/perf/builtin-buildid-cache.c -e5d1f524185c30ed129f2f52755bac23 linux-3.0/tools/perf/builtin-bench.c -556a7e970d9776c7f62b5731349b26dd linux-3.0/tools/perf/builtin-annotate.c -6a5e6e18ba5a8c74a2a3a87fe3007d53 linux-3.0/tools/perf/bench/sched-pipe.c -47c92d40435fffea05c6ab6ce80c19d8 linux-3.0/tools/perf/bench/sched-messaging.c -2c126acc3598ee4173da3c4794ebf97b linux-3.0/tools/perf/bench/mem-memcpy.c -6c32a99dca9aa1376cb436deeb6247ae linux-3.0/tools/perf/bench/mem-memcpy-x86-64-asm.S -014cbae3e3fd89c1bc20f6fdf94dcc0e linux-3.0/tools/perf/bench/mem-memcpy-x86-64-asm-def.h -13dbab6e6aae1a02c6f87c0927658c36 linux-3.0/tools/perf/bench/mem-memcpy-arch.h -d40da208df71e4fb7a06a3965075e952 linux-3.0/tools/perf/bench/bench.h -b2ab7f57bf7a1ed26b059bfa5a3f506f linux-3.0/tools/perf/arch/x86/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/x86/Makefile -a09b2b36bb4662dab71b5c01e9d59879 linux-3.0/tools/perf/arch/sparc/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/sparc/Makefile -3ac6491e10782befcffe08357ab604ad linux-3.0/tools/perf/arch/sh/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/sh/Makefile -7d98c6aabb69d7685599cd5cb9cc41a3 linux-3.0/tools/perf/arch/s390/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/s390/Makefile -fb786f11326d27a238de6f63e785b534 linux-3.0/tools/perf/arch/powerpc/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/powerpc/Makefile -00591183541c19f66d374635b35ace97 linux-3.0/tools/perf/arch/arm/util/dwarf-regs.c -1c250346ac6cd5f4a09950a317e6033d linux-3.0/tools/perf/arch/arm/Makefile -1a9ae59993e7b3afa664cf7a613953bf linux-3.0/tools/perf/Makefile -d50c40968fbd6b1d8718c1777f92cb3d linux-3.0/tools/perf/MANIFEST -93c4cac962074eabd2f6cd8d1e71b691 linux-3.0/tools/perf/Documentation/perf.txt -c29e7d0624c1a8b1dd876bfaba101fb3 linux-3.0/tools/perf/Documentation/perf-top.txt -d992f18addd44b64c81364d106c66238 linux-3.0/tools/perf/Documentation/perf-timechart.txt -ec8df46a7da46fb4f501976265f6bb21 linux-3.0/tools/perf/Documentation/perf-test.txt -2c6ec87628d25168c11451ec43c89e63 linux-3.0/tools/perf/Documentation/perf-stat.txt -5c078d2b59855efda01367ddb4b53be8 linux-3.0/tools/perf/Documentation/perf-script.txt -70af2c62628d6be1595fcebddf74090e linux-3.0/tools/perf/Documentation/perf-script-python.txt -46114d1d5d37f4b783467fde2a8a7e7f linux-3.0/tools/perf/Documentation/perf-script-perl.txt -89aa7f1008b5771306c78675cdfceb1a linux-3.0/tools/perf/Documentation/perf-sched.txt -eb4eb2fe8a19ae98f1d655f75789d329 linux-3.0/tools/perf/Documentation/perf-report.txt -af3f32892c8a3d58c459f3f3896e931e linux-3.0/tools/perf/Documentation/perf-record.txt -b490300006cc6eccf413195e5c34cbec linux-3.0/tools/perf/Documentation/perf-probe.txt -ea10c6bcd557e127411d68ce64e27edd linux-3.0/tools/perf/Documentation/perf-lock.txt -8824d507310503d0d6aa95ffa5334c81 linux-3.0/tools/perf/Documentation/perf-list.txt -8e90f7d8519a9b924af0c11fe75e0214 linux-3.0/tools/perf/Documentation/perf-kvm.txt -ff6bfa8dceb6ef56fe599feeec371d85 linux-3.0/tools/perf/Documentation/perf-kmem.txt -1d9140fdfd8ebdc35076a3a3b2e46c85 linux-3.0/tools/perf/Documentation/perf-inject.txt -6c37c424f2eb440f27530ec27fac0b55 linux-3.0/tools/perf/Documentation/perf-help.txt -3231edcdf426a1028a5a21927d887c71 linux-3.0/tools/perf/Documentation/perf-evlist.txt -4ee566a8fb667cfeb29e0386cb4fa5d2 linux-3.0/tools/perf/Documentation/perf-diff.txt -c8c55623eb52344b3b68cd4ac92fd9da linux-3.0/tools/perf/Documentation/perf-buildid-list.txt -4bbe27358a402ae6b3cc6c6497e74652 linux-3.0/tools/perf/Documentation/perf-buildid-cache.txt -30d839e7ddb9bc232bd15278bf2a4bb1 linux-3.0/tools/perf/Documentation/perf-bench.txt -8e4619e7705c2ddf1764b0972935cc8c linux-3.0/tools/perf/Documentation/perf-archive.txt -d62feb1cbe803159a746d89e0aaaa5be linux-3.0/tools/perf/Documentation/perf-annotate.txt -2f1169639fd5fca33a754016e2d3b89e linux-3.0/tools/perf/Documentation/manpage-suppress-sp.xsl -83f296aa79af8109808364d2421c1140 linux-3.0/tools/perf/Documentation/manpage-normal.xsl -a19316b1e11e779e61c30dfbea0b92f6 linux-3.0/tools/perf/Documentation/manpage-bold-literal.xsl -d0c51aa8fb59ac8d47ac045858d90543 linux-3.0/tools/perf/Documentation/manpage-base.xsl -31936e12e13942a2f2e667b657cb7611 linux-3.0/tools/perf/Documentation/manpage-1.72.xsl -f633d43ab551f7dba36e767bf6ed1f3a linux-3.0/tools/perf/Documentation/examples.txt -c3356b4a7834944003d08ad169d09618 linux-3.0/tools/perf/Documentation/asciidoc.conf -58c212793d1da971c1945c29db0e3435 linux-3.0/tools/perf/Documentation/Makefile -faeb5b249d8ac1c2e437aee897c3ea99 linux-3.0/tools/perf/CREDITS -7c74275e315752ceacf3c8b738ac7aa2 linux-3.0/tools/perf/.gitignore -b703b236e488fb789abe1dc4a21e4d1f linux-3.0/tools/firewire/nosy-dump.h -e291e490458d6a64bd419ff0e6f742df linux-3.0/tools/firewire/nosy-dump.c -e3d2c299fe53f4ec3c6a6860e822b8bc linux-3.0/tools/firewire/list.h -67354cfe4aa922b3cfc3ebc921af4471 linux-3.0/tools/firewire/decode-fcp.c -ab3c4816906ad529fa30dba43d94a8bc linux-3.0/tools/firewire/Makefile -0bdac03006c7223e763ce3ebfc6b2598 linux-3.0/sound/usb/usx2y/usx2yhwdeppcm.h -10e5905f0aa667b89961df1b7df0af44 linux-3.0/sound/usb/usx2y/usx2yhwdeppcm.c -9a0fd42bf5c863a53546479a106faf4d linux-3.0/sound/usb/usx2y/usx2y.h -31c72b242a96274f8f0458a33ec39e31 linux-3.0/sound/usb/usx2y/usbusx2yaudio.c -e1326b764eee9116901aa066ddcab5b5 linux-3.0/sound/usb/usx2y/usbusx2y.h -1ebf5287ef80f5440957d152251b63ad linux-3.0/sound/usb/usx2y/usbusx2y.c -c921038ef91f5c4cb326ea84e3333415 linux-3.0/sound/usb/usx2y/usbus428ctldefs.h -11e7e4fa26130fe459282881a8beac24 linux-3.0/sound/usb/usx2y/usb_stream.h -99f5df9f5cc2f798a01830da6e1746e3 linux-3.0/sound/usb/usx2y/usb_stream.c -531354385d52e2e41a215d9e3d840303 linux-3.0/sound/usb/usx2y/usX2Yhwdep.h -0193f199d433a0924500bcc9c4d57b2e linux-3.0/sound/usb/usx2y/usX2Yhwdep.c -666ddef60c26da2ede7927c88eef312c linux-3.0/sound/usb/usx2y/us122l.h -6340574b5ff23673a1b2eca68ddf19a9 linux-3.0/sound/usb/usx2y/us122l.c -cd385bbdac95b601a1d425505cddf069 linux-3.0/sound/usb/usx2y/Makefile -c67d7ea6556a782f051f207d5925dbde linux-3.0/sound/usb/usbaudio.h -fb6ecbfc04e97a4c85e2eb2707e052ba linux-3.0/sound/usb/urb.h -05922156a57a876fe27aecff23fd8942 linux-3.0/sound/usb/urb.c -428238069b9ad00709112596e3956b66 linux-3.0/sound/usb/quirks.h -9480f1963c4e0e189d35e82df833a8a0 linux-3.0/sound/usb/quirks.c -040ab807b72561e4739dc8205a48a0b6 linux-3.0/sound/usb/quirks-table.h -ec80cf5b9d1fd20ed379530610b7584c linux-3.0/sound/usb/proc.h -a168f2e76ea9d342b3b8890ae29cf6a7 linux-3.0/sound/usb/proc.c -d1b5d46c62a18f67a983feaad933b9ab linux-3.0/sound/usb/power.h -76da4253e3c07626dfaee30766107ad2 linux-3.0/sound/usb/pcm.h -cdd4fc911c96b352dca8624fbaf6cd6a linux-3.0/sound/usb/pcm.c -944c77c7b5dea1afb2d7c29d018a9bdf linux-3.0/sound/usb/mixer_quirks.h -43b3f282acecf30ec809f0d3e9e0ff07 linux-3.0/sound/usb/mixer_quirks.c -e39d2dad088aa936c3e010de9a290b6f linux-3.0/sound/usb/mixer_maps.c -6f2bc0def2d854379e8ad47af4f3e139 linux-3.0/sound/usb/mixer.h -882d5b7b4c6853cfca112ae44205a2b7 linux-3.0/sound/usb/mixer.c -8c032db196836c5b0c9f00cf4f9577e7 linux-3.0/sound/usb/misc/ua101.c -b033844feb8127eae70a301b27c2afce linux-3.0/sound/usb/misc/Makefile -4f2ad22746a841f57c30d1b103a6e99f linux-3.0/sound/usb/midi.h -bc975de6f3dea59ef0da852946e02816 linux-3.0/sound/usb/midi.c -ae453b21a0d4766620e9b7fc8ff732c4 linux-3.0/sound/usb/helper.h -a0cb66e1abf7c5f334e928232d8b1551 linux-3.0/sound/usb/helper.c -a8309597e49a387034ffe70e1b4ff35d linux-3.0/sound/usb/format.h -967646dcbd64eebb5f08a10d12e60918 linux-3.0/sound/usb/format.c -419b72e17464db58b8a4cd302d415cf5 linux-3.0/sound/usb/endpoint.h -6a30480c77048e1e54454976d479ac20 linux-3.0/sound/usb/endpoint.c -c9aba805def6716594b1923a6f43ab51 linux-3.0/sound/usb/debug.h -7c30c007ebcf3a8988d06b7fb696cf49 linux-3.0/sound/usb/clock.h -1e50575a0573d6d5ddd1d531768e1a51 linux-3.0/sound/usb/clock.c -32182a29a7b5bd2d4d1290f015896e76 linux-3.0/sound/usb/card.h -8970be9d950272c44de5f7d2e250c82e linux-3.0/sound/usb/card.c -d7e2d4d04b59260f7345af3d78b38831 linux-3.0/sound/usb/caiaq/midi.h -5c6ab8f48ff68c484ff3bf1ff738eb47 linux-3.0/sound/usb/caiaq/midi.c -737d2335ee636199a673768c3b38561e linux-3.0/sound/usb/caiaq/input.h -f989f57accb68826d468f42dbb29e722 linux-3.0/sound/usb/caiaq/input.c -49ca099c283ce65c275798c49f9f9af2 linux-3.0/sound/usb/caiaq/device.h -23de2aabbbacd2b4b19576c6f1e77aa8 linux-3.0/sound/usb/caiaq/device.c -6388fec88dd65e51e3203af0dd945dad linux-3.0/sound/usb/caiaq/control.h -4de3f2c0ecf9720451dee19ec82522e0 linux-3.0/sound/usb/caiaq/control.c -a46352ebaea75b90541e1e3cb58663b3 linux-3.0/sound/usb/caiaq/audio.h -c6d230ac02003f347cecdc772aca6c01 linux-3.0/sound/usb/caiaq/audio.c -100b4b2301f6081daefd0784e3a3fa16 linux-3.0/sound/usb/caiaq/Makefile -c06316d3cd7ea3173dc66755e038746b linux-3.0/sound/usb/Makefile -d218fc33bfbc493e80ef28a9f9d0a74b linux-3.0/sound/usb/Kconfig -049a54881438e49d087f8d03fad199da linux-3.0/sound/usb/6fire/pcm.h -c0df608d089594ae0361cbd6e6775802 linux-3.0/sound/usb/6fire/pcm.c -73576ff017218bdf6b80a0dfcca280a0 linux-3.0/sound/usb/6fire/midi.h -74ed60b18280f5d6fe45c8a416e7462b linux-3.0/sound/usb/6fire/midi.c -9c78ebf51165c74edf08e5791bc7fb9c linux-3.0/sound/usb/6fire/firmware.h -eda8c202e8579b4cfc10bef75f19b994 linux-3.0/sound/usb/6fire/firmware.c -b8fcc8548df605e694ecbac71a994d8d linux-3.0/sound/usb/6fire/control.h -ccec83b1802add4bb6c82513f5620532 linux-3.0/sound/usb/6fire/control.c -04d06f72f260922d8ca593206018b986 linux-3.0/sound/usb/6fire/common.h -7e6bf829906b5906987dfbe28e70670a linux-3.0/sound/usb/6fire/comm.h -3503662d76989cb325d3486a613dcbbf linux-3.0/sound/usb/6fire/comm.c -9e4c3e4853c9b80f1142b1f58eda6dc6 linux-3.0/sound/usb/6fire/chip.h -5b5124692fe3688f1b5a4648e382913d linux-3.0/sound/usb/6fire/chip.c -71e72ec0f50342023c1cf6d870a3d50a linux-3.0/sound/usb/6fire/Makefile -c4ec639f36f653d26d6a005a96327196 linux-3.0/sound/synth/util_mem.c -72bafbb71cd70bdf41ee43efe77b8240 linux-3.0/sound/synth/emux/soundfont.c -54a7cf4b5a92ce473cbe9eaf47ec6606 linux-3.0/sound/synth/emux/emux_voice.h -89176744ebc679999fbfe29b1fd09876 linux-3.0/sound/synth/emux/emux_synth.c -0b35dec1007d98b43a0d9eb6be8d8391 linux-3.0/sound/synth/emux/emux_seq.c -a52028a135ae20101b63299b3690116a linux-3.0/sound/synth/emux/emux_proc.c -c107707560bcd87ce20389ad4c35c6f4 linux-3.0/sound/synth/emux/emux_oss.c -e0cb274e99af2295570667baf9bc4799 linux-3.0/sound/synth/emux/emux_nrpn.c -e71cc7a527b15fa01b08a8e95917c567 linux-3.0/sound/synth/emux/emux_hwdep.c -9db8487dc3981cd7a528b0aeadb83bd0 linux-3.0/sound/synth/emux/emux_effect.c -815cf03bccdac0009ba9ef1a0f57e5b5 linux-3.0/sound/synth/emux/emux.c -6ca5c6817efad521dcb8e21359a4bb1a linux-3.0/sound/synth/emux/Makefile -0521b52ac764d8d0c98ad720c59e5ae0 linux-3.0/sound/synth/Makefile -a3cb59cce1d7a47f5771c2f11706f5f4 linux-3.0/sound/spi/at73c213.h -6bfbd68287170e618b133d58804591db linux-3.0/sound/spi/at73c213.c -81b963606e39d26aba2c97d553109780 linux-3.0/sound/spi/Makefile -92f6027a13f300bc7637f123c5ef54f1 linux-3.0/sound/spi/Kconfig -649ea4d7ab406c76f9d9ee6db61ce7c2 linux-3.0/sound/sparc/dbri.c -5033b20a760e403bee67011b570de181 linux-3.0/sound/sparc/cs4231.c -6b710da3384470646a817bceff52cbb0 linux-3.0/sound/sparc/amd7930.c -d7fc1e82e4dee3e12916d352b905969b linux-3.0/sound/sparc/Makefile -734d1c7369f9364947737f0e68207824 linux-3.0/sound/sparc/Kconfig -f817c5d398488344b14afe6a12b3dd6b linux-3.0/sound/sound_firmware.c -b39a7ac99ded21a1bf5bf92bf8da3650 linux-3.0/sound/sound_core.c -ef81d1f0d189737155023d0cd3778ab8 linux-3.0/sound/soc/txx9/txx9aclc.h -1292957473dcbf06601036c21d6e0523 linux-3.0/sound/soc/txx9/txx9aclc.c -b47dc636a225b84ee6037bd11dd72a28 linux-3.0/sound/soc/txx9/txx9aclc-generic.c -1b1b2e857401013ce70dfe0c9111336c linux-3.0/sound/soc/txx9/txx9aclc-ac97.c -6e9356a04e631fd557c7f53d7001f33c linux-3.0/sound/soc/txx9/Makefile -5e4433721cd5eb73591c180d0f1e85fc linux-3.0/sound/soc/txx9/Kconfig -6ddbac39284ed646318f15da12294bed linux-3.0/sound/soc/tegra/trimslice.c -6fe70940131cac002f8cec8d09f3a676 linux-3.0/sound/soc/tegra/tegra_wm8903.c -8cab9e6ff04e786c03a5132aff350eb4 linux-3.0/sound/soc/tegra/tegra_pcm.h -e1a511cbb99c0f8873213a7d32637fed linux-3.0/sound/soc/tegra/tegra_pcm.c -b71bbcb64a922d1e7bc71f9edf04a688 linux-3.0/sound/soc/tegra/tegra_i2s.h -5263e2686c0329618bbfc585e7e9ec3b linux-3.0/sound/soc/tegra/tegra_i2s.c -ea58d0b5b0a6252ed49237e9341facf5 linux-3.0/sound/soc/tegra/tegra_das.h -d6224850bcf007f589647e2f02fd45b2 linux-3.0/sound/soc/tegra/tegra_das.c -6b12d9809409a882f74640b686e4a2bf linux-3.0/sound/soc/tegra/tegra_asoc_utils.h -972bfd0ccc188cbb4fe1b8241baedfee linux-3.0/sound/soc/tegra/tegra_asoc_utils.c -ed62a352e765169e88482741ee23b97b linux-3.0/sound/soc/tegra/Makefile -619d90a69ff3be34c895d22c2a76156a linux-3.0/sound/soc/tegra/Kconfig -597d8025d17f846c9bdd58bd956adc5a linux-3.0/sound/soc/soc-utils.c -4a51e6b715c0a7be2aedbf85128be5ab linux-3.0/sound/soc/soc-jack.c -541038cea8bc3eb36d0c2d27b660a46a linux-3.0/sound/soc/soc-dapm.c -12548ac517019b542f0a5b1b681749b8 linux-3.0/sound/soc/soc-core.c -04437e5b6380703764c607b778e6438d linux-3.0/sound/soc/soc-cache.c -0ae012a4139d887af7db7deb3312dead linux-3.0/sound/soc/sh/ssi.c -1de11a4592df561a1002edf631a5745b linux-3.0/sound/soc/sh/siu_pcm.c -6d1b30b96c850d1b5d31240cdd07446f linux-3.0/sound/soc/sh/siu_dai.c -5a19537d39a3cc59a769a81633a26844 linux-3.0/sound/soc/sh/siu.h -801cc12002929d70426ecd1eb9dea514 linux-3.0/sound/soc/sh/sh7760-ac97.c -ee0491934d2710204291fd8114358888 linux-3.0/sound/soc/sh/migor.c -2b2d108f35faa04a36b01d24d9ddf27f linux-3.0/sound/soc/sh/hac.c -69e28a2792c9e450c80f10a5d96fdfaa linux-3.0/sound/soc/sh/fsi.c -8f9afee5dcb8c4cc2d3a36be95c06982 linux-3.0/sound/soc/sh/fsi-hdmi.c -52cb0623384e8368b2ecc05ed82e2106 linux-3.0/sound/soc/sh/fsi-da7210.c -ac1ee3366626d33395d02e634c26c67c linux-3.0/sound/soc/sh/fsi-ak4642.c -b9459c7774374b8d6528b8eb33963ff3 linux-3.0/sound/soc/sh/dma-sh7760.c -ee325a9e7a9d9ed448f4c51fee7b0ab9 linux-3.0/sound/soc/sh/Makefile -98f88fbb8c2f924c8ef20a5753bc8dbb linux-3.0/sound/soc/sh/Kconfig -50a1044686733db37db36cebeb0a3d17 linux-3.0/sound/soc/samsung/speyside.c -18d588e382d8a81ea31ab3bed3c82fea linux-3.0/sound/soc/samsung/spdif.h -414285e492187173197dd0aadec984f3 linux-3.0/sound/soc/samsung/spdif.c -62267da60a4843c94d23a37e7b27b6b6 linux-3.0/sound/soc/samsung/smdk_wm9713.c -96be8ff1e10627f3bb357b815cbdb7ce linux-3.0/sound/soc/samsung/smdk_wm8994.c -281679b2abb348c2d264b4c5c0fc6ed0 linux-3.0/sound/soc/samsung/smdk_wm8580pcm.c -08947dfc33bf85d1b495f29e9b3d5190 linux-3.0/sound/soc/samsung/smdk_wm8580.c -1143e0eceea27b959616bab0a294bb52 linux-3.0/sound/soc/samsung/smdk_spdif.c -b31544606114a5bd37a774eb782ab62f linux-3.0/sound/soc/samsung/smdk2443_wm9710.c -9d2a2adbe4b89603d60b7dd1ee6b0a23 linux-3.0/sound/soc/samsung/smartq_wm8987.c -a007e8fe435f46d7e9248d944100b8de linux-3.0/sound/soc/samsung/s3c24xx_uda134x.c -34cdcefcc0184bfa82439fcede7f3633 linux-3.0/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c -60a5570c6f175e4ca3ef69eb529120c4 linux-3.0/sound/soc/samsung/s3c24xx_simtec_hermes.c -0126e0f0ef7ef99496649527db8d0296 linux-3.0/sound/soc/samsung/s3c24xx_simtec.h -4d0ac3005b15d21001974d06d4a47a80 linux-3.0/sound/soc/samsung/s3c24xx_simtec.c -54804e1eeea72cf1d4bc13657155b4ce linux-3.0/sound/soc/samsung/s3c24xx-i2s.h -4ffb0594924b1832039e176f5b0bd5a1 linux-3.0/sound/soc/samsung/s3c24xx-i2s.c -211afd814ee26f6f83f40f24667bc621 linux-3.0/sound/soc/samsung/s3c2412-i2s.h -4d5c243a2ad9c8f80e116c80b7b9cdb0 linux-3.0/sound/soc/samsung/s3c2412-i2s.c -4045a8c63b8daa62a280a0423c73d751 linux-3.0/sound/soc/samsung/s3c-i2s-v2.h -d07bad2d05d73209861ddd02c6f4dc29 linux-3.0/sound/soc/samsung/s3c-i2s-v2.c -502d233e7218db0296ef00d3ad672a8e linux-3.0/sound/soc/samsung/rx1950_uda1380.c -16a6870a701c4244b4a554e7b5a612f7 linux-3.0/sound/soc/samsung/regs-i2s-v2.h -ea6897fb5ebffdae2a64996f83f8a88c linux-3.0/sound/soc/samsung/pcm.h -8ac98cc6735893a2781530bfaab9ffde linux-3.0/sound/soc/samsung/pcm.c -8f07706975b04eb51a155a12d7cc37f1 linux-3.0/sound/soc/samsung/neo1973_wm8753.c -ce96a834e709748f1779f7798bef1bc7 linux-3.0/sound/soc/samsung/ln2440sbc_alc650.c -35e5db2c8365c5fa11b41e4986214427 linux-3.0/sound/soc/samsung/jive_wm8750.c -867a5a02802e75593e1f31d4a0d00af6 linux-3.0/sound/soc/samsung/i2s.h -48f7e9d33094c7c3cdfa3eb9c234e5be linux-3.0/sound/soc/samsung/i2s.c -3f148c5ccc8bb82f496df75c0717c6c5 linux-3.0/sound/soc/samsung/h1940_uda1380.c -d2129620bf4afb7e79cd8322d906d065 linux-3.0/sound/soc/samsung/goni_wm8994.c -793b0437551be4b2857bb27369b80767 linux-3.0/sound/soc/samsung/dma.h -32b3e1eb0fe577eed66d578be4126c9a linux-3.0/sound/soc/samsung/dma.c -e453f93a6ab5c3b44973b1d4d75a8245 linux-3.0/sound/soc/samsung/ac97.c -26fac6899b16ec8e2060f53280b957c1 linux-3.0/sound/soc/samsung/Makefile -4ed6620f7ef27897fe5aa9896d0d7a68 linux-3.0/sound/soc/samsung/Kconfig -cdeca89d1996ef81f5a3ac814a946267 linux-3.0/sound/soc/s6000/s6105-ipcam.c -6efc3d9268f7104456e6cdd170feb0ce linux-3.0/sound/soc/s6000/s6000-pcm.h -1fca1e5905482a345fde61ad341948c9 linux-3.0/sound/soc/s6000/s6000-pcm.c -4b6ee4547c13432fffdee33d2c6379ce linux-3.0/sound/soc/s6000/s6000-i2s.h -182794523e283432bc3f26b66583377c linux-3.0/sound/soc/s6000/s6000-i2s.c -eb0a520d75e7a2b64b97215d00d53069 linux-3.0/sound/soc/s6000/Makefile -62bcad2d8be3b2cf1cbc870830d343a5 linux-3.0/sound/soc/s6000/Kconfig -5c33f2468a95c61d8eefc22147d8ddc1 linux-3.0/sound/soc/pxa/zylonite.c -febdc17fafa1781ad512dd16e87008a8 linux-3.0/sound/soc/pxa/z2.c -0b29f615322ce006d8c4cad436c2ec99 linux-3.0/sound/soc/pxa/tosa.c -c2edd2a9e8303605f3db6e0cd84388a0 linux-3.0/sound/soc/pxa/tavorevb3.c -968e18c1ceae53f7481f17bee74ae3b5 linux-3.0/sound/soc/pxa/spitz.c -1655b87d8b8947387e0896db255e1b9f linux-3.0/sound/soc/pxa/saarb.c -0e8e46bc4cd45dcf8db0944cc752696a linux-3.0/sound/soc/pxa/raumfeld.c -756bd0033af961c8c8bb711914670e68 linux-3.0/sound/soc/pxa/pxa2xx-pcm.c -7dc7d52d19d4a48d534404beb23080e7 linux-3.0/sound/soc/pxa/pxa2xx-i2s.h -c40a3b7dfec98fa9fe6c4f8a9c858866 linux-3.0/sound/soc/pxa/pxa2xx-i2s.c -9510ae1236a48d8fe571dad338a84fcd linux-3.0/sound/soc/pxa/pxa2xx-ac97.h -234c640066fbe7bd105314bc2495080a linux-3.0/sound/soc/pxa/pxa2xx-ac97.c -e72957dbd6d82eeab604fb2dde7af08d linux-3.0/sound/soc/pxa/pxa-ssp.h -59f28a4ddc5085d5cf758b939fb9155b linux-3.0/sound/soc/pxa/pxa-ssp.c -4946e631abcd983af41f47963ca1e5df linux-3.0/sound/soc/pxa/poodle.c -9eb4790f82c5100a1ab38915f796e500 linux-3.0/sound/soc/pxa/palm27x.c -0b8df7d283414e6856a0c6680043b9fe linux-3.0/sound/soc/pxa/mioa701_wm9713.c -9a2a293568758f78820dcc9e71777b68 linux-3.0/sound/soc/pxa/magician.c -06ccdd3a064a792d1e11623207d7c820 linux-3.0/sound/soc/pxa/imote2.c -8b558017a2e0b482a292292ba3542b45 linux-3.0/sound/soc/pxa/hx4700.c -9789a127a8b7879bba05be0f6f0ec0cc linux-3.0/sound/soc/pxa/em-x270.c -4fbb97790aac552cfcc552db49dfc093 linux-3.0/sound/soc/pxa/e800_wm9712.c -9317746d3606f5bda46902eeb57adcf8 linux-3.0/sound/soc/pxa/e750_wm9705.c -78e3990eabdf8fc46500bbb48014017b linux-3.0/sound/soc/pxa/e740_wm9705.c -449b54400fb0375d3dbbe7676627597b linux-3.0/sound/soc/pxa/corgi.c -7ebe56d46975b3c3418f640a462086e5 linux-3.0/sound/soc/pxa/Makefile -d94328b0ebcd644db8bdb6ab87699163 linux-3.0/sound/soc/pxa/Kconfig -adb7c897029e7c5213a117bd7fbaf3ff linux-3.0/sound/soc/omap/zoom2.c -8baf0698e7c83e2979ce04d81ba3ccfe linux-3.0/sound/soc/omap/sdp4430.c -09a1971a9401b28702d4749abe16f1cb linux-3.0/sound/soc/omap/sdp3430.c -91b43becd1811b3e7cf3bc4061116b58 linux-3.0/sound/soc/omap/rx51.c -9f70265adf36208f5228f6edc9025d93 linux-3.0/sound/soc/omap/overo.c -c8f3baaa75a4db1163b1e134df3ae065 linux-3.0/sound/soc/omap/osk5912.c -8ae0efa64a48bf1f701a5db70f44b487 linux-3.0/sound/soc/omap/omap3pandora.c -fdd0e522e5337cf9a3336acc8a49c7a3 linux-3.0/sound/soc/omap/omap3evm.c -b1359f59dfe9b991aba9058a0dee8044 linux-3.0/sound/soc/omap/omap3beagle.c -0a005ea8f4a286ddbea5c52f12f3cfaf linux-3.0/sound/soc/omap/omap-pcm.h -843ec660ab28139e336dace482b6b863 linux-3.0/sound/soc/omap/omap-pcm.c -0e46e2b7b0f00e58b174b79260ccbbec linux-3.0/sound/soc/omap/omap-mcpdm.c -21a741c96172cd0ffe316251ac1cac0b linux-3.0/sound/soc/omap/omap-mcbsp.h -7085b63039db44525f62cd5eb8163b0d linux-3.0/sound/soc/omap/omap-mcbsp.c -2d56c7557ef7be5aa5811cb67500f6c8 linux-3.0/sound/soc/omap/n810.c -7f63862a28d2a91821461bb00af85b43 linux-3.0/sound/soc/omap/mcpdm.h -172371794b2036edb5e3765c01fe0e41 linux-3.0/sound/soc/omap/mcpdm.c -af44b24ea737c91e8aace7fc63529435 linux-3.0/sound/soc/omap/igep0020.c -cf2fd98c24682da02e7116efd9cbedaf linux-3.0/sound/soc/omap/ams-delta.c -0ffe0b641eeb1e4864e8222d62b8b078 linux-3.0/sound/soc/omap/am3517evm.c -95b88df32427eca44db15a77618005b2 linux-3.0/sound/soc/omap/Makefile -ea5c129a7fc95ee9787b2b8317075ca8 linux-3.0/sound/soc/omap/Kconfig -e3e310029663442a97977832e5a24b5e linux-3.0/sound/soc/nuc900/nuc900-pcm.c -1a1a183899639bd26e4a08f2ed91bdec linux-3.0/sound/soc/nuc900/nuc900-audio.h -ab5cbd8c9f913fef7bef63208c8cb078 linux-3.0/sound/soc/nuc900/nuc900-audio.c -3a0ff072f73d4d6c77748bacf7dab2fc linux-3.0/sound/soc/nuc900/nuc900-ac97.c -23ba131a39f26bbe7d55d9410a8d1828 linux-3.0/sound/soc/nuc900/Makefile -5b502242c1d7fb0fcd1bd3c5c320a383 linux-3.0/sound/soc/nuc900/Kconfig -2e2a3f284c96b9e42cc4eba0b14e7f69 linux-3.0/sound/soc/mid-x86/sst_platform.h -9064d043ddc90712840d4d102c5acdab linux-3.0/sound/soc/mid-x86/sst_platform.c -4d0a6f286c0c0951d2707b9c3cfc2887 linux-3.0/sound/soc/mid-x86/mfld_machine.c -8ee38bd871049b46725cb100e097708d linux-3.0/sound/soc/mid-x86/Makefile -a83cd6a27be703099121e5b2aea0c603 linux-3.0/sound/soc/mid-x86/Kconfig -d14ed2ee2eb29d7aedabe7a6e61ce229 linux-3.0/sound/soc/kirkwood/kirkwood.h -abc7e355181ffe4a8f62c5e70d57aa63 linux-3.0/sound/soc/kirkwood/kirkwood-t5325.c -fe5a36f57bd26c22a90df36fec5962d4 linux-3.0/sound/soc/kirkwood/kirkwood-openrd.c -9712a21cef01a51ab9ca1669f52c6844 linux-3.0/sound/soc/kirkwood/kirkwood-i2s.c -c7d2558ce2e1cd6ae86b1fcb19f79978 linux-3.0/sound/soc/kirkwood/kirkwood-dma.c -ff552723e35be215277b108b9250933a linux-3.0/sound/soc/kirkwood/Makefile -770872fc98c4344a3cf07350e32849dc linux-3.0/sound/soc/kirkwood/Kconfig -92e7e2664e201aa1031060cdd2025847 linux-3.0/sound/soc/jz4740/qi_lb60.c -d98d0eb22a9afe0a0118e59f8b4d5db1 linux-3.0/sound/soc/jz4740/jz4740-pcm.h -f0bb6185c35e4c57616286ae2018f2a9 linux-3.0/sound/soc/jz4740/jz4740-pcm.c -a4d839d530d972f07b2d753bbfdaeeff linux-3.0/sound/soc/jz4740/jz4740-i2s.h -876497decf815ebb435cdd49942dc739 linux-3.0/sound/soc/jz4740/jz4740-i2s.c -ae1870cc4df488d762879262ba475d15 linux-3.0/sound/soc/jz4740/Makefile -25592518ca68ad638fae0cff371f0150 linux-3.0/sound/soc/jz4740/Kconfig -b7e54fb6f11e4a8978bbfce0218a3198 linux-3.0/sound/soc/imx/wm1133-ev1.c -b39a4abd3970aeff44f33e9566cb0020 linux-3.0/sound/soc/imx/phycore-ac97.c -35f4b1d1b30fb540c5822ac62ef74579 linux-3.0/sound/soc/imx/mx27vis-aic32x4.c -15d61e2c60b9bcd79ef514d919d250f3 linux-3.0/sound/soc/imx/imx-ssi.h -90da63017b162b2b8dbbd7f730cf85e9 linux-3.0/sound/soc/imx/imx-ssi.c -6e983448aff60d33468f4fc6ec04ab56 linux-3.0/sound/soc/imx/imx-pcm-fiq.c -304691b4adb5b4f32e060aac319842d0 linux-3.0/sound/soc/imx/imx-pcm-dma-mx2.c -855bf5c512b4ec7e937dbffec716b804 linux-3.0/sound/soc/imx/eukrea-tlv320.c -8f4b08d6e892f8d050ab37f3872251e5 linux-3.0/sound/soc/imx/Makefile -4b41c348ba4bb6d402a0aa70ba2a0dcb linux-3.0/sound/soc/imx/Kconfig -d9f0bf05413ff2ebfbd72310537d626e linux-3.0/sound/soc/fsl/pcm030-audio-fabric.c -2844a0f3ba2dfa998da94f120acc5312 linux-3.0/sound/soc/fsl/p1022_ds.c -e08c2db7dbcb72a6e5ea71e7c1cba6b4 linux-3.0/sound/soc/fsl/mpc8610_hpcd.c -74a71b37cbd226fb712ccfda1d5bbe97 linux-3.0/sound/soc/fsl/mpc5200_psc_i2s.c -45a3f98bc702e3147f761db259dea997 linux-3.0/sound/soc/fsl/mpc5200_psc_ac97.h -318ab9552fc8318d43eaea0f589b7d62 linux-3.0/sound/soc/fsl/mpc5200_psc_ac97.c -8bc4d73895bcf80f5b9ad7d3d9a5cc84 linux-3.0/sound/soc/fsl/mpc5200_dma.h -8f128d66a4e44ba6c06c989668ebcf87 linux-3.0/sound/soc/fsl/mpc5200_dma.c -df9e73bb2e2101a7d2d7876ff128c930 linux-3.0/sound/soc/fsl/fsl_ssi.h -7ffa6e6aa9228546d3c09b35730104a8 linux-3.0/sound/soc/fsl/fsl_ssi.c -8ad155907fde8ca247a5fef4aa08a3f8 linux-3.0/sound/soc/fsl/fsl_dma.h -c4a622ce680e3f9ff93ac313fcfe4605 linux-3.0/sound/soc/fsl/fsl_dma.c -1d29579cef18b5a244c86f56b591d1d4 linux-3.0/sound/soc/fsl/efika-audio-fabric.c -652303cf97111306ee056d2af1246927 linux-3.0/sound/soc/fsl/Makefile -0d3b789c879931aef84c9650ccd2754c linux-3.0/sound/soc/fsl/Kconfig -e44652aaf19bfc1b1451e86f9c8d9bb1 linux-3.0/sound/soc/ep93xx/snappercl15.c -f8771deb34f8e2c361f058aa503da794 linux-3.0/sound/soc/ep93xx/simone.c -f30b90d43c4bccaf0c592dfbd5d01a96 linux-3.0/sound/soc/ep93xx/ep93xx-pcm.h -bc1a334a2971767b8b8c649e2d5b7f5d linux-3.0/sound/soc/ep93xx/ep93xx-pcm.c -ddde4f4234ad89b8eb34c3aeb1ea99f6 linux-3.0/sound/soc/ep93xx/ep93xx-i2s.c -e075c2aa466a195ee8755041e29c3356 linux-3.0/sound/soc/ep93xx/ep93xx-ac97.c -9ff0a4e935d545d0720b7babb82ec2af linux-3.0/sound/soc/ep93xx/edb93xx.c -f3a8c9d7a460de808c01c2c6966da990 linux-3.0/sound/soc/ep93xx/Makefile -f106f689a23374a20f82c888d8e5bd78 linux-3.0/sound/soc/ep93xx/Kconfig -08648d8e7097cbc2dfb51bd44f0ac9ed linux-3.0/sound/soc/davinci/davinci-vcif.c -f3c3b8774d4784240878ffb70888f169 linux-3.0/sound/soc/davinci/davinci-sffsdr.c -222e6339d103ddbe6e4903f2490c9e0a linux-3.0/sound/soc/davinci/davinci-pcm.h -70c6f93e26c508c3e91023e7d9ffae60 linux-3.0/sound/soc/davinci/davinci-pcm.c -d37c12a62eedd91a20b8452518e9aca7 linux-3.0/sound/soc/davinci/davinci-mcasp.h -d2e8d31b468119da561b9915aee015ce linux-3.0/sound/soc/davinci/davinci-mcasp.c -4f6d6e3f54098a711b8c9bcb259368d9 linux-3.0/sound/soc/davinci/davinci-i2s.h -8d97e74861b276576cd450eb2796409d linux-3.0/sound/soc/davinci/davinci-i2s.c -5e7e4a868e85c5640b22537323b34378 linux-3.0/sound/soc/davinci/davinci-evm.c -b7a6a0234b9c2d55f82e250fb050c560 linux-3.0/sound/soc/davinci/Makefile -04bd46775b9f318011b60808a43802f2 linux-3.0/sound/soc/davinci/Kconfig -dbe990716ff2623195e56e604a51b04b linux-3.0/sound/soc/codecs/wm_hubs.h -7f60434d20c3f4042c85ffbd9811f165 linux-3.0/sound/soc/codecs/wm_hubs.c -ca6bb1425182e5f44c6c4bc7e1ca00ba linux-3.0/sound/soc/codecs/wm9713.h -410d585dd7e74257c157fe8cda80d498 linux-3.0/sound/soc/codecs/wm9713.c -38bc88257bc49bf1321dba0d0bcbe3d8 linux-3.0/sound/soc/codecs/wm9712.h -b4a447d33e677f8c4fc02f4c5129134d linux-3.0/sound/soc/codecs/wm9712.c -9ef51ddc7be44a56b1633d6e08d7eb2f linux-3.0/sound/soc/codecs/wm9705.h -2d7d774daf86a3cc5198ad7c2d78bb22 linux-3.0/sound/soc/codecs/wm9705.c -3e2df84d5a30f2a7c8acd75ecb5dc3bd linux-3.0/sound/soc/codecs/wm9090.h -426e23afae2a87a7f578f72901948732 linux-3.0/sound/soc/codecs/wm9090.c -d573af08306cb3b0ddebd8cd5ba38cdf linux-3.0/sound/soc/codecs/wm9081.h -42c1c15db8e4230902fff324e6dfabd1 linux-3.0/sound/soc/codecs/wm9081.c -c6c1f267c600dbd55d98fa0bcd0227b8 linux-3.0/sound/soc/codecs/wm8995.h -f85bf044a546be0a2097c3b315e0e6fb linux-3.0/sound/soc/codecs/wm8995.c -e9fec1be7fd8da8d6dc87e701fb2e023 linux-3.0/sound/soc/codecs/wm8994.h -5fa46aee2a07ea95604736b74f81eb9b linux-3.0/sound/soc/codecs/wm8994.c -dd8f6ba6e49d1b2c705455c2fcee7783 linux-3.0/sound/soc/codecs/wm8994-tables.c -1565df5157064c749103dfca32a8c512 linux-3.0/sound/soc/codecs/wm8993.h -d0c00656801aef97c561dead5c574035 linux-3.0/sound/soc/codecs/wm8993.c -c08d4ba946cdbb8e4c101c3dbb398d91 linux-3.0/sound/soc/codecs/wm8991.h -0956c7fadb5c13734eff723f8db0f325 linux-3.0/sound/soc/codecs/wm8991.c -52f3d9b31e1ddb7f060068cfa0008edf linux-3.0/sound/soc/codecs/wm8990.h -1a2c00d11d3974e7e27a71165cb16d31 linux-3.0/sound/soc/codecs/wm8990.c -83a36c9ca537ceec5dafa47690bc99d7 linux-3.0/sound/soc/codecs/wm8988.h -c0b3c05f85e92af0b2c6c6064eb931ac linux-3.0/sound/soc/codecs/wm8988.c -6233845e35f9040d579943c0289364ec linux-3.0/sound/soc/codecs/wm8985.h -64aba7d4ac50f0b16833e34db6d071ce linux-3.0/sound/soc/codecs/wm8985.c -62a81ff42e02c53adc1aab94f0bb191d linux-3.0/sound/soc/codecs/wm8978.h -13b1cdb976a154b818ca44c7fd7cfd16 linux-3.0/sound/soc/codecs/wm8978.c -a0d1ebfe7f4d9acbddac9db1b2f1dec0 linux-3.0/sound/soc/codecs/wm8974.h -2bdf9f921e0324d93883a6655fb02bf6 linux-3.0/sound/soc/codecs/wm8974.c -00c4ff0b3e89402feee1df0491a4b598 linux-3.0/sound/soc/codecs/wm8971.h -4568fdb9f3054c1e1a6a8df01e53e6e6 linux-3.0/sound/soc/codecs/wm8971.c -139a62462bf9cb34949a05c5df9b8294 linux-3.0/sound/soc/codecs/wm8962.h -9043a00ab1b4a27734f6ac0824e03910 linux-3.0/sound/soc/codecs/wm8962.c -9f5069aba436864494f278cbfdbb00a0 linux-3.0/sound/soc/codecs/wm8961.h -05dec8b0e76f676fed46fd3858ad47a7 linux-3.0/sound/soc/codecs/wm8961.c -c239614e1bd6c5dc8df47409d3d265fc linux-3.0/sound/soc/codecs/wm8960.h -554ba490b01c5bbb523c4ec1962041cb linux-3.0/sound/soc/codecs/wm8960.c -f138afa0ffb8e7b4b8a700c3cb5140c8 linux-3.0/sound/soc/codecs/wm8958-dsp2.c -5d02914dfb9372e866020425c0d221b5 linux-3.0/sound/soc/codecs/wm8955.h -dfba013bf8f4bb63571876a88a86327e linux-3.0/sound/soc/codecs/wm8955.c -a2bd170c6f68ff4c6261a4645720cbf7 linux-3.0/sound/soc/codecs/wm8940.h -610467d7add2a4fb21ef0ab5a61d49e6 linux-3.0/sound/soc/codecs/wm8940.c -54d672c66ba67a444683fe20c25c7d9d linux-3.0/sound/soc/codecs/wm8915.h -0c8cd9470b8bb0c04fef3d2f53151aba linux-3.0/sound/soc/codecs/wm8915.c -426974d92e2cf991fca6fdfb732b2481 linux-3.0/sound/soc/codecs/wm8904.h -984c7c65afb19c6c282fe88a3edc2ea0 linux-3.0/sound/soc/codecs/wm8904.c -281c0b2a528ab479c68a4f7f1fd50536 linux-3.0/sound/soc/codecs/wm8903.h -d0e547a0fd8d9c996296b85f4077561e linux-3.0/sound/soc/codecs/wm8903.c -da53a2e38b5539ce972737813b58b39c linux-3.0/sound/soc/codecs/wm8900.h -18df17d7c5b0bc9b24fd7ffee6c1e1a3 linux-3.0/sound/soc/codecs/wm8900.c -9604a9fd28b728edfc5d56ed6be204d7 linux-3.0/sound/soc/codecs/wm8804.h -e3bead02a9e9bdd4c454e01d46cfd82b linux-3.0/sound/soc/codecs/wm8804.c -3d4c8fc84202254ed55144a6bd8e4167 linux-3.0/sound/soc/codecs/wm8776.h -409dc1802a4b80158a094cb998847a81 linux-3.0/sound/soc/codecs/wm8776.c -b9e06496a0de5f2b6945a0f65f615b42 linux-3.0/sound/soc/codecs/wm8770.h -26ebdb88b3e270a8fdad8a0c1eb1011e linux-3.0/sound/soc/codecs/wm8770.c -c8794141cf237002ec56231622cac674 linux-3.0/sound/soc/codecs/wm8753.h -9327976bf558cde3a95bb389cde53958 linux-3.0/sound/soc/codecs/wm8753.c -979b2cd650f674cddfeb418e69378133 linux-3.0/sound/soc/codecs/wm8750.h -1f372d0a62f99137bf11c5fe6dd23cdc linux-3.0/sound/soc/codecs/wm8750.c -2e9a78ae51862f447ee29aa50f3e5da6 linux-3.0/sound/soc/codecs/wm8741.h -9389ef6110127b0a4b81d7a2b5af6b59 linux-3.0/sound/soc/codecs/wm8741.c -451117bd860ad8f6ee3609ea0d163bd1 linux-3.0/sound/soc/codecs/wm8737.h -63bc32da5d7a1ab8e3ea553e032417e4 linux-3.0/sound/soc/codecs/wm8737.c -a6f82f20fb7a63099d35b3cef4fbde42 linux-3.0/sound/soc/codecs/wm8731.h -8edcdede472d92e23f404f0971569bb4 linux-3.0/sound/soc/codecs/wm8731.c -0462450f054e4640840c8536ed3daaa8 linux-3.0/sound/soc/codecs/wm8728.h -23a67760c218d1fc0cf90c5e8688697a linux-3.0/sound/soc/codecs/wm8728.c -f5c5d52e9307af6280ec4702dcb8c6bd linux-3.0/sound/soc/codecs/wm8727.c -db0ab4462d4bbf7de3ab5b502bc11607 linux-3.0/sound/soc/codecs/wm8711.h -5e072fcfe280ebeee3ef37754dc63502 linux-3.0/sound/soc/codecs/wm8711.c -6c0986ff3b04325ca3804a396bc031bb linux-3.0/sound/soc/codecs/wm8580.h -d1e8cf4a2d2522f582a32c5087544a70 linux-3.0/sound/soc/codecs/wm8580.c -77a6ddec6d836b4ad064d502f311be38 linux-3.0/sound/soc/codecs/wm8523.h -7cf3f99405fb321cab5b7bf5a5f7276a linux-3.0/sound/soc/codecs/wm8523.c -3ba55def90850ee357f35161886e0982 linux-3.0/sound/soc/codecs/wm8510.h -513b21692bb0673cb6e4d82670b584c9 linux-3.0/sound/soc/codecs/wm8510.c -22f44226206aab232fb7dd33d66c3892 linux-3.0/sound/soc/codecs/wm8400.h -f81278f3bfc6e5736d25da3e82e4000b linux-3.0/sound/soc/codecs/wm8400.c -debf833fd45785165ae615cd1620a295 linux-3.0/sound/soc/codecs/wm8350.h -e06e53fc6949d590517dba61c0e09cd0 linux-3.0/sound/soc/codecs/wm8350.c -b0f560bc2e68863ccbc4ca0a11d850a6 linux-3.0/sound/soc/codecs/wm2000.h -7346fa171fab967606078521d7cb2a15 linux-3.0/sound/soc/codecs/wm2000.c -a823826cc19f0153ab2182e9d51e9bc7 linux-3.0/sound/soc/codecs/wm1250-ev1.c -83ad45dc0fa95658461181db57a5d051 linux-3.0/sound/soc/codecs/wl1273.h -9b44d527a33cf68bdf05d6b0c68f57aa linux-3.0/sound/soc/codecs/wl1273.c -4efec34a06287d8a8a5b7c8541acfd16 linux-3.0/sound/soc/codecs/uda1380.h -45bba0ac2a27daa0b0b96df9167ea611 linux-3.0/sound/soc/codecs/uda1380.c -b8c39c6eaa2ece67ee6e1f722a6aa708 linux-3.0/sound/soc/codecs/uda134x.h -1cc1c9cf3b66a74513e44d94e6212935 linux-3.0/sound/soc/codecs/uda134x.c -fd962624e200d91e87f52d1d1f423a93 linux-3.0/sound/soc/codecs/twl6040.h -ec9fba4476a28c4d59f10f1d0e57dffb linux-3.0/sound/soc/codecs/twl6040.c -0b58034916cd41acaaff77c7398b5081 linux-3.0/sound/soc/codecs/twl4030.c -7f802a126b216a3d111ca8838fe148d3 linux-3.0/sound/soc/codecs/tpa6130a2.h -be9c6d153ed1f8aa276385ead4c6c155 linux-3.0/sound/soc/codecs/tpa6130a2.c -558e525df9c22246841eb18c9ac2ad77 linux-3.0/sound/soc/codecs/tlv320dac33.h -a0e78cfa7594ddee3c728415239a46cf linux-3.0/sound/soc/codecs/tlv320dac33.c -cacee018085520da3095c5617291ebc9 linux-3.0/sound/soc/codecs/tlv320aic3x.h -ce68c3152793c8b80ccdaec0cc5a1d18 linux-3.0/sound/soc/codecs/tlv320aic3x.c -626fa1530648bab4b33c6739045c1c1b linux-3.0/sound/soc/codecs/tlv320aic32x4.h -55efdbba54974571b4f036ad89b182ea linux-3.0/sound/soc/codecs/tlv320aic32x4.c -ec0f91813d3f2c39bc405e79f8fa0b70 linux-3.0/sound/soc/codecs/tlv320aic26.h -b18511607fabaa32cb0c76c9d6394d4b linux-3.0/sound/soc/codecs/tlv320aic26.c -84ac125a70173268420509821f50ca06 linux-3.0/sound/soc/codecs/tlv320aic23.h -42147692093d9aa54f3f5b999fba9899 linux-3.0/sound/soc/codecs/tlv320aic23.c -5536c9dcf9d66516c60f0f72535abd78 linux-3.0/sound/soc/codecs/stac9766.h -eb8dc13a88289957dea0e955a2dfb6f5 linux-3.0/sound/soc/codecs/stac9766.c -efd45f6b87242a331ddaaebe2d477894 linux-3.0/sound/soc/codecs/ssm2602.h -a935440f204d7590ed55cd23e210eab5 linux-3.0/sound/soc/codecs/ssm2602.c -f2a2a2b1448750bcfb280010ab452662 linux-3.0/sound/soc/codecs/spdif_transciever.c -b19f1395ac9fb8d3879a1eb2835b559d linux-3.0/sound/soc/codecs/sn95031.h -e0ee4c8a6ef482bdfee80f3dfb9e9b6c linux-3.0/sound/soc/codecs/sn95031.c -2768712f9ea76b6f4a4fa26df5f7b013 linux-3.0/sound/soc/codecs/sgtl5000.h -ce19b295f39c4495b38efcb1068c0f83 linux-3.0/sound/soc/codecs/sgtl5000.c -c5facd5a893daff8e4f4466b33869897 linux-3.0/sound/soc/codecs/pcm3008.h -1bbc4a0ba7b1376b746cb08480d3cd37 linux-3.0/sound/soc/codecs/pcm3008.c -c70b094a11c5568cf5c29709cdb4a17d linux-3.0/sound/soc/codecs/max9877.h -8b6859ad1050493cae005c76933fe53d linux-3.0/sound/soc/codecs/max9877.c -4810cc315a776b5711e5730521efc9ad linux-3.0/sound/soc/codecs/max9850.h -9579562ccc6a60be796746fd080d6bf8 linux-3.0/sound/soc/codecs/max9850.c -35eef0ecc1e46afa4f7d0937c50988e6 linux-3.0/sound/soc/codecs/max98095.h -8387e0fd493516b76ae7344892faa61a linux-3.0/sound/soc/codecs/max98095.c -aa775c9713aa028fd060a8028a9883ab linux-3.0/sound/soc/codecs/max98088.h -711c9d7c5fe411d2363a7874dd5f3657 linux-3.0/sound/soc/codecs/max98088.c -c39ce649666b0d13cd830fb492d15bc9 linux-3.0/sound/soc/codecs/lm4857.c -44de510e57ce55d6a4eb24d0803523c5 linux-3.0/sound/soc/codecs/l3.c -9825a0a4aa3e9ac1e2ba2cff81f39e20 linux-3.0/sound/soc/codecs/jz4740.c -fd1410d5cf2fbfc453af1c36a0a63f0e linux-3.0/sound/soc/codecs/dmic.c -acf6e1617358a51410a82474e31d81a1 linux-3.0/sound/soc/codecs/dfbmcs320.c -13338a54c6b3de43bde5874aa19644f0 linux-3.0/sound/soc/codecs/da7210.c -8e48217be62406e9b792f56e1ef5ac52 linux-3.0/sound/soc/codecs/cx20442.h -c5642c623152ecbf1224e71146641d35 linux-3.0/sound/soc/codecs/cx20442.c -c3ef698a3782327eb40134b1d018d27d linux-3.0/sound/soc/codecs/cs42l51.h -b32e9cb1b3614770c485b1a63b007277 linux-3.0/sound/soc/codecs/cs42l51.c -48ac4ee126e6f6a5d602f95dd6213384 linux-3.0/sound/soc/codecs/cs4271.c -115a2097a23484ecd5272aa4c0720928 linux-3.0/sound/soc/codecs/cs4270.c -e404d283ffce108bb6ea32f0d4f5da4a linux-3.0/sound/soc/codecs/cq93vc.c -24b6f7e2c91cb97ef8068df9c13dc94a linux-3.0/sound/soc/codecs/alc5623.h -7d208651941b1533d34e7de44e18a40a linux-3.0/sound/soc/codecs/alc5623.c -2fb00e9edde166af0daaa939f4fb1985 linux-3.0/sound/soc/codecs/ak4671.h -d7166ec223e299033b51fbab760475cd linux-3.0/sound/soc/codecs/ak4671.c -8e3f5d365ea66daa6c81ea15eb6aceb1 linux-3.0/sound/soc/codecs/ak4642.c -2803af53951b37e6c3a39cab13ba1c9a linux-3.0/sound/soc/codecs/ak4641.h -f0489d96995347305c24f754e9b96fba linux-3.0/sound/soc/codecs/ak4641.c -0d6d56b23731ce8ce70f1f815823881d linux-3.0/sound/soc/codecs/ak4535.h -802384d809f72fe1bd78377e1a15c0c6 linux-3.0/sound/soc/codecs/ak4535.c -156ac1cb9fbfb0cf713f4d3c3487e795 linux-3.0/sound/soc/codecs/ak4104.c -740944f823bf3c957838d216024dabb4 linux-3.0/sound/soc/codecs/ads117x.h -915ec4e5de0b2ccbc2316d881532dd5f linux-3.0/sound/soc/codecs/ads117x.c -876d22ebbe5342840374064efc85aabe linux-3.0/sound/soc/codecs/ad73311.h -fd7a589eb13843ea71198c84e162e158 linux-3.0/sound/soc/codecs/ad73311.c -7e1a883c6f52f6248d08670993e55165 linux-3.0/sound/soc/codecs/ad1980.h -a04dfd6f49d78355965df81d497f8317 linux-3.0/sound/soc/codecs/ad1980.c -ecb25945808ce9cf3e64956d7b3a2ef3 linux-3.0/sound/soc/codecs/ad193x.h -303f64966033e6c366100c0535aff9d4 linux-3.0/sound/soc/codecs/ad193x.c -9bba601b49e0cc406e93adf68f3a5b5d linux-3.0/sound/soc/codecs/ad1836.h -dbf47460799a97149f3159ba52c64de2 linux-3.0/sound/soc/codecs/ad1836.c -740e7a10d850d7f744118ce1ede2cc98 linux-3.0/sound/soc/codecs/ac97.c -3a3d2a735a3dd8c90ac22e085152d942 linux-3.0/sound/soc/codecs/Makefile -9b9a3b8df0e4d2d2f28b9f06f7597ea6 linux-3.0/sound/soc/codecs/Kconfig -01bf41cfba0920fe3c4e2cf48a438706 linux-3.0/sound/soc/codecs/88pm860x-codec.h -5b9c4cfc648ac50edf5e778ddea058b2 linux-3.0/sound/soc/codecs/88pm860x-codec.c -229a0a0d4e20fa139cf3267618735fb5 linux-3.0/sound/soc/blackfin/bf5xx-tdm.h -1e05f800295af436fb890eb04b0475e8 linux-3.0/sound/soc/blackfin/bf5xx-tdm.c -9b67e31c056703f20978443efd3d66f0 linux-3.0/sound/soc/blackfin/bf5xx-tdm-pcm.h -ea42c995bc7aae78c88bf26d50d7ed0e linux-3.0/sound/soc/blackfin/bf5xx-tdm-pcm.c -baa15c3ccade5b53367f40f52d740232 linux-3.0/sound/soc/blackfin/bf5xx-ssm2602.c -cfa276d12d91ad9a4165b734ad407684 linux-3.0/sound/soc/blackfin/bf5xx-sport.h -d3cd2f91805ba45e93996a397c5ad38a linux-3.0/sound/soc/blackfin/bf5xx-sport.c -7224af5c178ef29499dfd08bb6bd3553 linux-3.0/sound/soc/blackfin/bf5xx-i2s.c -a0960ff85c4f7ed62b1ea14cd430a6c6 linux-3.0/sound/soc/blackfin/bf5xx-i2s-pcm.h -5deec4e5925fed07f50223358fd3cf6d linux-3.0/sound/soc/blackfin/bf5xx-i2s-pcm.c -6b728ddf8156ac0aeb73fd9e7c64b580 linux-3.0/sound/soc/blackfin/bf5xx-ad73311.c -5406f1b733ecf349410236e020c246da linux-3.0/sound/soc/blackfin/bf5xx-ad1980.c -3c9ff7541ff3769df88e61d34e7a0914 linux-3.0/sound/soc/blackfin/bf5xx-ad193x.c -1a44f9d1c0f84f30f9ad27da0fb80c51 linux-3.0/sound/soc/blackfin/bf5xx-ad1836.c -2a2c4f02e35216b3cbffde034d61718c linux-3.0/sound/soc/blackfin/bf5xx-ac97.h -af4df0d8f56adfc3aae8a4af5897d0f6 linux-3.0/sound/soc/blackfin/bf5xx-ac97.c -e10290b6346fc800f2cb9e064aab2848 linux-3.0/sound/soc/blackfin/bf5xx-ac97-pcm.h -38fca8663c487517c56d0229340ee1ee linux-3.0/sound/soc/blackfin/bf5xx-ac97-pcm.c -c0084c87724380f93923e775dc729abb linux-3.0/sound/soc/blackfin/Makefile -a43189e6dfaab36477d8455cd95b9a45 linux-3.0/sound/soc/blackfin/Kconfig -2ef5ed2b4c9d166108391f23304cea27 linux-3.0/sound/soc/au1x/psc.h -d54443b9d04d1f504633f8b685ce8c2d linux-3.0/sound/soc/au1x/psc-i2s.c -7358cc23cce2a9e15db93f828ea9a1ff linux-3.0/sound/soc/au1x/psc-ac97.c -4e22b90062e9a8e06e6db7d8dec8d48c linux-3.0/sound/soc/au1x/dbdma2.c -39a18e8878674bc62f768436b547d407 linux-3.0/sound/soc/au1x/db1200.c -c73d2bf06f1ae44187fde16b777b75b7 linux-3.0/sound/soc/au1x/Makefile -e719a66a3aa68360af4564f9f5402cdd linux-3.0/sound/soc/au1x/Kconfig -86681128748fb0e4baa2f560d91dc29f linux-3.0/sound/soc/atmel/snd-soc-afeb9260.c -0af8f4f25653d6b02fe328bc8f6d9aad linux-3.0/sound/soc/atmel/sam9g20_wm8731.c -5b9f42790440a5b807bce54025734140 linux-3.0/sound/soc/atmel/playpaq_wm8510.c -60469de7d1ffa34cb932c9864182c945 linux-3.0/sound/soc/atmel/atmel_ssc_dai.h -196d9f2b9e4db551ede0707f884305bd linux-3.0/sound/soc/atmel/atmel_ssc_dai.c -aef2d44dd28bc5a746b5b34d3707c901 linux-3.0/sound/soc/atmel/atmel-pcm.h -e49a421631614a716dd75859d4e19a1e linux-3.0/sound/soc/atmel/atmel-pcm.c -f90fccf53fc111e25ebfe3f8e894ea88 linux-3.0/sound/soc/atmel/Makefile -2cc6b04565a9600fce67241e1256f5a5 linux-3.0/sound/soc/atmel/Kconfig -7c5516012176adcc1f07d23b822b5fc5 linux-3.0/sound/soc/Makefile -d1bd211012640ea7a5a6aaf13ad9d1fe linux-3.0/sound/soc/Kconfig -d2f4d88668fcb14409e997665f1974cf linux-3.0/sound/sh/sh_dac_audio.c -0ce8ff665d33275c42934a8f1cc66909 linux-3.0/sound/sh/aica.h -dfe8d0bdb30a325e4ee235d6700e12e6 linux-3.0/sound/sh/aica.c -c8fc146c3634a29b325454a692fa9446 linux-3.0/sound/sh/Makefile -0459e561924e521e263403bc0884ffd0 linux-3.0/sound/sh/Kconfig -9a9456995a314eeb51c59a1b4ab3bb74 linux-3.0/sound/ppc/tumbler_volume.h -566fc6b6d8cf8b0f3aa11c55627ec3c2 linux-3.0/sound/ppc/tumbler.c -9d9b3d8fe9721d834de6b7c2549b3d56 linux-3.0/sound/ppc/snd_ps3_reg.h -d5d579ab2abd7940682257d2b328e2dd linux-3.0/sound/ppc/snd_ps3.h -62a946e81ef8c298987d4e79924a79e0 linux-3.0/sound/ppc/snd_ps3.c -de36042c1967bcd78565e6237caa59e7 linux-3.0/sound/ppc/powermac.c -6e8082d9849c35a5584e3bd79c62ee99 linux-3.0/sound/ppc/pmac.h -c3dac4ceabc9a830382826640081f666 linux-3.0/sound/ppc/pmac.c -3e327ba2134b98798a56b614a312ad72 linux-3.0/sound/ppc/keywest.c -2815438855a10e785481664ff3b4d43a linux-3.0/sound/ppc/daca.c -727c70ac875894b2a515b45e39d1e71a linux-3.0/sound/ppc/burgundy.h -f5ee525785c86c2ae87d2528aff10a44 linux-3.0/sound/ppc/burgundy.c -9e768ac8732404a604d11ec356ee756f linux-3.0/sound/ppc/beep.c -91dc87bc9bd0ffbc7bf38c4787e8b30f linux-3.0/sound/ppc/awacs.h -599a9754be5cd70637ea5cc2236b8a0a linux-3.0/sound/ppc/awacs.c -2360f0f944776ca63d6a59be6d3a4f10 linux-3.0/sound/ppc/Makefile -a2808dec4aa35c4a2299819f6cd47420 linux-3.0/sound/ppc/Kconfig -619c8f30e3579641122ed01e35cfd0c9 linux-3.0/sound/pcmcia/vx/vxpocket.h -9501ce0dee328c5eb55777e711ab8870 linux-3.0/sound/pcmcia/vx/vxpocket.c -a32269b1fd36a6426eaa7df2e3808ac7 linux-3.0/sound/pcmcia/vx/vxp_ops.c -0fdbf5d3eee1d988c3578d03d47f9803 linux-3.0/sound/pcmcia/vx/vxp_mixer.c -84b7245a60923cee8e497ae82b6f89bd linux-3.0/sound/pcmcia/vx/Makefile -b26a6e490bc95eb5b5c21d902eb30853 linux-3.0/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c -1867c5df4457a99845d4c50695980964 linux-3.0/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c -bebb3af38339cd771a91596ddf374a32 linux-3.0/sound/pcmcia/pdaudiocf/pdaudiocf_core.c -39418eca78dbb8f38388cbf3ba9f3eda linux-3.0/sound/pcmcia/pdaudiocf/pdaudiocf.h -9e11b8652a7ae623f8434e939eddb4ad linux-3.0/sound/pcmcia/pdaudiocf/pdaudiocf.c -5fae2db46f3c04f76bafae9ecceac1cc linux-3.0/sound/pcmcia/pdaudiocf/Makefile -ce638631b25c0c548aba2b0f46213328 linux-3.0/sound/pcmcia/Makefile -c6646ac0b866be2cbf4340190ef8226c linux-3.0/sound/pcmcia/Kconfig -685caaf44dddcf0785b030088ef432e5 linux-3.0/sound/pci/ymfpci/ymfpci_main.c -67d305e2e966ef406fa17c2935636f0c linux-3.0/sound/pci/ymfpci/ymfpci.c -6a14cae089af56725081934eefcd43ba linux-3.0/sound/pci/ymfpci/Makefile -f2a9a5dee8ffe55ea735f6eb2d52477b linux-3.0/sound/pci/vx222/vx222_ops.c -cbaf0460378373f113bf327752d32552 linux-3.0/sound/pci/vx222/vx222.h -a85406ecc1353a598a2a244d30940d72 linux-3.0/sound/pci/vx222/vx222.c -1f7c12715d31e008dec7bf5b1fa86360 linux-3.0/sound/pci/vx222/Makefile -4e48ac0fd98c17fd3a8a6d3c34b39cef linux-3.0/sound/pci/via82xx_modem.c -681cb2417da7fd9b1c7c6b5ffbb9c7bf linux-3.0/sound/pci/via82xx.c -05b9b5c69a6087c74486722b6507d282 linux-3.0/sound/pci/trident/trident_memory.c -2f00f199d226d47578642a8cb393fc45 linux-3.0/sound/pci/trident/trident_main.c -d93de8ae33d2032eac593a00268616c9 linux-3.0/sound/pci/trident/trident.c -9c1bff8c9e28d93fe2f2387d0806ec9f linux-3.0/sound/pci/trident/Makefile -3b39cbbdeb0baa2396b48c4ee8470eeb linux-3.0/sound/pci/sonicvibes.c -f5a01b719cabf36f3458ebb448592d9c linux-3.0/sound/pci/sis7019.h -cab9a1fa3e9bf9acdf36ddc0ca6f37a1 linux-3.0/sound/pci/sis7019.c -f1e575a779ffe324ee478e0036dcad2a linux-3.0/sound/pci/rme9652/rme9652.c -9b26b0a76f010699e9fa80140a990716 linux-3.0/sound/pci/rme9652/hdspm.c -bea311dfa9a45f6dd44de23830a9fc2c linux-3.0/sound/pci/rme9652/hdsp.c -c8e1c495ce08d44aff81a137e91047c4 linux-3.0/sound/pci/rme9652/Makefile -1d596c5f64f4f5f348ed1ab1e0be4345 linux-3.0/sound/pci/rme96.c -beedb353f8c047537921524df2269613 linux-3.0/sound/pci/rme32.c -00a139deccb0b074160eecf35ef6d367 linux-3.0/sound/pci/riptide/riptide.c -fc1fa5e28ad0e48f45cf602cb9f3a3e3 linux-3.0/sound/pci/riptide/Makefile -e2082968f25f059231164ef9a66268bd linux-3.0/sound/pci/pcxhr/pcxhr_mixer.h -bdfd5f5818f993d1b721630278d9738a linux-3.0/sound/pci/pcxhr/pcxhr_mixer.c -87cac6fbe21f416a7ead410e3399cc61 linux-3.0/sound/pci/pcxhr/pcxhr_mix22.h -0995c29fc8fa23080cb0c3fc85fd5b4d linux-3.0/sound/pci/pcxhr/pcxhr_mix22.c -846677bb123a8dcbc9919230b1d66e18 linux-3.0/sound/pci/pcxhr/pcxhr_hwdep.h -4bcb053c7953361f245db9043ba646f0 linux-3.0/sound/pci/pcxhr/pcxhr_hwdep.c -bf631060bac046e792d40a3e33958e62 linux-3.0/sound/pci/pcxhr/pcxhr_core.h -bd961a1942efcf41b83b07c91498ae6e linux-3.0/sound/pci/pcxhr/pcxhr_core.c -96dfbb8bde9a57e8ddd6270485590d27 linux-3.0/sound/pci/pcxhr/pcxhr.h -5ebc8ac873a55e6acc86ae5d52bea20c linux-3.0/sound/pci/pcxhr/pcxhr.c -5315b7a6768621268aa85f59c0a68483 linux-3.0/sound/pci/pcxhr/Makefile -4abd79f069fc0afa2aaa7d67059c83c5 linux-3.0/sound/pci/oxygen/xonar_wm87x6.c -a0630b0c3e0440c692b072c0694f3d6c linux-3.0/sound/pci/oxygen/xonar_pcm179x.c -8cc00ac2562e42df9fd28c18f75bbc67 linux-3.0/sound/pci/oxygen/xonar_lib.c -465da5b53ce09db2e6708610c831dec1 linux-3.0/sound/pci/oxygen/xonar_hdmi.c -92113344ae7a3bdc8b4afd6b6e2695aa linux-3.0/sound/pci/oxygen/xonar_dg.h -68aafd6a3b00ac96781f386951729366 linux-3.0/sound/pci/oxygen/xonar_dg.c -08ff7a7cad7ac44b46ffdea342f2c6b6 linux-3.0/sound/pci/oxygen/xonar_cs43xx.c -3f61fe222b5d37055bfeaed4087381f3 linux-3.0/sound/pci/oxygen/xonar.h -61eae12aac048ab8e5c331430259e594 linux-3.0/sound/pci/oxygen/wm8785.h -65137f05d95298e8f94ba6422396ed32 linux-3.0/sound/pci/oxygen/wm8776.h -1761be94ebb060069e647ed7c0044567 linux-3.0/sound/pci/oxygen/wm8766.h -5628aaccaefa0220319620f2fac437c0 linux-3.0/sound/pci/oxygen/virtuoso.c -fef7e7dc582e52a27bcb8c30e32e718f linux-3.0/sound/pci/oxygen/pcm1796.h -7f67e3a641bcafdededd5762ec1b1097 linux-3.0/sound/pci/oxygen/oxygen_regs.h -c4fce28b096391d80c6d7114d78b3e0f linux-3.0/sound/pci/oxygen/oxygen_pcm.c -c8d8da5ad8b8ffe4654494c10d386dd8 linux-3.0/sound/pci/oxygen/oxygen_mixer.c -e29ac73a53832d96ee1f567b597318a8 linux-3.0/sound/pci/oxygen/oxygen_lib.c -c630fe11f1e8b2373c89d76c932d4376 linux-3.0/sound/pci/oxygen/oxygen_io.c -71ba14c24451df0f5bee83b20f99d981 linux-3.0/sound/pci/oxygen/oxygen.h -7ca62df47a751b079e5a43665abef2d6 linux-3.0/sound/pci/oxygen/oxygen.c -f8ebc06e77c6a09c67a6dad9b08cb403 linux-3.0/sound/pci/oxygen/cs4398.h -8f3f1902dc9506845432679bf9695f83 linux-3.0/sound/pci/oxygen/cs4362a.h -494f4ab559852a9103ffc991cf5150d6 linux-3.0/sound/pci/oxygen/cs4245.h -1310981183277df3fa41ba10d234197b linux-3.0/sound/pci/oxygen/cs2000.h -504153bcb0e170da768f30122fa21fb1 linux-3.0/sound/pci/oxygen/cm9780.h -1acaa0dda7e7d65e61899c2825982d8c linux-3.0/sound/pci/oxygen/ak4396.h -1b8cf92db4d9540bf47710dfd2b9b6f7 linux-3.0/sound/pci/oxygen/Makefile -75c4363c90c7032ab84dbb547efb1ce1 linux-3.0/sound/pci/nm256/nm256_coef.c -f51065e7dc6889180cbe6762a9f1cd3c linux-3.0/sound/pci/nm256/nm256.c -ac4dea01e328ba5d3148d5b0417c0eba linux-3.0/sound/pci/nm256/Makefile -8df4a07c599b03a403bbf182b2001a04 linux-3.0/sound/pci/mixart/mixart_mixer.h -41992926c320b9de4b1f98d8029dd371 linux-3.0/sound/pci/mixart/mixart_mixer.c -39fff58f970c8825cd3748807a329d0c linux-3.0/sound/pci/mixart/mixart_hwdep.h -a355888edf1a5d19dd8208aa7b173a82 linux-3.0/sound/pci/mixart/mixart_hwdep.c -b9f7649759938ab62a7c321cff6cb9bb linux-3.0/sound/pci/mixart/mixart_core.h -2480408e81f1a5309a796c715b374cb2 linux-3.0/sound/pci/mixart/mixart_core.c -9b28d97b1d39e8c1eec726388afe19d6 linux-3.0/sound/pci/mixart/mixart.h -d7730058dd882c38eb166464b4dcd3f3 linux-3.0/sound/pci/mixart/mixart.c -e50284b81e74de54f390d57847b62907 linux-3.0/sound/pci/mixart/Makefile -dea97a9fcb9af4969272397c4c8658ef linux-3.0/sound/pci/maestro3.c -cb5c037f7384fad488041e80108f7d8e linux-3.0/sound/pci/lx6464es/lx_defs.h -a009bec200f6d92452866323a0578f30 linux-3.0/sound/pci/lx6464es/lx_core.h -3ead5ad54a7d86f4c06278896e65a433 linux-3.0/sound/pci/lx6464es/lx_core.c -cb77df6fad278dec8c75f22a852810fd linux-3.0/sound/pci/lx6464es/lx6464es.h -66fcfadb412ae34204781c3358da7b2a linux-3.0/sound/pci/lx6464es/lx6464es.c -da4d42d668d88420aa47f74e75ebd843 linux-3.0/sound/pci/lx6464es/Makefile -996bba98f407548efb0227ff7d828c50 linux-3.0/sound/pci/lola/lola_proc.c -3487d32b00714d7189374a09e0ce20c7 linux-3.0/sound/pci/lola/lola_pcm.c -87279a21211ec4dfb9764730d6e834f6 linux-3.0/sound/pci/lola/lola_mixer.c -5d0c247cced9b4049aa702756a5cd8cd linux-3.0/sound/pci/lola/lola_clock.c -3b5f3f8ed63d2f62987dcebb6866534a linux-3.0/sound/pci/lola/lola.h -fb078d1721222ed26f14e1f69652a808 linux-3.0/sound/pci/lola/lola.c -92bcf510a7f8ca69cba639fdb147410c linux-3.0/sound/pci/lola/Makefile -cd148fad2ffe9159aba89e04727c8007 linux-3.0/sound/pci/korg1212/korg1212.c -7c5812402a252ea5afce8e20c7ccccaa linux-3.0/sound/pci/korg1212/Makefile -4075a8d547666d6e9accd20c73c04c48 linux-3.0/sound/pci/intel8x0m.c -220bbcff1701e753ffe2c9cc0782a013 linux-3.0/sound/pci/intel8x0.c -af42801c85a0323f2ade35a8270e3b97 linux-3.0/sound/pci/ice1712/wtm.h -3d9ebaccffc328cabf9e50e3672d098e linux-3.0/sound/pci/ice1712/wtm.c -27632e1463b917faf829d0f70705e2fb linux-3.0/sound/pci/ice1712/vt1720_mobo.h -987ef52667e78a7e6779cc9ae774ab6c linux-3.0/sound/pci/ice1712/vt1720_mobo.c -52bb82e0219889f740be197e9fb56f8d linux-3.0/sound/pci/ice1712/stac946x.h -a9017eb3f3ec3930e5453c01accd0b87 linux-3.0/sound/pci/ice1712/se.h -fabbad8b19d36236669cfb11fe8984fc linux-3.0/sound/pci/ice1712/se.c -89dd3e7420e92e571826c1dc1df1b100 linux-3.0/sound/pci/ice1712/revo.h -2cf05355756a4204ce9936808b00a942 linux-3.0/sound/pci/ice1712/revo.c -678de9be4beea08659694d528b5b3643 linux-3.0/sound/pci/ice1712/quartet.h -d428b9f0c3f122ebe0792044f7aec9d1 linux-3.0/sound/pci/ice1712/quartet.c -17ade93620b09dd5ef091d96fe58395b linux-3.0/sound/pci/ice1712/prodigy_hifi.h -2e1925b84f861cc1b1f214a9c1417af8 linux-3.0/sound/pci/ice1712/prodigy_hifi.c -50b8225797d05ac8a673fbdf443be88a linux-3.0/sound/pci/ice1712/prodigy192.h -8620d9ce4fee8da2de67aefaf25d8e0b linux-3.0/sound/pci/ice1712/prodigy192.c -9b24b5e9592aee6f5270cdfa9d36db16 linux-3.0/sound/pci/ice1712/pontis.h -af2e8cf05623f726acb298135d9f6585 linux-3.0/sound/pci/ice1712/pontis.c -03926936c1380e9c60eef1c93fdb4bc7 linux-3.0/sound/pci/ice1712/phase.h -4abfd0cbe39386e9a471b3893fae1e25 linux-3.0/sound/pci/ice1712/phase.c -2e7bb015ee3eecef9b43245c1da5962e linux-3.0/sound/pci/ice1712/maya44.h -c4846568c1c73b12488e7be1febedb22 linux-3.0/sound/pci/ice1712/maya44.c -6a00eda8ef5bb62f65c00b8723846044 linux-3.0/sound/pci/ice1712/juli.h -8601c472418098c6b7d2e6f103f49907 linux-3.0/sound/pci/ice1712/juli.c -f998c09dacca1372e0ceeab18d31b1a5 linux-3.0/sound/pci/ice1712/ice1724.c -cfedbde0141f81bdec90594d9a6172c9 linux-3.0/sound/pci/ice1712/ice1712.h -28fd69b5319422d0cf80136ccdb7f050 linux-3.0/sound/pci/ice1712/ice1712.c -10203a8214773f5a1f09473bf1545d51 linux-3.0/sound/pci/ice1712/hoontech.h -a498a81dab96dca747cc133a2574b2b3 linux-3.0/sound/pci/ice1712/hoontech.c -53ef572c0890b5ab78de1c8d598ea1a4 linux-3.0/sound/pci/ice1712/ews.h -2aa363009fe885368ad567ad46b97046 linux-3.0/sound/pci/ice1712/ews.c -7a91109f0346e5a7f8c71ba5096e9a93 linux-3.0/sound/pci/ice1712/envy24ht.h -08f33d784a34c4990916fcc0900afb94 linux-3.0/sound/pci/ice1712/delta.h -8f508af0ce8341ddb461e72872c0a48b linux-3.0/sound/pci/ice1712/delta.c -fc614894ec77c197a09cbf3d1a2157a4 linux-3.0/sound/pci/ice1712/aureon.h -070d9b33906143c792de895bcec5871d linux-3.0/sound/pci/ice1712/aureon.c -65ac233f86353117556375d55b8eb617 linux-3.0/sound/pci/ice1712/amp.h -eda0b171dc388a139dc23907b60d7e0e linux-3.0/sound/pci/ice1712/amp.c -6fce7ecfb3d93755495ef33ebc30faec linux-3.0/sound/pci/ice1712/ak4xxx.c -c88f874007f9dc425be5f149b08e2edc linux-3.0/sound/pci/ice1712/Makefile -9b53b0488f18d179cdacb440f20f5058 linux-3.0/sound/pci/hda/patch_via.c -a2928eb58266ae57c06532efeda15120 linux-3.0/sound/pci/hda/patch_sigmatel.c -f63abbca5191a20497e23d74eaa74d06 linux-3.0/sound/pci/hda/patch_si3054.c -b6d76c0797fc7236531f9972232e695a linux-3.0/sound/pci/hda/patch_realtek.c -5d8944c8d60c3ccc6aec5d1806e0592e linux-3.0/sound/pci/hda/patch_hdmi.c -40499f256fb93b6909c44cd7449b123b linux-3.0/sound/pci/hda/patch_conexant.c -e2b7980b53635b03c9613692f7b701d1 linux-3.0/sound/pci/hda/patch_cmedia.c -a0cf65e56672a00abe580283c377a212 linux-3.0/sound/pci/hda/patch_cirrus.c -3d36a51ef70404b3dd815a8af3deb19b linux-3.0/sound/pci/hda/patch_ca0110.c -20508ecdda6a03d30f0394398ee00a15 linux-3.0/sound/pci/hda/patch_analog.c -4fe5f486abba7be6ef70a6a0e11a81c8 linux-3.0/sound/pci/hda/hda_proc.c -d5798c0d0b828452caf8495f1a885d28 linux-3.0/sound/pci/hda/hda_local.h -4f74ec3d12fca0b76750f0ec5c9a8746 linux-3.0/sound/pci/hda/hda_intel.c -2159181cfccd966635ba93cae761ed3a linux-3.0/sound/pci/hda/hda_hwdep.c -98acfe0551e499711b223eddadbc749f linux-3.0/sound/pci/hda/hda_generic.c -b8442df49c821b7ed5fd7c7492d9df09 linux-3.0/sound/pci/hda/hda_eld.c -45162ad95e990a45122be076dcdb2bab linux-3.0/sound/pci/hda/hda_codec.h -8f7d84b6fcfa1c54e906c98a97b2fa52 linux-3.0/sound/pci/hda/hda_codec.c -40882522c1508a95f1192d24a65af43f linux-3.0/sound/pci/hda/hda_beep.h -7c32788b5cd89747161723e466a8247c linux-3.0/sound/pci/hda/hda_beep.c -975ea1db6c4c06240a250e1f8d9f7261 linux-3.0/sound/pci/hda/Makefile -f31d841c8c4651ce65d21104aff0c906 linux-3.0/sound/pci/hda/Kconfig -132fc0bae6bceff53d98d4a5a504997e linux-3.0/sound/pci/fm801.c -619dc3c58b9cc61e18d7c4e070b84f8b linux-3.0/sound/pci/es1968.c -c887381e81bf01875f02a23e070e0e32 linux-3.0/sound/pci/es1938.c -d2912966a2f65db8efe8be8c018a3e20 linux-3.0/sound/pci/ens1371.c -d8f15649de2b8f564c4428c48b68e453 linux-3.0/sound/pci/ens1370.c -9c07f562411713de6e0b8501658be89a linux-3.0/sound/pci/emu10k1/voice.c -01f1cb48ac31fd780403cccbe711187c linux-3.0/sound/pci/emu10k1/tina2.h -24afa31ad64813480ea41f035c439d41 linux-3.0/sound/pci/emu10k1/timer.c -848fccacc7956a4590ae8dea455852c2 linux-3.0/sound/pci/emu10k1/p17v.h -f128bbd2cb10e2d11d10c15615e57be9 linux-3.0/sound/pci/emu10k1/p16v.h -cd1a1aa6e3cb708b7727454c4ced4319 linux-3.0/sound/pci/emu10k1/p16v.c -b823cf8709033a353aa97c89c222cb52 linux-3.0/sound/pci/emu10k1/memory.c -5e6d64aee2fef90958facf25bfaf06c0 linux-3.0/sound/pci/emu10k1/irq.c -02e1b8385bfa539c7156014449a5aef9 linux-3.0/sound/pci/emu10k1/io.c -b615eccc575d7a45d55a85d115af9b77 linux-3.0/sound/pci/emu10k1/emuproc.c -2fb78263e385d3f8b6eddf5813fe1d38 linux-3.0/sound/pci/emu10k1/emupcm.c -cb145b922a030cb6f676a7c30fa3ff8a linux-3.0/sound/pci/emu10k1/emumpu401.c -1abb24ec29f1556cbf74c6291d32d5b0 linux-3.0/sound/pci/emu10k1/emumixer.c -38d3631cb8050efa9fae7971f2f374eb linux-3.0/sound/pci/emu10k1/emufx.c -198ebacd53d81de85a04830a01ec4372 linux-3.0/sound/pci/emu10k1/emu10k1x.c -9222eee26a94f1a0b457acd0e691b2ba linux-3.0/sound/pci/emu10k1/emu10k1_synth_local.h -785106d6e3c0ce24b3b6228222397c00 linux-3.0/sound/pci/emu10k1/emu10k1_synth.c -e6c4d58fa9999f9d7f5a7feefb92abc0 linux-3.0/sound/pci/emu10k1/emu10k1_patch.c -9dd1fd2a309e233b51611551dd47ffeb linux-3.0/sound/pci/emu10k1/emu10k1_main.c -21b7b6c3fb75e7e5ddd495cf7f2357af linux-3.0/sound/pci/emu10k1/emu10k1_callback.c -27435963af70c2136068811acbca5f5f linux-3.0/sound/pci/emu10k1/emu10k1.c -4574fb7a397f4d3cb2277cedc892091c linux-3.0/sound/pci/emu10k1/Makefile -207d6ce64c5ec1a43d2a647101a077a3 linux-3.0/sound/pci/echoaudio/mona_dsp.c -8031512bde18b9e149f48d8825f5eb2a linux-3.0/sound/pci/echoaudio/mona.c -76fe42e361cb4a4f179ae65ae2e35a75 linux-3.0/sound/pci/echoaudio/midi.c -e950307732695f2440b24a0d4275c6c4 linux-3.0/sound/pci/echoaudio/mia_dsp.c -ea4713f8ce282c1e17a50ded40baa37e linux-3.0/sound/pci/echoaudio/mia.c -2d8bf208d6722d1b6e4b514cb02e5755 linux-3.0/sound/pci/echoaudio/layla24_dsp.c -13e98557520da2aa835ad2ccf6165dfa linux-3.0/sound/pci/echoaudio/layla24.c -5e29029578c97ac5e42dd3ea9f869b44 linux-3.0/sound/pci/echoaudio/layla20_dsp.c -6fba9dad041d5ae4c2836b4d82d13db8 linux-3.0/sound/pci/echoaudio/layla20.c -e8cda889328848c160ed0799ce50697f linux-3.0/sound/pci/echoaudio/indigoiox_dsp.c -330d39db738e9489b9227be4b80d6cc6 linux-3.0/sound/pci/echoaudio/indigoiox.c -bb1939b48faa37ba0e19dfd64dc225ee linux-3.0/sound/pci/echoaudio/indigoio_dsp.c -20d604bcc7fa00f7b2fb949645570e66 linux-3.0/sound/pci/echoaudio/indigoio.c -e4fc9ad1cb8574c9271618bc14846ce1 linux-3.0/sound/pci/echoaudio/indigodjx_dsp.c -3eb0f46c1f8f7605160bcdfa3cb81fbb linux-3.0/sound/pci/echoaudio/indigodjx.c -6c67db5f56704c03bc0db26abf627f6d linux-3.0/sound/pci/echoaudio/indigodj_dsp.c -d481e82dc8334d7eacfbdd02e4cf0c0f linux-3.0/sound/pci/echoaudio/indigodj.c -3fb28fdc2016897d22fc71980921bee5 linux-3.0/sound/pci/echoaudio/indigo_express_dsp.c -31fb71a6b6c81f0e7199807b6282767b linux-3.0/sound/pci/echoaudio/indigo_dsp.c -64e887647cb066c40cff654c9841e908 linux-3.0/sound/pci/echoaudio/indigo.c -b4c07f82398df0b786d7fcc227ff2b78 linux-3.0/sound/pci/echoaudio/gina24_dsp.c -a23a09a15f5328aadf7a9fd4e6330728 linux-3.0/sound/pci/echoaudio/gina24.c -b0a471265b34ad130f9bdaf1d33a3af3 linux-3.0/sound/pci/echoaudio/gina20_dsp.c -04fab4ddf763b2dced6f24e2e06a7564 linux-3.0/sound/pci/echoaudio/gina20.c -b6227daf9b647d2dea697b9ef904592c linux-3.0/sound/pci/echoaudio/echoaudio_gml.c -9bff3b6513d8a24ba9535d723c56c6b7 linux-3.0/sound/pci/echoaudio/echoaudio_dsp.h -a604033569a8ab89be51c204e16d7cc2 linux-3.0/sound/pci/echoaudio/echoaudio_dsp.c -c84749ae2dbf2ea478f1ab2e030ecb54 linux-3.0/sound/pci/echoaudio/echoaudio_3g.c -cc5f9fa7eaad42c43ce870c1a6c74cf5 linux-3.0/sound/pci/echoaudio/echoaudio.h -ff44da9d2b350eef63e9a26ebf7b14fa linux-3.0/sound/pci/echoaudio/echoaudio.c -8bf8284064c5eb63a58efed2d0cf4b25 linux-3.0/sound/pci/echoaudio/echo3g_dsp.c -c6334fd9ebfc3ebf4d2586dd0f31fcaa linux-3.0/sound/pci/echoaudio/echo3g.c -9160f0a3205cf0c130591edd7087dedd linux-3.0/sound/pci/echoaudio/darla24_dsp.c -5403a850ad27554d14966ff5fc34fa04 linux-3.0/sound/pci/echoaudio/darla24.c -f41dcb8cfbeeb96de6b4ead1d13cb0bd linux-3.0/sound/pci/echoaudio/darla20_dsp.c -337e0fcbce949f3dc6e152ba67d7667b linux-3.0/sound/pci/echoaudio/darla20.c -afb3ecf6b7c024c5af71e380cf007277 linux-3.0/sound/pci/echoaudio/Makefile -34e7705a2cdc9f46e0f7de6d17118ef4 linux-3.0/sound/pci/ctxfi/xfi.c -6e278be52250d19bf0e45d35c1d8a4cd linux-3.0/sound/pci/ctxfi/ctvmem.h -0e3ec0dc6944521db7a4d32888c60eab linux-3.0/sound/pci/ctxfi/ctvmem.c -d212c7f96e9917eb6518c784579d7895 linux-3.0/sound/pci/ctxfi/cttimer.h -f883e6e3684dd62de66293b607367897 linux-3.0/sound/pci/ctxfi/cttimer.c -35569ab9c37d467bad7bbb47e992ec1a linux-3.0/sound/pci/ctxfi/ctsrc.h -905b716b5ea30729233cbb8e96070396 linux-3.0/sound/pci/ctxfi/ctsrc.c -007de05b8db86591732d8d84966d3d86 linux-3.0/sound/pci/ctxfi/ctresource.h -16a2663c45077388a3a42c80abddd1ef linux-3.0/sound/pci/ctxfi/ctresource.c -3d601a8ab72777988b42f459c1db2570 linux-3.0/sound/pci/ctxfi/ctpcm.h -4bf7048467eac613f49b3f608d938427 linux-3.0/sound/pci/ctxfi/ctpcm.c -4815e965209251058ff1c8cb41928121 linux-3.0/sound/pci/ctxfi/ctmixer.h -0212a8dbde18ec2fec8a004bc211db3d linux-3.0/sound/pci/ctxfi/ctmixer.c -b35c232ae62d3d978745294435b546e2 linux-3.0/sound/pci/ctxfi/ctimap.h -fda47909f3d592c4ccd1d71490a5341a linux-3.0/sound/pci/ctxfi/ctimap.c -4288e789eaf3fc44d42e742ad71e117d linux-3.0/sound/pci/ctxfi/cthw20k2.h -15400e62e0096976014a8594e90a46a3 linux-3.0/sound/pci/ctxfi/cthw20k2.c -21ca0f5eb69358852c2fa81cdc09cf5c linux-3.0/sound/pci/ctxfi/cthw20k1.h -50ad1fa289de8259656ba5f9581d6bd8 linux-3.0/sound/pci/ctxfi/cthw20k1.c -5ffd7536ed9f9291cc6a263274fd3351 linux-3.0/sound/pci/ctxfi/cthardware.h -6dbfea4320bb66443756cb48516333ff linux-3.0/sound/pci/ctxfi/cthardware.c -bd6312c0b7d1944df2f974bad52eef58 linux-3.0/sound/pci/ctxfi/ctdaio.h -c581bb5867d2a7da7385ac6a1538aa71 linux-3.0/sound/pci/ctxfi/ctdaio.c -13b24f2aa7f79d19f44aea725e3c0532 linux-3.0/sound/pci/ctxfi/ctatc.h -2089ff0d9d4db70e82794f459702fdf6 linux-3.0/sound/pci/ctxfi/ctatc.c -caeea8dc962cf884d508245b00e184ae linux-3.0/sound/pci/ctxfi/ctamixer.h -fd5e62921d816e192fe7471ce43c4501 linux-3.0/sound/pci/ctxfi/ctamixer.c -dd4024d442a207128f942618c7506f40 linux-3.0/sound/pci/ctxfi/ct20k2reg.h -607c69aeef9099fe560a5c98b82e1063 linux-3.0/sound/pci/ctxfi/ct20k1reg.h -fc5c1c7221d29325db7a57401512697e linux-3.0/sound/pci/ctxfi/Makefile -73ba27c21fb473ba755f1a82c319818f linux-3.0/sound/pci/cs5535audio/cs5535audio_pm.c -29a4252907c4ed75ecd6b5ce7a1e8e41 linux-3.0/sound/pci/cs5535audio/cs5535audio_pcm.c -5dd0a12638d5c3f814a9f81f5528b177 linux-3.0/sound/pci/cs5535audio/cs5535audio_olpc.c -fdf8ce7027aa77d3ea0bdf8b3f5b68f8 linux-3.0/sound/pci/cs5535audio/cs5535audio.h -b0a46318fe28b38f3d8f68d57dc53599 linux-3.0/sound/pci/cs5535audio/cs5535audio.c -5d7038d92e40aa1bf7a5d2989f0e0e63 linux-3.0/sound/pci/cs5535audio/Makefile -22119497d5bcab8223269aaf1dbe91a8 linux-3.0/sound/pci/cs5530.c -f89cd396780bffa743292a47d694959f linux-3.0/sound/pci/cs46xx/imgs/cwcsnoop.h -18de5188665443b8c390a7092bd05795 linux-3.0/sound/pci/cs46xx/imgs/cwcdma.h -48631cd5e642b2a11159ee9488ddbe0a linux-3.0/sound/pci/cs46xx/imgs/cwcdma.asp -5806a4c9c0860b3c5849ec9a38d13792 linux-3.0/sound/pci/cs46xx/imgs/cwcbinhack.h -22ab3a6bc8be8b2be69f3061413a678b linux-3.0/sound/pci/cs46xx/imgs/cwcasync.h -69d61194ac463fc8fd4fe1a71a9ab7b9 linux-3.0/sound/pci/cs46xx/imgs/cwc4630.h -c019608b10169eda345283fbb4ffb09b linux-3.0/sound/pci/cs46xx/dsp_spos_scb_lib.c -97bdd11122cec98bcf644501883d3a99 linux-3.0/sound/pci/cs46xx/dsp_spos.h -8a261439d8250471402a2558f048f3f0 linux-3.0/sound/pci/cs46xx/dsp_spos.c -b821fa17db75e4cb5a0f59a0ecc1fc0d linux-3.0/sound/pci/cs46xx/cs46xx_lib.h -b221e7872ba04e681854d2c7f5963d4f linux-3.0/sound/pci/cs46xx/cs46xx_lib.c -5cc53fceda0bf3470b90cd4b9292e101 linux-3.0/sound/pci/cs46xx/cs46xx_image.h -4bdf1847d97c1887a96785c87bb2a459 linux-3.0/sound/pci/cs46xx/cs46xx.c -91c0d7a4ea6b4dc0703aa8ceb50a2506 linux-3.0/sound/pci/cs46xx/Makefile -e5229fa3722731433443844005905745 linux-3.0/sound/pci/cs4281.c -b4748261c68c23151105210cda772b67 linux-3.0/sound/pci/cmipci.c -d384d2fd653c733b9553ab61c2273736 linux-3.0/sound/pci/ca0106/ca_midi.h -555b1e00e9e31e36d87b68c0f5af7617 linux-3.0/sound/pci/ca0106/ca_midi.c -96d50852dd6e066696a9c710e5209fdd linux-3.0/sound/pci/ca0106/ca0106_proc.c -b877c7c48d8ecc81d8655c58ef5f219e linux-3.0/sound/pci/ca0106/ca0106_mixer.c -daf20ae74e4658647bcab1581ff98d94 linux-3.0/sound/pci/ca0106/ca0106_main.c -1612bb475e78fa309fc3b777d412ecf1 linux-3.0/sound/pci/ca0106/ca0106.h -8bc90285c3447fedbb6cdceed3bff865 linux-3.0/sound/pci/ca0106/Makefile -826663f15ca1305fb636e7e6bb321355 linux-3.0/sound/pci/bt87x.c -5d1b5987aa5708eef96f30a3e7031a1d linux-3.0/sound/pci/azt3328.h -8660f3c69db03720f74edcc285c72078 linux-3.0/sound/pci/azt3328.c -fd3d1ef001f91956e7883fa869121cc4 linux-3.0/sound/pci/aw2/saa7146.h -428afea403b2a05eb43f4ac9d49df50e linux-3.0/sound/pci/aw2/aw2-tsl.c -01e03caf908008fa44fb23ea090a8640 linux-3.0/sound/pci/aw2/aw2-saa7146.h -b60302f742bf1f751cd9ec7baace33a2 linux-3.0/sound/pci/aw2/aw2-saa7146.c -6d234c19356aa9f5d0d46a2c75c89f36 linux-3.0/sound/pci/aw2/aw2-alsa.c -5fc8b641f2d23d79966b516d92d3548c linux-3.0/sound/pci/aw2/Makefile -fcf35916261bc6adcd9aba2e88900d31 linux-3.0/sound/pci/au88x0/au88x0_xtalk.h -a93a058114f958b529095b21af18e83f linux-3.0/sound/pci/au88x0/au88x0_xtalk.c -8d495e5c7e0f5b32fee015d418f0d022 linux-3.0/sound/pci/au88x0/au88x0_wt.h -65a01dd8f6b6e33eb77330a7606ee95b linux-3.0/sound/pci/au88x0/au88x0_synth.c -c43ad4ec30b5b2d34434d27b8df0d413 linux-3.0/sound/pci/au88x0/au88x0_pcm.c -162219bb8dcf94633e275a12198b3942 linux-3.0/sound/pci/au88x0/au88x0_mpu401.c -82b2400c4aa7da48b14ac9b6b9894037 linux-3.0/sound/pci/au88x0/au88x0_mixer.c -46f8b6aa05bf1fff2d997e0433802f4e linux-3.0/sound/pci/au88x0/au88x0_game.c -064ffa8b5f05efeafb539cf317a719d0 linux-3.0/sound/pci/au88x0/au88x0_eqdata.c -126044527a328dc3cab23c2aeadc8a76 linux-3.0/sound/pci/au88x0/au88x0_eq.h -3088e20ae1febed1d90c1056001a51fe linux-3.0/sound/pci/au88x0/au88x0_eq.c -833bf0a1cc9d51ccfef672f1439b66bc linux-3.0/sound/pci/au88x0/au88x0_core.c -86d759d0b487a8f9e673001d37267dc0 linux-3.0/sound/pci/au88x0/au88x0_a3ddata.c -523c64b375039b47eab716fd73ed7ba0 linux-3.0/sound/pci/au88x0/au88x0_a3d.h -a560c6a6e7a5940ae63b0c3677753125 linux-3.0/sound/pci/au88x0/au88x0_a3d.c -e8cc51575a8864cfb9e870fb47cb6ac2 linux-3.0/sound/pci/au88x0/au88x0.h -06efdc5fb75de3452febb0f694743ef7 linux-3.0/sound/pci/au88x0/au88x0.c -56dbc36c4aded52f76402f8b423b9d0c linux-3.0/sound/pci/au88x0/au8830.h -795ae382568a42e384a7481ef5d74bcd linux-3.0/sound/pci/au88x0/au8830.c -9ff8c3fb7a40486aef58cf659ab92973 linux-3.0/sound/pci/au88x0/au8820.h -a51611606d325f88e6222a241cabfb3e linux-3.0/sound/pci/au88x0/au8820.c -baffcf90b7e54b4474c8ee442f819bfb linux-3.0/sound/pci/au88x0/au8810.h -87a750d5e1185b57181843533b937477 linux-3.0/sound/pci/au88x0/au8810.c -dac8f9498d7d78ae41b7744b280839c2 linux-3.0/sound/pci/au88x0/Makefile -22b6bc92d5eeb40ae8755762a05e2811 linux-3.0/sound/pci/atiixp_modem.c -7daff5b6f8014ab96df721be879220fa linux-3.0/sound/pci/atiixp.c -19ae0854cc0dc23b3eaf3b8822785409 linux-3.0/sound/pci/asihpi/hpipcida.h -5d549dcb0c525427db65c96377894e33 linux-3.0/sound/pci/asihpi/hpios.h -45e3b2e4acf197b7b05a0bb974be1933 linux-3.0/sound/pci/asihpi/hpios.c -5809cb78324f1e746968c6c246208d6a linux-3.0/sound/pci/asihpi/hpioctl.h -50a78184dc3339dee262987ea5dad8d9 linux-3.0/sound/pci/asihpi/hpioctl.c -34aa120a935169d4dc7c709f0875852b linux-3.0/sound/pci/asihpi/hpimsgx.h -9e8b6d3c9776d1585a8e37ce6843589a linux-3.0/sound/pci/asihpi/hpimsgx.c -48cdbfe79e31a4ed4a02b6a998e4a612 linux-3.0/sound/pci/asihpi/hpimsginit.h -e2d47c154a1cc1fa7f12af6e16755b31 linux-3.0/sound/pci/asihpi/hpimsginit.c -a58a7492c94accd95cd8b0cd2cc05b8c linux-3.0/sound/pci/asihpi/hpifunc.c -75e7d1d157f06d9e5772047df483ccdc linux-3.0/sound/pci/asihpi/hpidspcd.h -18ad89e5d88845d45d6806413f0d20c7 linux-3.0/sound/pci/asihpi/hpidspcd.c -1d138da23bc2440f0900d02d2ed56a16 linux-3.0/sound/pci/asihpi/hpidebug.h -04cda5660d140b46f43c71e559727f59 linux-3.0/sound/pci/asihpi/hpidebug.c -2b7dc88abda7d77a8e1d8ec2d79c7ee8 linux-3.0/sound/pci/asihpi/hpicmn.h -a037ab7faefab626b8da0be0484f6ec2 linux-3.0/sound/pci/asihpi/hpicmn.c -e42f2623df3f8c793290bd0ec23523aa linux-3.0/sound/pci/asihpi/hpi_internal.h -66e2db63750105e7ed5d541ffbc83b45 linux-3.0/sound/pci/asihpi/hpi6205.h -a0d12dd1a6e7a94b848cc520fa3b64e8 linux-3.0/sound/pci/asihpi/hpi6205.c -9585ae6b292cc2d276f3206ca1bfa48a linux-3.0/sound/pci/asihpi/hpi6000.h -b47cff29b7214a2c57b50299ecda7dd3 linux-3.0/sound/pci/asihpi/hpi6000.c -c232e6782e75f1d2e9e5b376548aeac9 linux-3.0/sound/pci/asihpi/hpi.h -6025bd4054725bbc7064165ed9b4450b linux-3.0/sound/pci/asihpi/asihpi.c -6a11615ba7832c174ca41728d8894fb1 linux-3.0/sound/pci/asihpi/Makefile -edc0683885ee7b4496730be1323953f5 linux-3.0/sound/pci/als4000.c -26311d25bdafd0aa38586f86f6f0884f linux-3.0/sound/pci/als300.c -9f53f42c8c9cded0801b05161c8ae339 linux-3.0/sound/pci/ali5451/ali5451.c -eb0308ea5ce8a1c9878ef36871ba8360 linux-3.0/sound/pci/ali5451/Makefile -d5101d122995faabb4141d0cca455afb linux-3.0/sound/pci/ak4531_codec.c -1fc4d259500dcfe61232a771685c39c7 linux-3.0/sound/pci/ad1889.h -d28db2497b0e82fe32c29648c3798956 linux-3.0/sound/pci/ad1889.c -10e1e6c6eba2225f49dc796fd48a6e43 linux-3.0/sound/pci/ac97/ac97_proc.c -ddc409f0d4d967d239d728d52200b80a linux-3.0/sound/pci/ac97/ac97_pcm.c -7312031846d8d6fd61890728b9da9557 linux-3.0/sound/pci/ac97/ac97_patch.h -c7edb8beab6091d35656677b52ebaeb8 linux-3.0/sound/pci/ac97/ac97_patch.c -5d52d86031c96ed68a5341ada062312b linux-3.0/sound/pci/ac97/ac97_local.h -243039df7327ee11db55399a7caffee0 linux-3.0/sound/pci/ac97/ac97_id.h -cfc495f45fefefe3c3ca499e89771dbc linux-3.0/sound/pci/ac97/ac97_codec.c -4ea22d1c93969582a7d1100cd95d2620 linux-3.0/sound/pci/ac97/Makefile -8fd9919f93a4c2eab7735ad00dfdb4a1 linux-3.0/sound/pci/Makefile -d2cc3c3d066f22feac437d6922cef8b3 linux-3.0/sound/pci/Kconfig -7f67c606c8ce6653ff544df1eb83fac7 linux-3.0/sound/parisc/harmony.h -827a37325c6d4dba299753719789ba24 linux-3.0/sound/parisc/harmony.c -a93594dbea6e87a7713c0f4a893377ff linux-3.0/sound/parisc/Makefile -fe4a7d084c4e0863321ac19e82e833bc linux-3.0/sound/parisc/Kconfig -8096c90d7319000e7664b20c08b47e31 linux-3.0/sound/oss/waveartist.h -2e13ecb1da2171ea4494fa723f962cbe linux-3.0/sound/oss/waveartist.c -08eea51bf66a093764143bbdd7d37655 linux-3.0/sound/oss/vwsnd.c -358e1facbff3cf96f71fe6f7353d2804 linux-3.0/sound/oss/vidc_fill.S -808ddad2bfb8f861c6fde2d56e5cb50e linux-3.0/sound/oss/vidc.h -d63b182b0fdb08feb2b411ad5d8738c0 linux-3.0/sound/oss/vidc.c -5b624411a2b5258aa1c3045d6c892cfb linux-3.0/sound/oss/v_midi.h -b6da070e5f06d81e73e78a8b6d1d6fdc linux-3.0/sound/oss/v_midi.c -b7382115cc344db33cca37f4875a62e6 linux-3.0/sound/oss/ulaw.h -689b3e47cca9343ef0ba303bc1fe84ba linux-3.0/sound/oss/uart6850.c -9c03b660bbb2d7776cebbb0705d923d3 linux-3.0/sound/oss/uart401.c -542988bc632f3f535b5f9c27450cf598 linux-3.0/sound/oss/tuning.h -0965fe4b0a69b758e8c4f58ee170bb44 linux-3.0/sound/oss/trix.c -786ae677492923b5b9a7ec1ca5e2f035 linux-3.0/sound/oss/sys_timer.c -a8ed653977d7d7bc033051947bbc96ce linux-3.0/sound/oss/swarm_cs4297a.c -034ff622f3bbd33eba22b2431859b591 linux-3.0/sound/oss/soundvers.h -9aa8c91955e6ea21c172faafa2d4c55e linux-3.0/sound/oss/soundcard.c -4a8af322a8a7f07fe160b85bb377e371 linux-3.0/sound/oss/sound_timer.c -d14fcb2c0d91cb744bf4cfedac18e6aa linux-3.0/sound/oss/sound_firmware.h -a085c87763930adb48034b1c9e5adcf4 linux-3.0/sound/oss/sound_config.h -4608228a44feddb8afdef1aaf0e34fcc linux-3.0/sound/oss/sound_calls.h -79b380fd68abef0d698709f039dc2807 linux-3.0/sound/oss/sequencer.c -10d1cdd8fa8c81ac1ad75c582755dc9d linux-3.0/sound/oss/sb_mixer.h -d23e9f0fabad60dcbdaa56694a40b927 linux-3.0/sound/oss/sb_mixer.c -e811bcd29e91b2031ac3ee51035d5aa5 linux-3.0/sound/oss/sb_midi.c -d9e1f0f6bdf98fa235c02f45a446445f linux-3.0/sound/oss/sb_ess.h -0be4a4e58095f80a2cb0131a10f3f550 linux-3.0/sound/oss/sb_ess.c -51bdbb4ebdc22b59e72408db297a2db8 linux-3.0/sound/oss/sb_common.c -0fbab05e4315cd74ee9396f2e08ec252 linux-3.0/sound/oss/sb_card.h -656faa4ae41b58d7e462a9edacd08865 linux-3.0/sound/oss/sb_card.c -d8724b37657ab82fbb7a2f29c7a01e8b linux-3.0/sound/oss/sb_audio.c -42cb3a028a34a18857a93d286b9e50c2 linux-3.0/sound/oss/sb.h -20c2c3bbb837c3f118fe7ae93a083037 linux-3.0/sound/oss/pss.c -0576e320c3d2404e8bf1d24fa389b904 linux-3.0/sound/oss/pas2_pcm.c -066f44fd1ec8557f5e6e31e4805e6b82 linux-3.0/sound/oss/pas2_mixer.c -9ed0abef2bf49d70c6cbdb10fc844b6b linux-3.0/sound/oss/pas2_midi.c -1b7981de0300f5e4a4fc6f271ec15c58 linux-3.0/sound/oss/pas2_card.c -35b8fc1af4e545d779b737b220c817c1 linux-3.0/sound/oss/pas2.h -e86354884605fb3b9af009bd873f6b7a linux-3.0/sound/oss/os.h -f98d725464ae9469974e6bf2f9fcfeb9 linux-3.0/sound/oss/opl3_hw.h -c57cfd1674a329c2365835b4a0644c2d linux-3.0/sound/oss/opl3.c -ee9d2a7b2dfd14948356ea8eed406168 linux-3.0/sound/oss/msnd_pinnacle.h -72c0402ea0d8f92a1b45bf44b8662a97 linux-3.0/sound/oss/msnd_pinnacle.c -986d7c41be4a72648abec19c1b2bd0b9 linux-3.0/sound/oss/msnd_classic.h -e1def14ef2ec82e7467b425e20002eca linux-3.0/sound/oss/msnd_classic.c -f0f6919aa2ab28a598bbcd62cf8d1064 linux-3.0/sound/oss/msnd.h -f66d7deb98c981146fe9d5add27e1740 linux-3.0/sound/oss/msnd.c -f47d2c75a84a0a5eb4000e71a1d78a8f linux-3.0/sound/oss/mpu401.h -0ca913d83b3a4dfb861a5a473c4120b2 linux-3.0/sound/oss/mpu401.c -6cbba5e6ec5c7b6a19be9115a1d87cf0 linux-3.0/sound/oss/midibuf.c -36f4bd7459542039493fec366452adaf linux-3.0/sound/oss/midi_synth.h -57e3a03f293caf97dd2871d7e78e5b50 linux-3.0/sound/oss/midi_synth.c -9fc144ff8449e0a0685d072dc500352c linux-3.0/sound/oss/midi_ctrl.h -d21eebf230e51349453157ea31acb4e1 linux-3.0/sound/oss/kahlua.c -d0d727cdd82c54c528b1e8ac4556a04e linux-3.0/sound/oss/hex2hex.c -1361b02441cf6a18568e725964a58aeb linux-3.0/sound/oss/dmasound/dmasound_q40.c -9ffdf8bca95edd1c8887700339c66c6d linux-3.0/sound/oss/dmasound/dmasound_paula.c -28252cee4db5cd5d28513ffb81e3729d linux-3.0/sound/oss/dmasound/dmasound_core.c -02dd17fb15d8ca7818bfa2aaca64e7f1 linux-3.0/sound/oss/dmasound/dmasound_atari.c -a5baa12b86639288339338a2c36629c0 linux-3.0/sound/oss/dmasound/dmasound.h -8a1d68a09ca410f629980409c816c3bb linux-3.0/sound/oss/dmasound/Makefile -7626dba14494abb5c843786a794b1b74 linux-3.0/sound/oss/dmasound/Kconfig -798aa34da7182a1b968c99f2b205c4fc linux-3.0/sound/oss/dmabuf.c -3d28a4b3154aef39affd6877efccb7a0 linux-3.0/sound/oss/dev_table.h -25443879abc2c58d0b10499659bd3766 linux-3.0/sound/oss/dev_table.c -8cb3006e970c3d07845b1eb5d3e7430a linux-3.0/sound/oss/coproc.h -85b99f1b33c6ff87b25f54523389f81c linux-3.0/sound/oss/bin2hex.c -e917879fc01765731809294e53fc111f linux-3.0/sound/oss/audio.c -bf32455268e11aeca3760367f713f09d linux-3.0/sound/oss/aedsp16.c -7012fa6e9497b4195902aecd4ac5f6c6 linux-3.0/sound/oss/ad1848_mixer.h -ecda4b094a2af5363d35ed13722157c5 linux-3.0/sound/oss/ad1848.h -fdf03fac02505ef94e2fc60d04ff0bbb linux-3.0/sound/oss/ad1848.c -1f93e2fc154516ab7d008d60e97f480c linux-3.0/sound/oss/README.FIRST -6560b5e436ac86a5e97b6ffaa99bc932 linux-3.0/sound/oss/Makefile -fa85f12f0197660052aaf2c92a37a366 linux-3.0/sound/oss/Kconfig -e39b2322373e29d16f5884243809000d linux-3.0/sound/oss/CHANGELOG -ca0cb4b26d0666a3ad5f23034389fb25 linux-3.0/sound/oss/.gitignore -a932f5bb1e67154fc3eb07d5d8da625a linux-3.0/sound/mips/sgio2audio.c -21872685e446ff2775b2109513288fd5 linux-3.0/sound/mips/hal2.h -4444ea474c7fc73749f0353a93b02020 linux-3.0/sound/mips/hal2.c -67b1dea5a25b264576e6a5a1c4118f36 linux-3.0/sound/mips/au1x00.c -08f1f053212a7588a9b3b495e22320a8 linux-3.0/sound/mips/ad1843.c -71db2b6ecc08e6642f384c5ec17632b5 linux-3.0/sound/mips/Makefile -c7bec396b27d8619ab8bb648bbcc64c0 linux-3.0/sound/mips/Kconfig -1ebda09f71a0c5429e46fd2f356a69a4 linux-3.0/sound/last.c -ecb374f1600b9f3f090f6359d333c5b6 linux-3.0/sound/isa/wss/wss_lib.c -c56e340d83df8970f41be4ec41508802 linux-3.0/sound/isa/wss/Makefile -e410aad4f960405d3acd5a679de03e05 linux-3.0/sound/isa/wavefront/wavefront_synth.c -162e791440cf8df5758e3dec3869909e linux-3.0/sound/isa/wavefront/wavefront_midi.c -1ba83267346a3a5b6835f99c73f702dd linux-3.0/sound/isa/wavefront/wavefront_fx.c -620cb47322d59c248f68d0b7ff8a848d linux-3.0/sound/isa/wavefront/wavefront.c -ad23a5465402cd1f2c7fb7abadf4c0e5 linux-3.0/sound/isa/wavefront/Makefile -0190e4053b095f718eadcbdc07d7b126 linux-3.0/sound/isa/sscape.c -97bdfa69b1177bc25b36c76f4527c0ad linux-3.0/sound/isa/sc6000.c -e6f63cd51d5ca741440d8a3ff95de3a2 linux-3.0/sound/isa/sb/sbawe.c -6d7cdc68d173d576f7103aaad9e6dc65 linux-3.0/sound/isa/sb/sb_mixer.c -100127a75ebaaac199d6d469d9db1c95 linux-3.0/sound/isa/sb/sb_common.c -44ee72e7b24c96f62638f42334f42ff5 linux-3.0/sound/isa/sb/sb8_midi.c -8e046e2cb540a9ecd9cd7beeb9b45ba8 linux-3.0/sound/isa/sb/sb8_main.c -c40e35f7631d17acfb66f62a02f7bc94 linux-3.0/sound/isa/sb/sb8.c -aaebd2b6deafc0d60cc44a915163ab49 linux-3.0/sound/isa/sb/sb16_main.c -c92679d508855ae2f8d912ba9d37c2b4 linux-3.0/sound/isa/sb/sb16_csp.c -3435043a5f0a5daf864605bef42f4e53 linux-3.0/sound/isa/sb/sb16.c -12a8b884affc105739f7f85e0a3c1ebb linux-3.0/sound/isa/sb/jazz16.c -ee685436d9ff6b046392aa7054794e38 linux-3.0/sound/isa/sb/emu8000_synth.c -a081da00c5dd8e4ab4745b947656a4f7 linux-3.0/sound/isa/sb/emu8000_pcm.c -374540e34ffc22328dd4a532567bf751 linux-3.0/sound/isa/sb/emu8000_patch.c -de4840ad085fcab583930355970efe7c linux-3.0/sound/isa/sb/emu8000_local.h -21c3f1460b5696ca8c3a0ddfea0010fd linux-3.0/sound/isa/sb/emu8000_callback.c -42f569125ad06f7df710017bae4872db linux-3.0/sound/isa/sb/emu8000.c -88b395f0ca66fa1544ce3fba3352431e linux-3.0/sound/isa/sb/Makefile -974df45037b01c86a7ce12be1681c83a linux-3.0/sound/isa/opti9xx/opti93x.c -f4f59cf70e21bc03bfc3fa994d5aedff linux-3.0/sound/isa/opti9xx/opti92x-cs4231.c -0daa2cbb132530257df3be2ab8a54542 linux-3.0/sound/isa/opti9xx/opti92x-ad1848.c -b01dfacfaa51d7db90e588bdd192e705 linux-3.0/sound/isa/opti9xx/miro.c -62d4b8a89fd9ba879235eefea3248090 linux-3.0/sound/isa/opti9xx/Makefile -de832afc6cf0b324923ff60a3deca590 linux-3.0/sound/isa/opl3sa2.c -a657fb00a0887ce0baaa15506908752b linux-3.0/sound/isa/msnd/msnd_pinnacle_mixer.c -888cffa4f8664dfd3c118d03a5f65e4a linux-3.0/sound/isa/msnd/msnd_pinnacle.h -f150040b02bfc1aa835939d0ef08120c linux-3.0/sound/isa/msnd/msnd_pinnacle.c -737d4ee116fd871c300c8a731778674c linux-3.0/sound/isa/msnd/msnd_midi.c -9bdcc697bcd56b7f88e67d03f44c2e69 linux-3.0/sound/isa/msnd/msnd_classic.h -e1def14ef2ec82e7467b425e20002eca linux-3.0/sound/isa/msnd/msnd_classic.c -5c2a88c691244a2880cc82ccd8130171 linux-3.0/sound/isa/msnd/msnd.h -afffd7cf6ee211c1e30d098392db8f99 linux-3.0/sound/isa/msnd/msnd.c -851618d7f61a1ea14d9b69ffb299f120 linux-3.0/sound/isa/msnd/Makefile -58b9310d5da69bda2c5cb1b31f56b0e9 linux-3.0/sound/isa/gus/interwave.c -e1d9f44b5e45de1df9ff9a3a21b76677 linux-3.0/sound/isa/gus/interwave-stb.c -26c7d00aef4a0eb082985518ff734088 linux-3.0/sound/isa/gus/gusmax.c -56bacdb41cbfdf431eade686904d15c0 linux-3.0/sound/isa/gus/gusextreme.c -99bc6a6e88970ae2f34182729d611bb0 linux-3.0/sound/isa/gus/gusclassic.c -7bd6aabd717d25a6a5f5b305c7dd2b18 linux-3.0/sound/isa/gus/gus_volume.c -539f7d205ffac55ed5610d65f5e7e350 linux-3.0/sound/isa/gus/gus_uart.c -89fdf1c585d43982f38e670bb2a4330a linux-3.0/sound/isa/gus/gus_timer.c -f9ac24a02accca0d7f807d3ec359ae80 linux-3.0/sound/isa/gus/gus_tables.h -6e9c69cf3fd622672e0c53eba177d27c linux-3.0/sound/isa/gus/gus_reset.c -32e07b9c15d347ed2e48048d8c962bd6 linux-3.0/sound/isa/gus/gus_pcm.c -95135c72ea1e3c965c8072114a10531d linux-3.0/sound/isa/gus/gus_mixer.c -8dd5f09bb1809bac4fe663de98910eef linux-3.0/sound/isa/gus/gus_mem_proc.c -3f16580ffbbabae2043a552fe144f2b3 linux-3.0/sound/isa/gus/gus_mem.c -e22c5ce6faa4ed03f6e9f72e36c77f57 linux-3.0/sound/isa/gus/gus_main.c -96dd9514215a643f0410aa38fc7a2fb2 linux-3.0/sound/isa/gus/gus_irq.c -0b68f3116a5899c3f691ac4f42e5367f linux-3.0/sound/isa/gus/gus_io.c -b26fdd6455ee0a155bac7bb8d3f20e59 linux-3.0/sound/isa/gus/gus_instr.c -9a91570c01450d90ca1a307fe746c2dc linux-3.0/sound/isa/gus/gus_dram.c -6a9b263b6f31fe8aa3ac46e4dc924b6a linux-3.0/sound/isa/gus/gus_dma.c -a43420912444ddf0f299069d223ecc14 linux-3.0/sound/isa/gus/Makefile -cba8d1e29ff976040948668b10316652 linux-3.0/sound/isa/galaxy/galaxy.c -ab6da131f4ca922b9b7acbacabc2a6b8 linux-3.0/sound/isa/galaxy/azt2316.c -1694f4da487f5c8105bed8766394ea3a linux-3.0/sound/isa/galaxy/azt1605.c -7d9beffc6359f814ca765fe98bfd4a04 linux-3.0/sound/isa/galaxy/Makefile -ad27312f9f107ead5b91a8e3d1a57e0d linux-3.0/sound/isa/es18xx.c -3cdc3e65f3393fe0e001cc47073efbe1 linux-3.0/sound/isa/es1688/es1688_lib.c -25787779804e5d58d59291e261d93e7d linux-3.0/sound/isa/es1688/es1688.c -5dbc9cacc35f25b92510a30d1d73ff42 linux-3.0/sound/isa/es1688/Makefile -a08cdce8d275af99314f2eb12fd7d94c linux-3.0/sound/isa/cs423x/cs4236_lib.c -3c9e394c564dcc420ce8efe370d572cf linux-3.0/sound/isa/cs423x/cs4236.c -a487d06539ca20484ab5eb4dc43959e5 linux-3.0/sound/isa/cs423x/cs4231.c -e42e2ed6cb7bf42791a811d9dccb7c49 linux-3.0/sound/isa/cs423x/Makefile -230e8da1f65c1379cca3be4121615333 linux-3.0/sound/isa/cmi8330.c -d57c691362cf54bb824052ae18a64c60 linux-3.0/sound/isa/azt2320.c -73ae9fcfdffd33a8573ccd27745ab37b linux-3.0/sound/isa/als100.c -2ec6015450431b07ee484caa0c36dd71 linux-3.0/sound/isa/adlib.c -a96b1fd9b9f856cc3f159f64576b55a2 linux-3.0/sound/isa/ad1848/ad1848.c -e6cb2f1cd0de30225807901db862eb5d linux-3.0/sound/isa/ad1848/Makefile -17fb0d30bd049c89ed35633f5ecc273c linux-3.0/sound/isa/ad1816a/ad1816a_lib.c -177d20473c43a788cddd60131ca23864 linux-3.0/sound/isa/ad1816a/ad1816a.c -c5ce248ddbce3859b93046221fe9a2c8 linux-3.0/sound/isa/ad1816a/Makefile -7603a8e4d5516e565152063f42ae2279 linux-3.0/sound/isa/Makefile -82f0e6fba532d0f55f01a7219f331fa5 linux-3.0/sound/isa/Kconfig -92b66e3b878867ad4e6b6b3654130225 linux-3.0/sound/i2c/tea6330t.c -8f5bbc5632f62321d436590836b44878 linux-3.0/sound/i2c/other/tea575x-tuner.c -c973fe31cd7ba0551cabfc7fc1ef8ca7 linux-3.0/sound/i2c/other/pt2258.c -b075b3c0f31c300dd6f7e339b63fb2ad linux-3.0/sound/i2c/other/ak4xxx-adda.c -78ff8335ee1f7147ad9e1b80743c6755 linux-3.0/sound/i2c/other/ak4117.c -52fd3365c24d58a0878fc3fc0b0c04e8 linux-3.0/sound/i2c/other/ak4114.c -f1dc930e98265a8692aff9882dbe5aab linux-3.0/sound/i2c/other/ak4113.c -4e74cc6f14774d5a26231d1344fce2e1 linux-3.0/sound/i2c/other/Makefile -3c3977c96e331a4d7a3629dca178e8d6 linux-3.0/sound/i2c/i2c.c -7386acd6faf7af8f192523709d5d6907 linux-3.0/sound/i2c/cs8427.c -4712ae1ccc39fe77e8a6ac4ac7a1cfaa linux-3.0/sound/i2c/Makefile -8f09cd0e077787c3a4d412b775d5b8fd linux-3.0/sound/firewire/speakers.c -6ce20689f5d4f600d56b162ba61d89aa linux-3.0/sound/firewire/packets-buffer.h -7c1d076c9a49e0aae2cebae3dca3ad67 linux-3.0/sound/firewire/packets-buffer.c -4265c12a195b12ffd77976a73ce3a977 linux-3.0/sound/firewire/lib.h -996ecec86386f36be017a227a5606068 linux-3.0/sound/firewire/lib.c -aee92e8b6e30278b93bf8c934800b139 linux-3.0/sound/firewire/iso-resources.h -5713a9334bdeada4a748ba2b5f1404d7 linux-3.0/sound/firewire/iso-resources.c -c48846a2515af8bd1d416daabb4197dd linux-3.0/sound/firewire/isight.c -7ef010b17f45a9522a36a65a3124c1a5 linux-3.0/sound/firewire/fcp.h -d577c7bfe4e1b2187da4ec3eb4d67439 linux-3.0/sound/firewire/fcp.c -70f5c17bec342cdad66ec670e8fb25d2 linux-3.0/sound/firewire/cmp.h -8457052f6a98888f44b8df9b89e1f220 linux-3.0/sound/firewire/cmp.c -55c90708df89e53e8117f7ae12f2aa59 linux-3.0/sound/firewire/amdtp.h -5c6660bed02acaff2d7ac45b79cfe7a1 linux-3.0/sound/firewire/amdtp.c -c60bdb004925418b69c8cadb90936fa2 linux-3.0/sound/firewire/Makefile -edf6a3332822f89b0dce31923935419d linux-3.0/sound/firewire/Kconfig -8dd2b1ea367b249a44ed974054741fbf linux-3.0/sound/drivers/vx/vx_uer.c -3078224b51f89bdfda3d998996725ea2 linux-3.0/sound/drivers/vx/vx_pcm.c -775ed8f6f3f8f31581bfa8c3127e4f95 linux-3.0/sound/drivers/vx/vx_mixer.c -56179e569e874243d4bc10dbfeeb8502 linux-3.0/sound/drivers/vx/vx_hwdep.c -41d7377dd2bee36a57eb1ab1ffa5de5d linux-3.0/sound/drivers/vx/vx_core.c -66ee223d0805afe8e03663ad96d4fb43 linux-3.0/sound/drivers/vx/vx_cmd.h -c59e79cfd0d35be848b09c90ebf283d9 linux-3.0/sound/drivers/vx/vx_cmd.c -951f3d895f6af1d891d1856004002092 linux-3.0/sound/drivers/vx/Makefile -3e74096e4362dcea0cc2cc568bfd0242 linux-3.0/sound/drivers/virmidi.c -04a9b5ed82576bb52c791b9b875552f3 linux-3.0/sound/drivers/serial-u16550.c -10d27f3de68e5ab4eeff56c0647e0491 linux-3.0/sound/drivers/portman2x4.c -f79c0b37dcd866bad6ec808c2ed4c52a linux-3.0/sound/drivers/pcsp/pcsp_mixer.c -98b5cabe9161bf5d4ea720da58ac6cd4 linux-3.0/sound/drivers/pcsp/pcsp_lib.c -680088a1fb84454add4355eab1fdf58c linux-3.0/sound/drivers/pcsp/pcsp_input.h -e3bde40ad116a5420e0f3d20696d846c linux-3.0/sound/drivers/pcsp/pcsp_input.c -b468814ce894dca12cf78f740a803b49 linux-3.0/sound/drivers/pcsp/pcsp.h -d09d8b560a8709f159eddcdfc4474051 linux-3.0/sound/drivers/pcsp/pcsp.c -8b170a95b6734573dbac9f98aa49b026 linux-3.0/sound/drivers/pcsp/Makefile -67fb5d018151ba2dc90648d5c138bbc7 linux-3.0/sound/drivers/pcm-indirect2.h -c761d8b80331b71aaa369c3ff9302bc5 linux-3.0/sound/drivers/pcm-indirect2.c -e0f5b5ac94e05b12eb0db1e286ea2c27 linux-3.0/sound/drivers/opl4/yrw801.c -f6ed5e10732ae53c9a80bf55d36692c9 linux-3.0/sound/drivers/opl4/opl4_synth.c -9637950eb237301ab1bcb4909a5bdc4b linux-3.0/sound/drivers/opl4/opl4_seq.c -d2b8d9057a661fbb69052bf4b3d6c30c linux-3.0/sound/drivers/opl4/opl4_proc.c -b2952a6bcd3939fb9a6ebc03519d48db linux-3.0/sound/drivers/opl4/opl4_mixer.c -c825ee1bd4e0278a45c4ee8c64f19fdc linux-3.0/sound/drivers/opl4/opl4_local.h -a1b296f7be15b82f4122e8f7de4041d4 linux-3.0/sound/drivers/opl4/opl4_lib.c -affef427edac4d8ed2e0ce027681d90e linux-3.0/sound/drivers/opl4/Makefile -21574636a578e9c1b23d8c2dff7dd285 linux-3.0/sound/drivers/opl3/opl3_voice.h -709ba04aca2cf99514327c4561358b71 linux-3.0/sound/drivers/opl3/opl3_synth.c -4ac1556033a2525b89924f94c8a6fcd7 linux-3.0/sound/drivers/opl3/opl3_seq.c -244103b708067dd15d27e77178b1f541 linux-3.0/sound/drivers/opl3/opl3_oss.c -0c2fa630ef3af60b9b4ada8e56fab284 linux-3.0/sound/drivers/opl3/opl3_midi.c -54966302a90041da5a5d1e512581a728 linux-3.0/sound/drivers/opl3/opl3_lib.c -2e05c708aafd952513959b66e4c97c8c linux-3.0/sound/drivers/opl3/opl3_drums.c -7e12e3b87772606614f69a10b3e3945e linux-3.0/sound/drivers/opl3/Makefile -17e1324dad43553b29d9b3de59a36d22 linux-3.0/sound/drivers/mts64.c -1a2a3f15a3ab7a969d4fd99d23068264 linux-3.0/sound/drivers/mtpav.c -46ab23c84b02dac39f4a24e383902e25 linux-3.0/sound/drivers/mpu401/mpu401_uart.c -c8d33e631c6ce50c42a977ec3fbb4e4b linux-3.0/sound/drivers/mpu401/mpu401.c -cb5f4fd1052b73bf8341b21148860473 linux-3.0/sound/drivers/mpu401/Makefile -65040a6df25ade9a34c162127143f374 linux-3.0/sound/drivers/ml403-ac97cr.c -43695c4e1f40209c98e4671f601da957 linux-3.0/sound/drivers/dummy.c -dca012f9de1a859eb9933c045c0b6f70 linux-3.0/sound/drivers/aloop.c -75cd8d0e79f65c747cce35eed9516c14 linux-3.0/sound/drivers/Makefile -dbb5f1d76e3183f45068a17a2255ee58 linux-3.0/sound/drivers/Kconfig -b9cfa184b23ba4ca7de07c0adb316c75 linux-3.0/sound/core/vmaster.c -5b7b1b2621aadfdc1894bf512883693e linux-3.0/sound/core/timer_compat.c -72ea9c3d777cc29f8b189b994c70e735 linux-3.0/sound/core/timer.c -14682e20c6915b5510f387c567f0860a linux-3.0/sound/core/sound_oss.c -0c94f9dd7fc15ad6658b40ed938627c6 linux-3.0/sound/core/sound.c -b64c05b51b6e6502c189f5f840bca635 linux-3.0/sound/core/sgbuf.c -63da7468634a338256e64d09c96c9160 linux-3.0/sound/core/seq/seq_virmidi.c -0ed2633ab8137fa92035b16e1619076f linux-3.0/sound/core/seq/seq_timer.h -a4f9e0c0889a8c4e283dc804fee08c6e linux-3.0/sound/core/seq/seq_timer.c -f44685ad67570276765f3dde2a5db587 linux-3.0/sound/core/seq/seq_system.h -37a76a08926f7e62b65c48944bc2c82e linux-3.0/sound/core/seq/seq_system.c -ebd755c9b82fd2a7edababe0f4193657 linux-3.0/sound/core/seq/seq_queue.h -527348feac121ec8f58c471900eb2b7d linux-3.0/sound/core/seq/seq_queue.c -4cbc97aee9bc43b74bd2ab3bde742953 linux-3.0/sound/core/seq/seq_prioq.h -c09e48238b82ae401b5c6c7411a26877 linux-3.0/sound/core/seq/seq_prioq.c -a7d6b499953645e97eb94cfefc06903b linux-3.0/sound/core/seq/seq_ports.h -311480be1423de6886441311e84a638f linux-3.0/sound/core/seq/seq_ports.c -60c090e59218530466bfa218232c6523 linux-3.0/sound/core/seq/seq_midi_event.c -956e6dc929178f319dc56074f6d27a10 linux-3.0/sound/core/seq/seq_midi_emul.c -da6d982496d0b7bbdf56cf84b1e1d249 linux-3.0/sound/core/seq/seq_midi.c -237734125dbf997f56dcfdfa90171207 linux-3.0/sound/core/seq/seq_memory.h -512ea07b95eb27d7dad274d7eb5af626 linux-3.0/sound/core/seq/seq_memory.c -bc370c0e167f6443e13664af790651ac linux-3.0/sound/core/seq/seq_lock.h -1c7138f6a69c80e29f4b7775820595b1 linux-3.0/sound/core/seq/seq_lock.c -9e3678410b02b5b3601d5ba048954823 linux-3.0/sound/core/seq/seq_info.h -0b380878d50c7188160aacb5cc200450 linux-3.0/sound/core/seq/seq_info.c -7f90a5fa5db0242e781feb6146491ef9 linux-3.0/sound/core/seq/seq_fifo.h -6d06710beacae28348d5ed4623dbef5c linux-3.0/sound/core/seq/seq_fifo.c -97db0592823d87fef6ad9c998d7f5f3d linux-3.0/sound/core/seq/seq_dummy.c -24a356310e5bfbde08a5452386297d75 linux-3.0/sound/core/seq/seq_device.c -595ce59d2770a10da09c9ea7238dc269 linux-3.0/sound/core/seq/seq_compat.c -3d5ad4adff049c647919dc7e534ca572 linux-3.0/sound/core/seq/seq_clientmgr.h -b8a4b2f4816452f868cb6f5b75fd3d10 linux-3.0/sound/core/seq/seq_clientmgr.c -e527806c42050a33b1dbfcc72661effc linux-3.0/sound/core/seq/seq.c -6f727868f9b3a60ce5e73bf725c35c60 linux-3.0/sound/core/seq/oss/seq_oss_writeq.h -c015ba84ec18386072ec65ead8742995 linux-3.0/sound/core/seq/oss/seq_oss_writeq.c -5fbb6b89b53771b858fb2709dcac2030 linux-3.0/sound/core/seq/oss/seq_oss_timer.h -9a69d648cc99aa7958fda26d03abbcb8 linux-3.0/sound/core/seq/oss/seq_oss_timer.c -19665f799b65814735087791ed13b7c7 linux-3.0/sound/core/seq/oss/seq_oss_synth.h -4f57d15e3d697a102adc8f9494155f29 linux-3.0/sound/core/seq/oss/seq_oss_synth.c -6d7ceb14fb4b8dc43188be5a225d3c04 linux-3.0/sound/core/seq/oss/seq_oss_rw.c -31a67898196d61f8ccc3d4e43630dc2b linux-3.0/sound/core/seq/oss/seq_oss_readq.h -edc67ac21041040f7278cb1abdbdd281 linux-3.0/sound/core/seq/oss/seq_oss_readq.c -cfc8dc59e22b4f697c9e3d0f6c8d712c linux-3.0/sound/core/seq/oss/seq_oss_midi.h -5d590d8312bbd1f22db9dc6b05127247 linux-3.0/sound/core/seq/oss/seq_oss_midi.c -67fda32d9e04c5fe456f177f41d19cf2 linux-3.0/sound/core/seq/oss/seq_oss_ioctl.c -bbbf8f585dd3db83e496b11a0e219453 linux-3.0/sound/core/seq/oss/seq_oss_init.c -2c0a7c218802165006b28f3f3c125e24 linux-3.0/sound/core/seq/oss/seq_oss_event.h -8070be3ff6e34f6c7987b8bc142265c1 linux-3.0/sound/core/seq/oss/seq_oss_event.c -18cb8abee40f891d09ec22f5fa8d1318 linux-3.0/sound/core/seq/oss/seq_oss_device.h -747ffe3d198dcebc3f825f1c99ebae87 linux-3.0/sound/core/seq/oss/seq_oss.c -133d9dc2a02f0b627abab4524a808733 linux-3.0/sound/core/seq/oss/Makefile -5a9769d73d54cbaab46ce45ed8b69693 linux-3.0/sound/core/seq/Makefile -4502b39eb151b7e486179515883595e7 linux-3.0/sound/core/seq/Kconfig -88134e884c94cfc9f69e7af6a30ed5e8 linux-3.0/sound/core/rtctimer.c -e9f08f0e9bc8ef3d899d376f8bf68316 linux-3.0/sound/core/rawmidi_compat.c -213e4a877a30f83d65b020e9167515a9 linux-3.0/sound/core/rawmidi.c -4af52913f59c099fc78c35574b65c0df linux-3.0/sound/core/pcm_timer.c -67afd12626c5a80f67fce041232ec4a2 linux-3.0/sound/core/pcm_native.c -1530046eac2b5271779464a542aa85cb linux-3.0/sound/core/pcm_misc.c -5dac0f200391a26892d3cd17f71eb1bf linux-3.0/sound/core/pcm_memory.c -14d817a7b3830b04dd9b872fcc098a9c linux-3.0/sound/core/pcm_lib.c -7dd491abb509fd43e750ec3a8d1abf35 linux-3.0/sound/core/pcm_compat.c -cbaee2979fad096fa99b20bbadb21292 linux-3.0/sound/core/pcm.c -6b5032d38065f3af91e8164e5792e6b9 linux-3.0/sound/core/oss/route.c -dc9a3d8d7ae260a3f84e432dfbf79ea5 linux-3.0/sound/core/oss/rate.c -950fa6c7a91661a5c054f4c548a0ecd9 linux-3.0/sound/core/oss/pcm_plugin.h -e8c4102e480f922907225bfdde6c3048 linux-3.0/sound/core/oss/pcm_plugin.c -5ab5a16cce6e3827440027b739cc10a8 linux-3.0/sound/core/oss/pcm_oss.c -13679a4a6084f4cd15410b159e683d4e linux-3.0/sound/core/oss/mulaw.c -88a0d4c878628004488759db83bc96d7 linux-3.0/sound/core/oss/mixer_oss.c -0836477845a3bef85154d8b8fc0bdcb7 linux-3.0/sound/core/oss/linear.c -76dd5f8bf57fd6e3f9f3c418c1a78463 linux-3.0/sound/core/oss/io.c -3f5068d2670a55ccd693d4d518bf3a05 linux-3.0/sound/core/oss/copy.c -7227e900dcc1eb5f930a653d237a9234 linux-3.0/sound/core/oss/Makefile -a34e08d4c34ac3d3851dfca51fe97f73 linux-3.0/sound/core/misc.c -b7b6eb9bd72e5b8a58681426240a8b93 linux-3.0/sound/core/memory.c -15ea4baf380a155e1724add152831ccb linux-3.0/sound/core/memalloc.c -df5814728477cf017df7453fa15f7a01 linux-3.0/sound/core/jack.c -a9b507d618c257482dec119e5ac7bb60 linux-3.0/sound/core/isadma.c -9579e13c878eabd1bcd2cebf95b62c0f linux-3.0/sound/core/init.c -f1ad0c3dfc21eda4312ff6bcb9656e74 linux-3.0/sound/core/info_oss.c -debe991124efdfc029084021c7fe9f6e linux-3.0/sound/core/info.c -9d7bc4aacfd8787c19392f85d1e61b4c linux-3.0/sound/core/hwdep_compat.c -632443523e19cd0397238e8e312ed23e linux-3.0/sound/core/hwdep.c -4848844523d125b783f3ff27412a7821 linux-3.0/sound/core/hrtimer.c -36089a3e90772c674158044556ac39ea linux-3.0/sound/core/device.c -8a19b1189d7d176af8b9d36f01d8afec linux-3.0/sound/core/control_compat.c -5e09b1b27553b2b80683000ecfd25f16 linux-3.0/sound/core/control.c -fddcd978ae3cd4c3568fc5864155960c linux-3.0/sound/core/Makefile -7bc2a4268ca739a275da5fc88844e4ab linux-3.0/sound/core/Kconfig -462018ed9739cb8e88c3a2320b62d9ba linux-3.0/sound/atmel/ac97c.h -f49552a56de1587fb9542e82412570ec linux-3.0/sound/atmel/ac97c.c -d250c2650e43de1303403d232de0ba6e linux-3.0/sound/atmel/abdac.c -fa03ef55f5adc02476805adb0d00758b linux-3.0/sound/atmel/Makefile -aa3bdaf122fe000013391f0f63228789 linux-3.0/sound/atmel/Kconfig -8fad2b609c3d8655e7bc1bfed729e923 linux-3.0/sound/arm/pxa2xx-pcm.h -1994ca4c0c39541911a0c9eeb9f54a25 linux-3.0/sound/arm/pxa2xx-pcm.c -b18e46f9bdf2aeffaeb1b79d33d76912 linux-3.0/sound/arm/pxa2xx-pcm-lib.c -f4017ab28daea91ec3cc7692fed45fed linux-3.0/sound/arm/pxa2xx-ac97.c -b4daf8b9ec1ce4e204033e7521494692 linux-3.0/sound/arm/pxa2xx-ac97-lib.c -3182b0c385242d3ee72b0aad5adfe888 linux-3.0/sound/arm/aaci.h -f7c08fc29a96618ff14e270585a7be9e linux-3.0/sound/arm/aaci.c -37ccdea37235530dee74433285192480 linux-3.0/sound/arm/Makefile -16245b89b537afd476f9fe3269594c2f linux-3.0/sound/arm/Kconfig -eab40cc549399d20ac7d266b07788bd8 linux-3.0/sound/aoa/soundbus/sysfs.c -edc717e8553280a1e5e7a2bc8c06d8fc linux-3.0/sound/aoa/soundbus/soundbus.h -d8ee39d613559a55c2a6483f80a2670b linux-3.0/sound/aoa/soundbus/i2sbus/pcm.c -e4f2671d69b34f9bc6c99fa60abb19d2 linux-3.0/sound/aoa/soundbus/i2sbus/interface.h -5caadbb3556e11dd9528d3294d876fc0 linux-3.0/sound/aoa/soundbus/i2sbus/i2sbus.h -a62d388caefc7475df6dca1a6f5211c3 linux-3.0/sound/aoa/soundbus/i2sbus/core.c -0035d1b932ff94e754ce67567bf1bee6 linux-3.0/sound/aoa/soundbus/i2sbus/control.c -12f5174b535043834ff50e8f19131b4a linux-3.0/sound/aoa/soundbus/i2sbus/Makefile -308540f0e55d0d75cc2b085442ff7b63 linux-3.0/sound/aoa/soundbus/core.c -fa09740a6f5da0902524462f43206910 linux-3.0/sound/aoa/soundbus/Makefile -be59301bddbf2bea02a986fe6991fe39 linux-3.0/sound/aoa/soundbus/Kconfig -c6555065970d0ed25525c744caa1aecc linux-3.0/sound/aoa/fabrics/layout.c -fe55146f21a495d4f02697ae668f5a1e linux-3.0/sound/aoa/fabrics/Makefile -dbaac1548c0a0b967f086ee620b402fd linux-3.0/sound/aoa/fabrics/Kconfig -e8d20dab01d8d814cdd047ea49542dd3 linux-3.0/sound/aoa/core/gpio-pmf.c -2ef33a93fe9fb5cd97e5960bade652a3 linux-3.0/sound/aoa/core/gpio-feature.c -9eb67f9e7c20ff203c6db01da15df273 linux-3.0/sound/aoa/core/core.c -3e1c51812c451c753fed1a929ff6b0ae linux-3.0/sound/aoa/core/alsa.h -310a75068a0b036ba54befc3e209f98e linux-3.0/sound/aoa/core/alsa.c -45dc98e90fc0bee185125e0653e2aeba linux-3.0/sound/aoa/core/Makefile -ca6d006eca9a248eef72118080fca2b2 linux-3.0/sound/aoa/codecs/toonie.c -836bfa8e52ed674cbb5934ed0d52498a linux-3.0/sound/aoa/codecs/tas.h -9d0251580ef8e20538f7ab6f4f789cdf linux-3.0/sound/aoa/codecs/tas.c -d93046c243a2b23b41ece359638555e1 linux-3.0/sound/aoa/codecs/tas-gain-table.h -82dcd4e97e86434a68a91c9d4455b2c3 linux-3.0/sound/aoa/codecs/tas-basstreble.h -05d1fd783e690c6441849371584ec30b linux-3.0/sound/aoa/codecs/onyx.h -7c6170daa764ed6cd90479521ff17723 linux-3.0/sound/aoa/codecs/onyx.c -272b53ae68151c0ed13cd7d2ded4c0db linux-3.0/sound/aoa/codecs/Makefile -bd07ef1831434136bc09438f3c8ac75c linux-3.0/sound/aoa/codecs/Kconfig -e20a8a2f168597dcf6033e289912bf70 linux-3.0/sound/aoa/aoa.h -f6293617cf76e5cf4ede3570e2c6eb9a linux-3.0/sound/aoa/aoa-gpio.h -2e6537269845624bbf1f86d8e769a330 linux-3.0/sound/aoa/Makefile -c520e1904dd6d3a8b92ee2256093c41c linux-3.0/sound/aoa/Kconfig -7f167377b3f7e3b8599ce437da9ca594 linux-3.0/sound/ac97_bus.c -7b77a3799b4f89bd566f87b423147959 linux-3.0/sound/Makefile -b49a270c9469d06a11e35899d8c88162 linux-3.0/sound/Kconfig -5f57e642e6853b9958ee9b76803a1c3d linux-3.0/security/tomoyo/util.c -3b6797f58ac8226c8d57befbcfc83d90 linux-3.0/security/tomoyo/tomoyo.c -1fab3513e7c83c79f908a53e7aaca90c linux-3.0/security/tomoyo/securityfs_if.c -31b3aec17c653405ad4b1a042fcd1b68 linux-3.0/security/tomoyo/realpath.c -16bcd522c3432629c9af792c0c7278c9 linux-3.0/security/tomoyo/mount.c -e1ea91d3f07f6a6e80a28a810a2887e0 linux-3.0/security/tomoyo/memory.c -cd4511963a36ede466326ecad9700b86 linux-3.0/security/tomoyo/load_policy.c -c73c5f9626f896dbaf082aff0a538fe9 linux-3.0/security/tomoyo/group.c -3265e4a58cf0574e088781e69617de57 linux-3.0/security/tomoyo/gc.c -ddbaf2a7677beab1e799c9d546eca138 linux-3.0/security/tomoyo/file.c -80b27c1b1a9e6d35b959b804f4e8f69e linux-3.0/security/tomoyo/domain.c -89c8bba9c8489bef291bb2dd7480f421 linux-3.0/security/tomoyo/common.h -be1d1ff5f8d2743bb562daffb6f77fb8 linux-3.0/security/tomoyo/common.c -7abd021e6080cf179e2b2c6877431359 linux-3.0/security/tomoyo/Makefile -a2462aad4201c666bd248300bb99b45f linux-3.0/security/tomoyo/Kconfig -ce011e9ae3f8be8e9557f8d0a95e32fe linux-3.0/security/smack/smackfs.c -a08d2822b86948b913e73498ca7c455b linux-3.0/security/smack/smack_lsm.c -19110c10dc2510b8c4254f1bcdfc443b linux-3.0/security/smack/smack_access.c -39aa137d2a2eea105cb6fbfa99dc1d0a linux-3.0/security/smack/smack.h -e87f4f9ac2e46d819ff407b1fddf23c1 linux-3.0/security/smack/Makefile -1a5aeb51218d6e5fd6c40051b72b8a19 linux-3.0/security/smack/Kconfig -1d1f0cb01e9baa07f27bfd596c2c286a linux-3.0/security/selinux/xfrm.c -3b821cb4ce0096931c204fbc119374fe linux-3.0/security/selinux/ss/symtab.h -67324d67fdb01e38545902845be46542 linux-3.0/security/selinux/ss/symtab.c -f870af075a7bd7e6e68453a58020d3bc linux-3.0/security/selinux/ss/status.c -20bc1f0c4d0c1bee7b95774f3d91c1c2 linux-3.0/security/selinux/ss/sidtab.h -5f4fd668033aaca263efa216c664a3c8 linux-3.0/security/selinux/ss/sidtab.c -486cc5613ac10c831c9721b5f2568917 linux-3.0/security/selinux/ss/services.h -de42b810dff685f171dd93dc74ddeb28 linux-3.0/security/selinux/ss/services.c -dacf4a8bc9d7922206137faac578ab81 linux-3.0/security/selinux/ss/policydb.h -687a0748eae1f84038ace509ced532de linux-3.0/security/selinux/ss/policydb.c -4b36d8764c6ee4a7661508258cb9d0b9 linux-3.0/security/selinux/ss/mls_types.h -4b496a6d2b80e44ec17199e59ed194c9 linux-3.0/security/selinux/ss/mls.h -04928f0e7970996169c1e7eec2c4b9a7 linux-3.0/security/selinux/ss/mls.c -639ffabd31f242610dc5ff545a44ade4 linux-3.0/security/selinux/ss/hashtab.h -336ecdf4af93a396c98e1eb82dfbba44 linux-3.0/security/selinux/ss/hashtab.c -d0fc5827a3af946e9ba1589d7b4b2a42 linux-3.0/security/selinux/ss/ebitmap.h -c9c3f83439639216d4f7bf02d4efb7e5 linux-3.0/security/selinux/ss/ebitmap.c -899c9c7a2473d34be5502500d26eebaf linux-3.0/security/selinux/ss/context.h -206e569bc1e6499031b6f878126187fe linux-3.0/security/selinux/ss/constraint.h -d13fd17e20ae02b2d467b62da0fe1305 linux-3.0/security/selinux/ss/conditional.h -4673d3fba655d37cb9184013cc4f16b5 linux-3.0/security/selinux/ss/conditional.c -4bc0acafe642866d4705b6a683eb8b75 linux-3.0/security/selinux/ss/avtab.h -697df01181d28ed8ece86f1444909f56 linux-3.0/security/selinux/ss/avtab.c -d31726629a854754d791674e2842f694 linux-3.0/security/selinux/selinuxfs.c -18fb7a5515f93ee936f6cac9418b24c8 linux-3.0/security/selinux/nlmsgtab.c -d3fa1f08077de1bf7a5fa3372496723b linux-3.0/security/selinux/netport.c -83acee6b15d8aef3777affed02ff12a5 linux-3.0/security/selinux/netnode.c -6bff1ba055ac278485cb2913428c4505 linux-3.0/security/selinux/netlink.c -d5feb7e241041e05dccee6ed2c40daa7 linux-3.0/security/selinux/netlabel.c -54609e9e90ed7f35f4cd71c518ccc46f linux-3.0/security/selinux/netif.c -0e86f893eb850cecfbc5ebefdc8b2754 linux-3.0/security/selinux/include/xfrm.h -f423e127bc16a1df796d333d1e251cb3 linux-3.0/security/selinux/include/security.h -1d34c810b2c92db9cf5e35c3ab0053c5 linux-3.0/security/selinux/include/objsec.h -0da4482e65432b09314300ea71a9e028 linux-3.0/security/selinux/include/netport.h -6fb9ee2a68c225caec3b8199d167e520 linux-3.0/security/selinux/include/netnode.h -eb1c996f52f6aa4d561ea1d677a714ef linux-3.0/security/selinux/include/netlabel.h -d31948df60e838b58f86c935bdcdcaec linux-3.0/security/selinux/include/netif.h -3fa3beb0c15149edd9db5641eb0994a2 linux-3.0/security/selinux/include/initial_sid_to_string.h -6692432b941396dc5485e6d62cfc7d5f linux-3.0/security/selinux/include/conditional.h -af8091b7738f75706b35965977854389 linux-3.0/security/selinux/include/classmap.h -aca2f35a2ed821152d3eff6cf31811ca linux-3.0/security/selinux/include/avc_ss.h -c020a92e36f273e7866bc769b55a8e98 linux-3.0/security/selinux/include/avc.h -1a96345b7380237a2107e96c874c1d0d linux-3.0/security/selinux/include/audit.h -3044cd4d4d8723df189365cd4f18342a linux-3.0/security/selinux/hooks.c -2ba0bc0c986da363cb7b3b95edf59d69 linux-3.0/security/selinux/exports.c -e18cf4714104c665c5d7242bbead31a3 linux-3.0/security/selinux/avc.c -804ade267e3276bc5a5747135e1a58b5 linux-3.0/security/selinux/Makefile -096a9c8a832e1e5e81e0a8614ccf9f7b linux-3.0/security/selinux/Kconfig -6fa9b183d1f035988a4e8c0e546576cb linux-3.0/security/selinux/.gitignore -ca7c9da1806281ea66a2f8ac0560ea24 linux-3.0/security/security.c -fd7f6f8b711dbe02fa8da6c886fda8ce linux-3.0/security/min_addr.c -6cfc3dcb7a14c93f4f5d844513c7b343 linux-3.0/security/lsm_audit.c -203fc953e1b9d3c1fb7645ced2d95b67 linux-3.0/security/keys/user_defined.c -eabd43c8cd50260e182f02155d9e5e2c linux-3.0/security/keys/trusted.h -05b959e363c6b5d84a2d82a9a7c28ff0 linux-3.0/security/keys/trusted.c -b4cdc1492c0068641082acdbcfb1f977 linux-3.0/security/keys/sysctl.c -588e934ffd70f8268874ae729defe3aa linux-3.0/security/keys/request_key_auth.c -da681d749289f68d5d7699cd5a52a672 linux-3.0/security/keys/request_key.c -e2876926ad6b3b0ba7439362a923ced8 linux-3.0/security/keys/process_keys.c -6b91aeb310383e59554eab69cdfd02d7 linux-3.0/security/keys/proc.c -1fc3b043e9697ea06ccb555473389fd7 linux-3.0/security/keys/permission.c -0ddf161c58704c1354835618f1bc6a84 linux-3.0/security/keys/keyring.c -a466273dfc18d0fb6313e03e62069b4f linux-3.0/security/keys/keyctl.c -8d2813f494c46036e6ac400255e114d8 linux-3.0/security/keys/key.c -827cdd218c914df2e19577943c3f98f7 linux-3.0/security/keys/internal.h -8216ec8bb8f8982f31b9ae8989037e16 linux-3.0/security/keys/gc.c -cddfea6616f9a19c5226c8a347f39a58 linux-3.0/security/keys/encrypted.h -eb43a66339a63c40a2a65c035e6e3e57 linux-3.0/security/keys/encrypted.c -ebdaba5503bee67169c28bfa863d77aa linux-3.0/security/keys/compat.c -030a901bfa00c7c921f64c52c8e187df linux-3.0/security/keys/Makefile -c8a5c664ff5690d28ae9ad3c82dac3da linux-3.0/security/integrity/ima/ima_queue.c -5c73357a1a5452f19a3408a7836c5ef2 linux-3.0/security/integrity/ima/ima_policy.c -332973097d744d6da97ad15955f24762 linux-3.0/security/integrity/ima/ima_main.c -9ed87ae4e0f46cb8113479ccd3563cea linux-3.0/security/integrity/ima/ima_init.c -f2490df1d0c1edc7a08bb56680a4c294 linux-3.0/security/integrity/ima/ima_iint.c -5dda419b723c3fb24b458dc62db84f82 linux-3.0/security/integrity/ima/ima_fs.c -c2559381cf7ed63693635dc58cef979b linux-3.0/security/integrity/ima/ima_crypto.c -c68f3f67e9416529a6b51e2ae4abd7df linux-3.0/security/integrity/ima/ima_audit.c -d9bf3f6718864b5a57dbdbdd22df828e linux-3.0/security/integrity/ima/ima_api.c -ced87d22dba178ee172991aab3e599f4 linux-3.0/security/integrity/ima/ima.h -3aa1912cfadf2169c6ce2bfee934ec7e linux-3.0/security/integrity/ima/Makefile -2b5e1df3a341a888258238c840661952 linux-3.0/security/integrity/ima/Kconfig -4c406c20684df4f9e538809308ed3c7e linux-3.0/security/inode.c -a32262195df744e420a27ea8561a4f6c linux-3.0/security/device_cgroup.c -1c8e79c9fd62e28b47f8a73452ffc4c3 linux-3.0/security/commoncap.c -d23df32563810af1230cd9083b2c53ee linux-3.0/security/capability.c -747312f601fa6bb0a90eec02db006dd1 linux-3.0/security/apparmor/sid.c -3b972abc01a772dd769193c3092c1a0a linux-3.0/security/apparmor/resource.c -bc63783f9b07450932cd67be8934be83 linux-3.0/security/apparmor/procattr.c -a7d4a182129dbd980af76490b6698263 linux-3.0/security/apparmor/policy_unpack.c -45ed6a0dd30979228e8f0b76baa7cf5a linux-3.0/security/apparmor/policy.c -f6c987c122cf6769d78157be509ebbac linux-3.0/security/apparmor/path.c -6c15ccace261fa527d9059e77b7790f4 linux-3.0/security/apparmor/match.c -1f32140e79783d21605ee8949baa66f1 linux-3.0/security/apparmor/lsm.c -2dc51e98458293e65ddfeefe3854a051 linux-3.0/security/apparmor/lib.c -1ba39b45ada72338335632ec359ab04d linux-3.0/security/apparmor/ipc.c -a90268c85d05c408f978de2babc79fea linux-3.0/security/apparmor/include/sid.h -bdf8759042498ed13920c905831d698a linux-3.0/security/apparmor/include/resource.h -6a68a5c0e77504c7a00bbb15cbbd20a1 linux-3.0/security/apparmor/include/procattr.h -3ffcb16ef574a0eb46dbd47e5b212907 linux-3.0/security/apparmor/include/policy_unpack.h -540c2fbd81c4067e92c0e6c8630486e5 linux-3.0/security/apparmor/include/policy.h -5e229157532c020a0d0e82580b84a5f0 linux-3.0/security/apparmor/include/path.h -1af7e65d3e0c3b9c25a924ecb42f7e47 linux-3.0/security/apparmor/include/match.h -40ad47a8d5c6226a8638cf36ee220943 linux-3.0/security/apparmor/include/ipc.h -762ebda69a3ef291270a31c5a14a1842 linux-3.0/security/apparmor/include/file.h -90a8e9260c72703d0d604cb7a1b9a830 linux-3.0/security/apparmor/include/domain.h -fb5cbcb7443a70b4b4df083c1e4e7c0a linux-3.0/security/apparmor/include/context.h -523f727844dbc11e2e620b8eb5230494 linux-3.0/security/apparmor/include/capability.h -a6b9081d4dff89ad57f1075ae49db544 linux-3.0/security/apparmor/include/audit.h -9733ac5cff07015a10e0c7e9019452b6 linux-3.0/security/apparmor/include/apparmorfs.h -8827725be00fc7036acec671b06ecb0e linux-3.0/security/apparmor/include/apparmor.h -40130f29aa7a0d80fbfffb95b0348802 linux-3.0/security/apparmor/file.c -f41f0a36782ba2f2c5a4fabd3526ebb0 linux-3.0/security/apparmor/domain.c -82536ea25f5ee84df68ad9586072ce25 linux-3.0/security/apparmor/context.c -5aeace3d16b32d85c05e839cbde22813 linux-3.0/security/apparmor/capability.c -c6466aa71288acaa349eed6a918aa257 linux-3.0/security/apparmor/audit.c -5283b49f86af43d2d42a2886b56acc05 linux-3.0/security/apparmor/apparmorfs.c -8b319a5fa21a1ae3810142ca04d61582 linux-3.0/security/apparmor/Makefile -d2da2d514c5e65502f993370f84b9fb9 linux-3.0/security/apparmor/Kconfig -00c2ededa0fbb43e79c854ef13a71eef linux-3.0/security/apparmor/.gitignore -8e51a3b11753a1ee0939085a33cf57a8 linux-3.0/security/Makefile -a098f3708a314da6210f13a803d0d44d linux-3.0/security/Kconfig -5e54317eb763f2f9ced699a15691071a linux-3.0/scripts/xz_wrap.sh -0a7419178a93de5c1aa000a564363a9c linux-3.0/scripts/ver_linux -7787c27190035c4ad35fa03e5260f6cf linux-3.0/scripts/unifdef.c -679ecfa6569224e4576452e70266b5a3 linux-3.0/scripts/tracing/draw_functrace.py -3197eb0529c9657e27b2bb16946e2598 linux-3.0/scripts/tags.sh -1a0a97f908aabcf4957c5314042fa3a0 linux-3.0/scripts/show_delta -0e3e9b7d30b9af884f79eee5636cac48 linux-3.0/scripts/setlocalversion -3e0975740eec3481da4239017709545c linux-3.0/scripts/selinux/mdp/mdp.c -b1c42884fa5bdbde53d64cff469374fd linux-3.0/scripts/selinux/mdp/dbus_contexts -d5b17207a395d8a544610e7921762bd8 linux-3.0/scripts/selinux/mdp/Makefile -d1c9d4d6c8298009b2a3aeecd684db72 linux-3.0/scripts/selinux/mdp/.gitignore -de03c80328e9a3e875d641e11349ce85 linux-3.0/scripts/selinux/install_policy.sh -1eb1f59c37ac5644e5af0ca3160cc7be linux-3.0/scripts/selinux/genheaders/genheaders.c -257effa6c8370a229f8092c9e14f17af linux-3.0/scripts/selinux/genheaders/Makefile -58dce1f2fbfdc9cc6dd15ee9d2370504 linux-3.0/scripts/selinux/genheaders/.gitignore -ca76bcf8e6a059ec9f29e9d1e9cd57b1 linux-3.0/scripts/selinux/README -42f8ff89f0593769d29050c61459ed05 linux-3.0/scripts/selinux/Makefile -4307e3aa8db753fcef81b69e2814ad33 linux-3.0/scripts/rt-tester/t5-l4-pi-boost-deboost.tst -3acec07fcb4d53a6a76847bb028a1072 linux-3.0/scripts/rt-tester/t5-l4-pi-boost-deboost-setsched.tst -33b4656812264ad1fd765ab88816a1be linux-3.0/scripts/rt-tester/t4-l2-pi-deboost.tst -e73dccd0d51a803b3958f5f55b5370ae linux-3.0/scripts/rt-tester/t3-l2-pi.tst -ef8bdfad61d493578a6adee871c6063c linux-3.0/scripts/rt-tester/t3-l1-pi-steal.tst -5b2afc3d3ce687b6a7cadf11ac4f242e linux-3.0/scripts/rt-tester/t3-l1-pi-signal.tst -22edbe63c0fce6b65b269cc7a08ebc2f linux-3.0/scripts/rt-tester/t3-l1-pi-3rt.tst -9913a4a4c2114fab6dd584acac6d2ac5 linux-3.0/scripts/rt-tester/t3-l1-pi-2rt.tst -da1e9e4bba327e63a8150921fa82273f linux-3.0/scripts/rt-tester/t3-l1-pi-1rt.tst -bfb29784c27ec6a97d2fa2505340ea52 linux-3.0/scripts/rt-tester/t2-l2-2rt-deadlock.tst -ec1e249f643960b6a178d17ceb8fda3d linux-3.0/scripts/rt-tester/t2-l1-signal.tst -1967153946546f63360a3652f7861841 linux-3.0/scripts/rt-tester/t2-l1-pi.tst -9c3c64d31fc3845f2da1e3949647ecb6 linux-3.0/scripts/rt-tester/t2-l1-2rt-sameprio.tst -9711193211b1b501bb84f62be00e13ac linux-3.0/scripts/rt-tester/rt-tester.py -83cb91918bb3d25dfc7b8658b78075d8 linux-3.0/scripts/rt-tester/check-all.sh -bc38e783e678bcade3c62a1a9e2f5e84 linux-3.0/scripts/recordmcount.pl -754207a189d68507c3b12c915932f42e linux-3.0/scripts/recordmcount.h -6517b2e98a3e1cedf27fdd32210f41ec linux-3.0/scripts/recordmcount.c -254ccc549c25c783520e6f99d8c9538e linux-3.0/scripts/profile2linkerlist.pl -7e1995df0f8366e50a96877fe9ba8b88 linux-3.0/scripts/pnmtologo.c -ac14d9409b08c193de88af258b81d5e0 linux-3.0/scripts/patch-kernel -5107fefbe41755a64ec340661d2dae15 linux-3.0/scripts/package/mkspec -1ba2523cabb84cb36a4a0f788253bf18 linux-3.0/scripts/package/buildtar -ab204fb05aa35bdeb77fb27e5f6a03ba linux-3.0/scripts/package/builddeb -d1d25ac03a37ed98027c26c617167165 linux-3.0/scripts/package/Makefile -57f28d1da988ea81391127a4c4c5020e linux-3.0/scripts/namespace.pl -6ba27f228837dd44482ce12ab2094b4d linux-3.0/scripts/module-common.lds -53e36dddb1e5a855e8254c84ee3fb0b4 linux-3.0/scripts/mod/sumversion.c -aacadad6c34964aa7b2a3e82283d8098 linux-3.0/scripts/mod/modpost.h -ce52f55a7538a0e81357ba7eed347ddf linux-3.0/scripts/mod/modpost.c -0ae61355e8ceefd34e417c0a0ea75f14 linux-3.0/scripts/mod/mk_elfconfig.c -810ae2e0807c1353c0d36ee500d287a2 linux-3.0/scripts/mod/file2alias.c -ad1348d1e1397761a9932a84f401c436 linux-3.0/scripts/mod/empty.c -b0af677977e2a0d94a6d934501e5af5e linux-3.0/scripts/mod/Makefile -eb48d1d832e01d829133e2a67fda1a0e linux-3.0/scripts/mod/.gitignore -7ee13cf245d7150105631ec0b283136f linux-3.0/scripts/mkversion -44fcea17a498be27f2d3a88401895c9d linux-3.0/scripts/mkuboot.sh -5a14a5b337499415fb6a82546de97375 linux-3.0/scripts/mksysmap -abc3bc9b9092d2fc338f587e0bed23bf linux-3.0/scripts/mkmakefile -0950be57a8748352ff937486e777da89 linux-3.0/scripts/mkcompile_h -059e2787db647ae4eee9229a4c3de93e linux-3.0/scripts/markup_oops.pl -6b5b4e1610159d42b062badc5add27f5 linux-3.0/scripts/makelst -c3227e84d81e5a83dfdd28e5e6d084a0 linux-3.0/scripts/ksymoops/README -7142e7ace027398141e63cf69805c0d0 linux-3.0/scripts/kernel-doc -ebbc33abe6212be8d7dc5f9622ed0297 linux-3.0/scripts/kconfig/zconf.y -fcd4c65626dfcb428498c12c87e66db2 linux-3.0/scripts/kconfig/zconf.tab.c_shipped -cdf12b23837f0fa8233ef602bcae478d linux-3.0/scripts/kconfig/zconf.l -0130ca987e4d545deacaafe64cb884cd linux-3.0/scripts/kconfig/zconf.hash.c_shipped -daaf15a7714d09af143d65fa23efc108 linux-3.0/scripts/kconfig/zconf.gperf -42d5e998531842ce3d936f8d85576cf3 linux-3.0/scripts/kconfig/util.c -e71e43b8136c1d3b172f7dc10ae7bbaa linux-3.0/scripts/kconfig/symbol.c -cc109a0ebf381e1f7d405f716bd04f53 linux-3.0/scripts/kconfig/streamline_config.pl -300137aa291fcf4dd5c41c9c4a5001d2 linux-3.0/scripts/kconfig/qconf.h -3480cd4f85ab939c2de5881b281f4c62 linux-3.0/scripts/kconfig/qconf.cc -d060fab962445335afb13cf4a4a8a2cf linux-3.0/scripts/kconfig/nconf.h -498466020e1bb267d14cd01400dbd76d linux-3.0/scripts/kconfig/nconf.gui.c -9dc5b49e964ae1369d7b0d813855d350 linux-3.0/scripts/kconfig/nconf.c -e30becda4a04bd20262c9f4aeeefcfef linux-3.0/scripts/kconfig/menu.c -6b63ebecc64fcfc9adf0018e8959f4e8 linux-3.0/scripts/kconfig/mconf.c -9769589490ac420463d64a8b2221ab25 linux-3.0/scripts/kconfig/lxdialog/yesno.c -72a2f3dbdf1d9fa96ff61da28269b52f linux-3.0/scripts/kconfig/lxdialog/util.c -e74891ce550d233ae0da469c1cfed13b linux-3.0/scripts/kconfig/lxdialog/textbox.c -d3e9d71d6cfc6b8c1219678ea146e904 linux-3.0/scripts/kconfig/lxdialog/menubox.c -836070cf260aa9285ff69828124b37c7 linux-3.0/scripts/kconfig/lxdialog/inputbox.c -6ab37e536b723f6cbe07fca073daef03 linux-3.0/scripts/kconfig/lxdialog/dialog.h -4b6cdf8fca5338adc5a995bb5f070d0e linux-3.0/scripts/kconfig/lxdialog/checklist.c -831f9d2b82fff2a0ac6cee4ca0ef64f2 linux-3.0/scripts/kconfig/lxdialog/check-lxdialog.sh -2e0bfdc0eb78ca744114b42489f077d3 linux-3.0/scripts/kconfig/lxdialog/BIG.FAT.WARNING -f1b186abc7a482548c4e0cdd9d362588 linux-3.0/scripts/kconfig/lxdialog/.gitignore -c0d892c01bbd6980fda003d7803f937e linux-3.0/scripts/kconfig/lkc_proto.h -309f1ed1963be925cb3927a053e1386a linux-3.0/scripts/kconfig/lkc.h -cc446d204726d186124db7260560c7bf linux-3.0/scripts/kconfig/lex.zconf.c_shipped -f3c2236bbbed2c8a11a208614f9c4f2d linux-3.0/scripts/kconfig/kxgettext.c -9376b55503a3d5f212697b620df6c178 linux-3.0/scripts/kconfig/kconfig_load.c -41016141bf664d349437c25220c2fc94 linux-3.0/scripts/kconfig/images.c -0aba4498cae58405f721cf4cb8d172d8 linux-3.0/scripts/kconfig/gconf.glade -2aebeff91ff5303ced87cc29a5761781 linux-3.0/scripts/kconfig/gconf.c -5a2fc974e7746ebe9c0a89f869a79173 linux-3.0/scripts/kconfig/expr.h -1494f49397f6d27b07923b66097c2afc linux-3.0/scripts/kconfig/expr.c -199db8ee82da9f96b97803571de59f84 linux-3.0/scripts/kconfig/confdata.c -cd6460481b80a4ae0b72ebfd70ca88a1 linux-3.0/scripts/kconfig/conf.c -18c087cafc6fc643387c4103d4e657f4 linux-3.0/scripts/kconfig/check.sh -7fe8482e843fa5261d5315e4a88f7924 linux-3.0/scripts/kconfig/POTFILES.in -60733d7e27a91baa01afc48d7408d962 linux-3.0/scripts/kconfig/Makefile -8e1a95257917f9fdb64d97bc31707033 linux-3.0/scripts/kconfig/.gitignore -46817f906d048960cfa50985320a5be3 linux-3.0/scripts/kallsyms.c -c266c0148dae15d494577cfdf4f70f07 linux-3.0/scripts/headers_install.pl -4ae251fa6915cedc794b9de33ecd9ef8 linux-3.0/scripts/headers_check.pl -6d883b7bd0aeffe48793d5dc40b4805f linux-3.0/scripts/headers.sh -8af0c972659d0046fe09d4c47525fbf6 linux-3.0/scripts/headerdep.pl -e1244c47a0856980d9ed18d234a881d2 linux-3.0/scripts/gfp-translate -3a7fb481c077cdfa03592115ba2bf860 linux-3.0/scripts/get_maintainer.pl -11bc7512ee10863e9fb5af6b3cd38ca3 linux-3.0/scripts/genksyms/parse.y -6aa35ba3ecd459af95a112deb252c118 linux-3.0/scripts/genksyms/parse.h_shipped -5062a66ed547df2463a77484b87df586 linux-3.0/scripts/genksyms/parse.c_shipped -9b587090fd813577d3fc353a11815ece linux-3.0/scripts/genksyms/lex.l -1b26c01f37f693dcfcc704bd42baf393 linux-3.0/scripts/genksyms/lex.c_shipped -c9bdea696a3a06ee9147384190694511 linux-3.0/scripts/genksyms/keywords.gperf -2a5e4c91a04bfcef81e5de1e48e01763 linux-3.0/scripts/genksyms/keywords.c_shipped -50c9d8233c89aeb61cfd66479438babc linux-3.0/scripts/genksyms/genksyms.h -042f688f8d8b0cfaf741989658ec9acf linux-3.0/scripts/genksyms/genksyms.c -dfe6a04a69f6e3c4fd9fe0026b2cc6ab linux-3.0/scripts/genksyms/Makefile -3b947d62946715f9334b14ec258be1a9 linux-3.0/scripts/genksyms/.gitignore -fc6b43d61c79098ed8333df66aee8f2b linux-3.0/scripts/gen_initramfs_list.sh -d9885a170b8026a4dbfbcac7042604df linux-3.0/scripts/gcc-x86_64-has-stack-protector.sh -c41c70d0a390e67fe978160ed83b68f4 linux-3.0/scripts/gcc-x86_32-has-stack-protector.sh -ae76a0d493652680dbe82b305017db8b linux-3.0/scripts/gcc-version.sh -3aaa2a214f5a13f046a9a85ec0895347 linux-3.0/scripts/gcc-goto.sh -738ba6181d0709d68892d8b57b08f395 linux-3.0/scripts/extract-ikconfig -c39ddfa12e5c2f65f1b3e9d431f3ea72 linux-3.0/scripts/export_report.pl -9879faeeaf6d5289a5112d9f67380f5d linux-3.0/scripts/dtc/version_gen.h -cf47ff95333b89268f24ba426c253415 linux-3.0/scripts/dtc/util.h -d462364096944c031ab530ee36cdcb48 linux-3.0/scripts/dtc/util.c -c19b242ec4976524b704dc9ce40452d2 linux-3.0/scripts/dtc/treesource.c -ca032c5c3ed5c78b012cf97fd10945ff linux-3.0/scripts/dtc/srcpos.h -e34ba8ded6b6171d38277dfcc3518c72 linux-3.0/scripts/dtc/srcpos.c -d01912acf622addab8cf19ba6642032d linux-3.0/scripts/dtc/livetree.c -3933a0bba8fb52065317d551d8330f41 linux-3.0/scripts/dtc/libfdt/libfdt_internal.h -a93109ebc49d8118affda77d57ede155 linux-3.0/scripts/dtc/libfdt/libfdt_env.h -c4ef288354ca8d3e7ab405477eef5680 linux-3.0/scripts/dtc/libfdt/libfdt.h -f040cec9298e25a50badff3a5e30a45b linux-3.0/scripts/dtc/libfdt/fdt_wip.c -875caa55e878310c387eab89ae7bba30 linux-3.0/scripts/dtc/libfdt/fdt_sw.c -3e5f700a69b700020055d8ba2899d769 linux-3.0/scripts/dtc/libfdt/fdt_strerror.c -b68f3b9325d54a06cb52c487fb666f7d linux-3.0/scripts/dtc/libfdt/fdt_rw.c -2b860e5a14b7caf084e4300a300a6f0e linux-3.0/scripts/dtc/libfdt/fdt_ro.c -10a715100b804f8279198c9eb36dc73a linux-3.0/scripts/dtc/libfdt/fdt.h -c575f3407e38320ac9a2823f759202ce linux-3.0/scripts/dtc/libfdt/fdt.c -4b46cd1e2aa554dad70fd9676d2e6ad7 linux-3.0/scripts/dtc/libfdt/Makefile.libfdt -b43894b5917feaa990b475e5085de2a3 linux-3.0/scripts/dtc/fstree.c -044eba0fd7532b742d1637f625c75426 linux-3.0/scripts/dtc/flattree.c -b78ef2e9f3bd322f6c9ba149c7913bc1 linux-3.0/scripts/dtc/dtc.h -261dc90bb97b74b60cc67dd8d0ff5084 linux-3.0/scripts/dtc/dtc.c -9bfaf5a32b441ade7009c8acc18e8c88 linux-3.0/scripts/dtc/dtc-parser.y -fe792f82cb925baa64905459a541c0cd linux-3.0/scripts/dtc/dtc-parser.tab.h_shipped -5bfc7e25dd34cc71e527133017a040b3 linux-3.0/scripts/dtc/dtc-parser.tab.c_shipped -3af764e61fae92411441d31c6f475420 linux-3.0/scripts/dtc/dtc-lexer.lex.c_shipped -3ff20957f59c9b43d9100ddcb96ff42e linux-3.0/scripts/dtc/dtc-lexer.l -14de9d2775c52e2435bdba4c1145f0ca linux-3.0/scripts/dtc/data.c -9cb3a33709eb7a4e50f309bbabe8dfad linux-3.0/scripts/dtc/checks.c -01d559568572de6237689f56559f7209 linux-3.0/scripts/dtc/Makefile.dtc -438de8eecb232f83d9f7cfa549df31d7 linux-3.0/scripts/dtc/Makefile -dcd77f2cf67cd100836bd291df68ac04 linux-3.0/scripts/dtc/.gitignore -eaa3219675031ce5ee5a8de4b52c8fb2 linux-3.0/scripts/docproc.c -f267dbbc34ad47e02f1fc8ebe6b74e3a linux-3.0/scripts/diffconfig -e0f91791a6b4717efa5f5fd9e9969dd3 linux-3.0/scripts/depmod.sh -d971195e88f57f8019c1416cb204ff35 linux-3.0/scripts/decodecode -86c8c555a151b186db23959d1a4b5032 linux-3.0/scripts/conmakehash.c -f4331b2b2fa6e60922b826a88ce922b8 linux-3.0/scripts/config -3d18e7dcd40dc68155d46e0f34d94a16 linux-3.0/scripts/coccinelle/tests/doubletest.cocci -d7d0bf94475275deaea5e3cd1daef3c4 linux-3.0/scripts/coccinelle/tests/doublebitand.cocci -d71f07650abfbb5eecf54c2f3ce1a3f3 linux-3.0/scripts/coccinelle/null/kmerr.cocci -f533b3acebd12d26c56023a81f0c4fd0 linux-3.0/scripts/coccinelle/null/eno.cocci -8c4e05957a4a315c964ae89d103def29 linux-3.0/scripts/coccinelle/null/deref_null.cocci -f82172388d23c4136d56f6ec16240f28 linux-3.0/scripts/coccinelle/misc/ifcol.cocci -19ae4640a51a494d8fa9ca4c2356472f linux-3.0/scripts/coccinelle/misc/doubleinit.cocci -345c3d82db8dea7e7285140f2cf07cb5 linux-3.0/scripts/coccinelle/locks/mini_lock.cocci -2696c3e655c80771c31cf1c0479f4b4c linux-3.0/scripts/coccinelle/locks/flags.cocci -22352d7b203204972299714911848137 linux-3.0/scripts/coccinelle/locks/double_lock.cocci -8d51655003396fa012b1b7232b60a1e3 linux-3.0/scripts/coccinelle/locks/call_kern.cocci -9d0cd350d8a2c3f6e415cde950ec0b5b linux-3.0/scripts/coccinelle/iterators/list_entry_update.cocci -f89ec936fa7765ab726478a496a9c0e5 linux-3.0/scripts/coccinelle/iterators/itnull.cocci -f24d224273f7fabdd80afab9491c890c linux-3.0/scripts/coccinelle/iterators/fen.cocci -e6d2f77efb448c2c809093a0f1ebbc10 linux-3.0/scripts/coccinelle/free/kfree.cocci -2eca061aff8d86361cbe864fe08331fb linux-3.0/scripts/coccinelle/api/resource_size.cocci -f6ca6425a7da734873d03c9188e6eb5a linux-3.0/scripts/coccinelle/api/memdup_user.cocci -0a91d2695b5ed56e0fd3f00e573a661b linux-3.0/scripts/coccinelle/api/memdup.cocci -f34e4e86c7276d0c6fa59cbbe5d08894 linux-3.0/scripts/coccinelle/api/kstrdup.cocci -84b43b07478ea8861aa9260ad4b79006 linux-3.0/scripts/coccinelle/api/err_cast.cocci -81baab136d269509ff6003303192d592 linux-3.0/scripts/coccinelle/api/alloc/kzalloc-simple.cocci -547d177c1ad98d57cd7afb5a669eac9b linux-3.0/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci -bb267b9f727b42291477959bf58a4712 linux-3.0/scripts/coccicheck -84b5a9ec6b8b236a95db3437877407f4 linux-3.0/scripts/cleanpatch -bc5d1612e4f4a6f85427ecf28cc7a660 linux-3.0/scripts/cleanfile -18512fa27f7cc97063870d49c8344d97 linux-3.0/scripts/checkversion.pl -00bd26b2ab8eb0a296a2325cf0095fe6 linux-3.0/scripts/checksyscalls.sh -923de84fca39efc8ed732fc828459152 linux-3.0/scripts/checkstack.pl -4c5931375e2097d6d507b964094ce420 linux-3.0/scripts/checkpatch.pl -15a7bb14c253201c78d16cd37d4df3ec linux-3.0/scripts/checkkconfigsymbols.sh -3f019114c4a19600c20fb19da0247241 linux-3.0/scripts/checkincludes.pl -7349ce4d06c82e13df761fa7d0dde7fc linux-3.0/scripts/bootgraph.pl -32c4bad320050f7eff9f6f8629476ff8 linux-3.0/scripts/bloat-o-meter -b8b087b2b06074e2985c768e8bdca357 linux-3.0/scripts/bin2c.c -f346cd3df137340756e3b9e2bf1f89f8 linux-3.0/scripts/basic/fixdep.c -de48aab12a6aea5b4f3a1f75e6bb77ef linux-3.0/scripts/basic/Makefile -f2a839f3afb435ccdaa996d9c403b6f8 linux-3.0/scripts/basic/.gitignore -900552a1ad3712dd2458e08a8128e460 linux-3.0/scripts/Makefile.modpost -ebe485c5f8a3aa0cb203d0e8cb03ed2c linux-3.0/scripts/Makefile.modinst -e98c371abf763509ec7ca49f5b613ce1 linux-3.0/scripts/Makefile.modbuiltin -00dd761b30ad22786424246fc0cb7990 linux-3.0/scripts/Makefile.lib -9da9e47d03142f731f0f651fad4fb28a linux-3.0/scripts/Makefile.host -6409c7aafc6bac7a0805d0a718edc8ef linux-3.0/scripts/Makefile.help -fe8bbf25fedbc1cf475883c6f507426b linux-3.0/scripts/Makefile.headersinst -aee47710527399dc27399b1aa2f07e7b linux-3.0/scripts/Makefile.fwinst -f3da726faef2a80235617a5342e7080d linux-3.0/scripts/Makefile.clean -6801891e8f731b5dcf6da22ec0ded249 linux-3.0/scripts/Makefile.build -89514cbc0f017ab03c8d38114cba200e linux-3.0/scripts/Makefile.asm-generic -e01fe1347b0cea264040157fe6f5fa30 linux-3.0/scripts/Makefile -11a836a5aacc90586554c3718d53f2a1 linux-3.0/scripts/Lindent -19a2e107f7a055544486864136f6e619 linux-3.0/scripts/Kbuild.include -a1d841db9ba94257dcbe30305bea78e1 linux-3.0/scripts/.gitignore -b01e8660c987a21236cace5f6cfb6473 linux-3.0/samples/tracepoints/tracepoint-sample.c -884e37b0ce52bd89d63cfd8ed21aad30 linux-3.0/samples/tracepoints/tracepoint-probe-sample2.c -7223813bd0db108b5b67dbe9de7e3a66 linux-3.0/samples/tracepoints/tracepoint-probe-sample.c -1becc28f9edb35ff72330e4222ee14be linux-3.0/samples/tracepoints/tp-samples-trace.h -4eee7aa4a00b85313be9f4b4d27eb48f linux-3.0/samples/tracepoints/Makefile -8fb862c115a01ad0fe143e1a317d9198 linux-3.0/samples/trace_events/trace-events-sample.h -3f897f49ad897bb51ad38c73b2481948 linux-3.0/samples/trace_events/trace-events-sample.c -089e90f635b9c370369f8b7e4f126cc0 linux-3.0/samples/trace_events/Makefile -b3c4e4513f61c6f90cce98183f5ea8a2 linux-3.0/samples/kprobes/kretprobe_example.c -510e09ef9e497135389d4fb80fcc18b7 linux-3.0/samples/kprobes/kprobe_example.c -e8a402e9c1acea57745de5c49d3e83cd linux-3.0/samples/kprobes/jprobe_example.c -ab645a4232624cf304b31611c4d31639 linux-3.0/samples/kprobes/Makefile -9c421ac2bec461ba741e62ef041e8cea linux-3.0/samples/kobject/kset-example.c -8c9092c5a74814b4710c925dc1a7e171 linux-3.0/samples/kobject/kobject-example.c -b3717824e7a8fd02b04a75381f1da834 linux-3.0/samples/kobject/Makefile -b4ce24244a3ff0f8abd0488c3e056224 linux-3.0/samples/kfifo/record-example.c -f505d486c5eea0ea0c6d8a02bba30c33 linux-3.0/samples/kfifo/inttype-example.c -6cdccb8558b07a17d4aa85ec9c499d47 linux-3.0/samples/kfifo/dma-example.c -4edee9ee18b0134d216a3f9a7a882afa linux-3.0/samples/kfifo/bytestream-example.c -859b65aca7f9983e1e33af300152a8b2 linux-3.0/samples/kfifo/Makefile -f116fcc3a5def736272258fa4eb2eeb6 linux-3.0/samples/kdb/kdb_hello.c -60846f0072beab785af00d2290bbf33d linux-3.0/samples/kdb/Makefile -057d385592649770c916122e123bc424 linux-3.0/samples/hw_breakpoint/data_breakpoint.c -4d204bd8be238cfb19b3f8459d84c45e linux-3.0/samples/hw_breakpoint/Makefile -d14dff562734d8572e80dc9457039d84 linux-3.0/samples/hidraw/hid-example.c -07bdeef9398d9eb33b2faec05fbc838e linux-3.0/samples/hidraw/Makefile -2f5c85ec9e27a4fda1d6b71b9fb48934 linux-3.0/samples/Makefile -12b824079f2192e9e9c22a3378d0becd linux-3.0/samples/Kconfig -03bf613a7215f5943167cdea8936a6f9 linux-3.0/net/xfrm/xfrm_user.c -d41ba97854547ac39ef6bb5355f524df linux-3.0/net/xfrm/xfrm_sysctl.c -b5128cfc213432b46db85f1975c277b4 linux-3.0/net/xfrm/xfrm_state.c -ba9d5d2cc39b5f1845a3122628bf2e36 linux-3.0/net/xfrm/xfrm_replay.c -794194450c39ad8c25d7233ad282d54f linux-3.0/net/xfrm/xfrm_proc.c -4c23b5d8eb838b4227c9040422d6e900 linux-3.0/net/xfrm/xfrm_policy.c -0f575f48ea849675981b0ab329cae467 linux-3.0/net/xfrm/xfrm_output.c -adac4fe90f9192f53d60260e414de075 linux-3.0/net/xfrm/xfrm_ipcomp.c -077a18391489f2f9a783b76f2b2d3a60 linux-3.0/net/xfrm/xfrm_input.c -7c3ba7588b8ee76f53811412a0fe8cc9 linux-3.0/net/xfrm/xfrm_hash.h -44646362f20b4c0a58c57e2fb4309c85 linux-3.0/net/xfrm/xfrm_hash.c -1109ee788b770f51fb90596813c9a272 linux-3.0/net/xfrm/xfrm_algo.c -ece77bcd2cb5f00e2cbcd0310c5bc873 linux-3.0/net/xfrm/Makefile -7c3cf358e6837827e8ded51f4abe8237 linux-3.0/net/xfrm/Kconfig -fe36e04bbc8f74bb7e1517237c74db8d linux-3.0/net/x25/x25_timer.c -14b4f606a4c8e865bdb758b71579e03c linux-3.0/net/x25/x25_subr.c -86770af653d0c6a466ea83eedbfdd866 linux-3.0/net/x25/x25_route.c -4b2e6304be5b60a388ff24cdf115830f linux-3.0/net/x25/x25_proc.c -163e652e15ce469d9961d0fe4dfe081d linux-3.0/net/x25/x25_out.c -cb5bd0219423752f9c3c765b50eb083a linux-3.0/net/x25/x25_link.c -d94446fbdc5fc0a516cc4879ca0e4111 linux-3.0/net/x25/x25_in.c -425f37013da9c28b68dcf2aaf7c9d163 linux-3.0/net/x25/x25_forward.c -6ea4bebf84386dff2ef598b1ce119057 linux-3.0/net/x25/x25_facilities.c -b5e6c6278f9b31a2178b34f8d64a4b9a linux-3.0/net/x25/x25_dev.c -f8fb15fa556113a7e70954f643dccaaa linux-3.0/net/x25/sysctl_net_x25.c -9f71ae68c11b41688776da45bd32db75 linux-3.0/net/x25/af_x25.c -46b986134d9168d3300a029b80baceb0 linux-3.0/net/x25/Makefile -5eb57c92e639ffb0285d3af126dcdf1f linux-3.0/net/x25/Kconfig -342cadfbe2ef395c443443db98fbde9e linux-3.0/net/wireless/wext-spy.c -71149f79d21b1615bffcfb7d171c7108 linux-3.0/net/wireless/wext-sme.c -bf198172f63bd4fdf37416a4f2d06b00 linux-3.0/net/wireless/wext-proc.c -ccb665a9d042c965c59b87fde705213b linux-3.0/net/wireless/wext-priv.c -5a15b2402fdb249b8bf9467078796952 linux-3.0/net/wireless/wext-core.c -f160bcff8481e58cdbbe748dfd54232e linux-3.0/net/wireless/wext-compat.h -3f0959a88537c24c6ed53cd9f081c956 linux-3.0/net/wireless/wext-compat.c -1f04e3b5d4e67fe54a6ba3753172ec90 linux-3.0/net/wireless/util.c -4dee94a93888e6157db00f3be90266cd linux-3.0/net/wireless/sysfs.h -3a60893fe17aba9d45f9fd0e36647fb3 linux-3.0/net/wireless/sysfs.c -78e668ed64f1bb07f0cf1e045e0b0bcd linux-3.0/net/wireless/sme.c -6313338692960e65a662913ad84f5fc4 linux-3.0/net/wireless/scan.c -196fb136a9fd8b6018706055f685cbe7 linux-3.0/net/wireless/regdb.h -098fe2435c2cc43f1cbeb55eed23eef0 linux-3.0/net/wireless/reg.h -8f0f134c673f6994ce337d6691aa4c01 linux-3.0/net/wireless/reg.c -086b784995d9a8aaa1325a6fe11a3e85 linux-3.0/net/wireless/radiotap.c -10c0edd87476aecea171cfc1c6dd10fb linux-3.0/net/wireless/nl80211.h -899b2bad4f9b89ba06f83330750e64b3 linux-3.0/net/wireless/nl80211.c -6e2a6d2bc3cbc1fdf835da58648e5172 linux-3.0/net/wireless/mlme.c -a88bc6ee808e1df3ce8e42cdd4c251d7 linux-3.0/net/wireless/mesh.c -da8f80ee6bd3077bc659bfaaf60c0cad linux-3.0/net/wireless/lib80211_crypt_wep.c -8a28febf95ddea1d8f3eea9295406607 linux-3.0/net/wireless/lib80211_crypt_tkip.c -35e46120b7e0b64b6309f682a26794a3 linux-3.0/net/wireless/lib80211_crypt_ccmp.c -01736ec77a6d376a433789520ac1f0d5 linux-3.0/net/wireless/lib80211.c -bf18ea1b66a93eae8a672980fbef8949 linux-3.0/net/wireless/ibss.c -e5ab47bc065f8196a5765e3b330df828 linux-3.0/net/wireless/genregdb.awk -94eacc1fbeeeb5c7e5617ce95ccde605 linux-3.0/net/wireless/ethtool.h -c667068b96ba1fdd035f0e6664068718 linux-3.0/net/wireless/ethtool.c -68e3d45c727d1ff7650ddc8b0a6b0872 linux-3.0/net/wireless/debugfs.h -55df444ba6bc23e7a03d68b74ad57996 linux-3.0/net/wireless/debugfs.c -079eab79931c561e95f933b1a68bf53e linux-3.0/net/wireless/db.txt -78c2691bb780a287aada617ff51c3bdc linux-3.0/net/wireless/core.h -0a0d8446238b92912e64161080d11dcd linux-3.0/net/wireless/core.c -aac1fe8ef4dd1b67995b357d6a1274d1 linux-3.0/net/wireless/chan.c -cc3fb9c0ad5d02ff5cb4eba80f9df8cc linux-3.0/net/wireless/Makefile -00369047e088a07f9465560153e30954 linux-3.0/net/wireless/Kconfig -8bfccc1f47b557bb89efd8d57498fad8 linux-3.0/net/wireless/.gitignore -9dcb49535d5823d3a520be18a6483115 linux-3.0/net/wimax/wimax-internal.h -04a5bae10dda7e5ae0f69d25cae99a2a linux-3.0/net/wimax/stack.c -d1e50dd3d3b680527775452968fb398a linux-3.0/net/wimax/op-state-get.c -92c837342c5d830441663b9062d848b1 linux-3.0/net/wimax/op-rfkill.c -ea2d1cabe4ddc6ee99ede38402d3a391 linux-3.0/net/wimax/op-reset.c -d3abfb4b9c8e531a034ee24b4df3645e linux-3.0/net/wimax/op-msg.c -f6d59e4cd1f8e2ad3a2dac5d1f7ada44 linux-3.0/net/wimax/id-table.c -31e94c56af32fffaf63e3d51958d0432 linux-3.0/net/wimax/debugfs.c -9638f7378f3fa9540426fcea0b7b1f28 linux-3.0/net/wimax/debug-levels.h -df90012fda145960057ea690dbcabdcb linux-3.0/net/wimax/Makefile -600868e73bd15fa205da6cdde9ee6a1b linux-3.0/net/wimax/Kconfig -e906537f2b66f6cbfd1c85818e45fcad linux-3.0/net/wanrouter/wanproc.c -4a9f0de62e82f8453907c7c24beb9bb6 linux-3.0/net/wanrouter/wanmain.c -48096b8ebd1f9bf4b25a87bc47bd60f5 linux-3.0/net/wanrouter/patchlevel -529238ff7f127c36044001c7b3256a3c linux-3.0/net/wanrouter/Makefile -5f73117caa7c611c54c633b4b63928d0 linux-3.0/net/wanrouter/Kconfig -06741144150ce5b20744b5fe0649db3d linux-3.0/net/unix/sysctl_net_unix.c -b1fe38ef6e69e6eea3c175a8cda2afae linux-3.0/net/unix/garbage.c -d31a619da746032e41c8c60ff737e5da linux-3.0/net/unix/af_unix.c -ba0e7c6ec15e50307f3ae4ab18f8a1f2 linux-3.0/net/unix/Makefile -3ede9ec6efbb6765f5a124e7c2f1111e linux-3.0/net/unix/Kconfig -853fa4128643bf6749a1bb4336c58e89 linux-3.0/net/tipc/subscr.h -919488483d5125481d2855b54b85d766 linux-3.0/net/tipc/subscr.c -74513746937bd2e4ce6c485d7997674b linux-3.0/net/tipc/socket.c -15589a8bee9926f56b4d5c6147e696c2 linux-3.0/net/tipc/ref.h -c644e00714aa69c24cb0380f8eac7d69 linux-3.0/net/tipc/ref.c -198ca2f1db56cc8e40b5519b9291c034 linux-3.0/net/tipc/port.h -821c1c020c8fdc5afea6395345ba26d7 linux-3.0/net/tipc/port.c -ae2c9ac9782bf10aaf84547993be5c7b linux-3.0/net/tipc/node_subscr.h -6694afece31e05846dc37ba7e740a1ec linux-3.0/net/tipc/node_subscr.c -a9d22d64a132094b3e77e48afdc322d4 linux-3.0/net/tipc/node.h -59606c459d36c9e12826b5fc04422735 linux-3.0/net/tipc/node.c -d82a98219dae3805fc039c5ef7bc5570 linux-3.0/net/tipc/netlink.c -61d5831749d2e016ec5691dff19fbe15 linux-3.0/net/tipc/net.h -48e589645a05f7b3f3dee1ee1fa39916 linux-3.0/net/tipc/net.c -1d40e7bd1248a2f25e24cba89fed3d4f linux-3.0/net/tipc/name_table.h -8073f69528a63dd2de3d3cb72cd5a12b linux-3.0/net/tipc/name_table.c -11ab19ea2ae5c0b50ccc28e3bbd82ca3 linux-3.0/net/tipc/name_distr.h -3b931ec0c131a65a93bca71c66403881 linux-3.0/net/tipc/name_distr.c -704a84c12e55eae1b91d3d8b4e4a91f3 linux-3.0/net/tipc/msg.h -70de1d008aac58315e00421ee88a144f linux-3.0/net/tipc/msg.c -7b07a63dfd8af745469f1c9646af0177 linux-3.0/net/tipc/log.h -6d6c845ec5d64a5e83d1f3d6d7832d1f linux-3.0/net/tipc/log.c -faa0baef495b3a64c1afe9909f9ee7d9 linux-3.0/net/tipc/link.h -5166a4298404485f46077fc3a8e6854a linux-3.0/net/tipc/link.c -0df0505239981670edb328b6b942d890 linux-3.0/net/tipc/handler.c -b4d0c183e04d1bff00ab352794dbcaa3 linux-3.0/net/tipc/eth_media.c -07c8b6dcfc7b56635766c7247a3fbf3e linux-3.0/net/tipc/discover.h -45a13c675c755b7f99f68ae74f96921b linux-3.0/net/tipc/discover.c -5c712716a624bf6c42920739ee457896 linux-3.0/net/tipc/core.h -e60e9e659046fb971025c3c4f62ae501 linux-3.0/net/tipc/core.c -e54361ac6e8ca99adadc7e463342660b linux-3.0/net/tipc/config.h -4e5df3965e749d55903b67deac181607 linux-3.0/net/tipc/config.c -31304e792ceaee480c9e3144fc0777bf linux-3.0/net/tipc/bearer.h -2ce3feeca7e9db76703ace3c861c9f50 linux-3.0/net/tipc/bearer.c -204c2ef69be78a1a4d631314e9787e87 linux-3.0/net/tipc/bcast.h -c56f6b9d54d50bed92c5550cd1895c69 linux-3.0/net/tipc/bcast.c -f029d8132471d2dfe90b0091b09ae87c linux-3.0/net/tipc/addr.h -21535b7af59d41e99410dbc39ab2c09b linux-3.0/net/tipc/addr.c -234b3a21649beb8810dfe1ef9e581134 linux-3.0/net/tipc/Makefile -e978a64c9d031e8036c87e5b651fecd5 linux-3.0/net/tipc/Kconfig -088f49e5f5b20255aeb0292e5e6ea179 linux-3.0/net/sysctl_net.c -d5df3ab2b4f974e1338827bb20009cde linux-3.0/net/sunrpc/xprtsock.c -35ca8a3e375e4855ba1682f49a980e8e linux-3.0/net/sunrpc/xprtrdma/xprt_rdma.h -4423b8d37eb186b4cdc9b4348e3bed1a linux-3.0/net/sunrpc/xprtrdma/verbs.c -9bdbb4022b1061ec43d28ff97f8e4b39 linux-3.0/net/sunrpc/xprtrdma/transport.c -b915cada1b2482cb6e5a97e88e7aeaf8 linux-3.0/net/sunrpc/xprtrdma/svc_rdma_transport.c -41082b4a12c4f1f1a7f960940288a11a linux-3.0/net/sunrpc/xprtrdma/svc_rdma_sendto.c -45612f2aeef89562b1ea64c0df2ef351 linux-3.0/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c -bd7f140a2294e85d5f4e112145736e86 linux-3.0/net/sunrpc/xprtrdma/svc_rdma_marshal.c -b6d9eb73ab652df21b7c5b56b6e6c78f linux-3.0/net/sunrpc/xprtrdma/svc_rdma.c -19f85de9715d2808e7b24286337e4fb4 linux-3.0/net/sunrpc/xprtrdma/rpc_rdma.c -32fa05fedd13758192204d0d80613fac linux-3.0/net/sunrpc/xprtrdma/Makefile -3dfe23870a230474cbd99b09ca51c167 linux-3.0/net/sunrpc/xprt.c -c7c39dce88ea81c0f3a70026a3168c2a linux-3.0/net/sunrpc/xdr.c -84f31bbfb40c76f39223e801cda02acf linux-3.0/net/sunrpc/timer.c -5b29d145ad7b74436c57244fa8b00b44 linux-3.0/net/sunrpc/sysctl.c -a31603b319d9683f69d6971a87a64566 linux-3.0/net/sunrpc/svcsock.c -b3ffb4c2fc78331924f1889da9cd045d linux-3.0/net/sunrpc/svcauth_unix.c -35397457dd1bfa9cb83d0e56722d83e5 linux-3.0/net/sunrpc/svcauth.c -8327633a092249051ad351e00a043080 linux-3.0/net/sunrpc/svc_xprt.c -801c254a5596d6bcc253d8b2b7993d5c linux-3.0/net/sunrpc/svc.c -4070449f834ae1b07311472738bff958 linux-3.0/net/sunrpc/sunrpc_syms.c -d6aff2e4ad52e35823b55f02b4fa1580 linux-3.0/net/sunrpc/sunrpc.h -7b8550a03545be3a0de1880234cea1b7 linux-3.0/net/sunrpc/stats.c -0970cb58987b35c4c03067f5a5c8a71f linux-3.0/net/sunrpc/socklib.c -b96b53b0451e36c09f8b50cfd17721ee linux-3.0/net/sunrpc/sched.c -8cd8b0f49a8c439fb96e48740f3dc3ab linux-3.0/net/sunrpc/rpcb_clnt.c -14492e9be744dfeeb9f9a2d2f90ce68f linux-3.0/net/sunrpc/rpc_pipe.c -725283544c874348e24baf599918934b linux-3.0/net/sunrpc/netns.h -515b29483e67f1170ee13cc4ee3696c8 linux-3.0/net/sunrpc/clnt.c -22bbeea8e58effa4fd5977b445cff970 linux-3.0/net/sunrpc/cache.c -69122f7751de83f15243357139a0343f linux-3.0/net/sunrpc/bc_svc.c -e6f0cc78e09e6be2a333a67d6476b83e linux-3.0/net/sunrpc/backchannel_rqst.c -119b9dda7b1e56abb290b82c0489f468 linux-3.0/net/sunrpc/auth_unix.c -cf64f76e445c57c2efb9255ee3626eb9 linux-3.0/net/sunrpc/auth_null.c -bd0a53119e23ea6b5e9a4a45062f82c8 linux-3.0/net/sunrpc/auth_gss/svcauth_gss.c -d3e598003fd36ef4c2d9332243bec33c linux-3.0/net/sunrpc/auth_gss/gss_mech_switch.c -59f06efc4acf86403246e47f979b004c linux-3.0/net/sunrpc/auth_gss/gss_krb5_wrap.c -23f6df04660b9fa26230297e80d13816 linux-3.0/net/sunrpc/auth_gss/gss_krb5_unseal.c -ffa497a7606c7c4081c6578b04d27db5 linux-3.0/net/sunrpc/auth_gss/gss_krb5_seqnum.c -90dd4f76d67187cc390bfab710238670 linux-3.0/net/sunrpc/auth_gss/gss_krb5_seal.c -2b443c7d6b1078ca00e1ac554dffdbef linux-3.0/net/sunrpc/auth_gss/gss_krb5_mech.c -41537591ad8ef563d83018743dcc1340 linux-3.0/net/sunrpc/auth_gss/gss_krb5_keys.c -23cae5fa8f15ca677079136da44343e9 linux-3.0/net/sunrpc/auth_gss/gss_krb5_crypto.c -8908cd978de626bc609a65759a6d5119 linux-3.0/net/sunrpc/auth_gss/gss_generic_token.c -ca97a26417d8236086cf6a2b126cbcbd linux-3.0/net/sunrpc/auth_gss/auth_gss.c -e277f2f93b0f4a10d7c5c9594583c531 linux-3.0/net/sunrpc/auth_gss/Makefile -fca104d1b3368b508bd19a6d94025cc1 linux-3.0/net/sunrpc/auth_generic.c -c5ddc71dde74b75de23faa203dfc5ced linux-3.0/net/sunrpc/auth.c -d9ba0ad6a257e8453aa2afd8e47ca960 linux-3.0/net/sunrpc/addr.c -5ba49574938ee1ae190b131c287047c8 linux-3.0/net/sunrpc/Makefile -ecd31c7512e9f655591dfca7d194e736 linux-3.0/net/sunrpc/Kconfig -9c2f3b4985c5a376cd7887d8466fc943 linux-3.0/net/socket.c -946671f172df78d4ddefc640c4796369 linux-3.0/net/sctp/ulpqueue.c -d35156a87abf55553d7749ca74af18a4 linux-3.0/net/sctp/ulpevent.c -7da78a814a1f1bbe6bf1741342440fa2 linux-3.0/net/sctp/tsnmap.c -ab762db5492ca9411c0ec048bd27049a linux-3.0/net/sctp/transport.c -a5ad17df77ceda58b8acf0f8750303ed linux-3.0/net/sctp/sysctl.c -596e151067253c3f60f94b1a062e9592 linux-3.0/net/sctp/ssnmap.c -b0a9f142cdb4391a81a6c400c880b4d8 linux-3.0/net/sctp/socket.c -c261685eca77b8c4fd2c16b0da171a9d linux-3.0/net/sctp/sm_statetable.c -62a41c24a36a9d0b954aa52baeea1bfe linux-3.0/net/sctp/sm_statefuns.c -10f46fccc6aa499d4ce29966bd67995d linux-3.0/net/sctp/sm_sideeffect.c -976b79cdd328c9355a4640250ccc9305 linux-3.0/net/sctp/sm_make_chunk.c -c75a08fd94bf08f96a9e6ea86c286d11 linux-3.0/net/sctp/protocol.c -1e796a8cffcb64e58eaeb7b760f98a6c linux-3.0/net/sctp/proc.c -a78f88e4b708d182c950cd74950e46d4 linux-3.0/net/sctp/probe.c -f76eaed16b3f4a456bb5b04dc23b9b21 linux-3.0/net/sctp/primitive.c -774978280dd4235e63671891c4e04373 linux-3.0/net/sctp/outqueue.c -898f3f13f4a7a6c0c36eb4080a2c86df linux-3.0/net/sctp/output.c -9887b0f995a6d8312aa5e5eb4cf92c48 linux-3.0/net/sctp/objcnt.c -589701d5d8a60e25598f2675fc811d82 linux-3.0/net/sctp/ipv6.c -4b4a8857c0560fd727e56b607a0e92a4 linux-3.0/net/sctp/inqueue.c -98c64cc3d4fdb93a32a9676109d3590b linux-3.0/net/sctp/input.c -276b76e73fe00b0e22d43982f4e42e4e linux-3.0/net/sctp/endpointola.c -41c8928a5a08b1a6a418eacbb9af343c linux-3.0/net/sctp/debug.c -0b3694a3cf133861c4d2d4ced5dbd6e2 linux-3.0/net/sctp/command.c -a5f60aa1659897bc03c6f3b33befb230 linux-3.0/net/sctp/chunk.c -718ab5ae9cfadcc0bd73034e6996bd2d linux-3.0/net/sctp/bind_addr.c -9cbbf491ff5fbd5917de6c8ecdc5a340 linux-3.0/net/sctp/auth.c -49d699feafd37bccd5a665f7b1c9f9db linux-3.0/net/sctp/associola.c -13c22012f477b848c97d301d0fe20bcc linux-3.0/net/sctp/Makefile -7cfd84a89206d532df6263cfa274e2a6 linux-3.0/net/sctp/Kconfig -3dbefaa1ef5fb1a58fc02e3f53888c79 linux-3.0/net/sched/sch_teql.c -63d923c61cf0336398c4b389b0b7ae85 linux-3.0/net/sched/sch_tbf.c -f339f4fb5f72b394eed829b11284a95f linux-3.0/net/sched/sch_sfq.c -10ec5805b38e330669baf90e8825ec1b linux-3.0/net/sched/sch_sfb.c -4729c4e575e4e00478bffd91168e9527 linux-3.0/net/sched/sch_red.c -e5755e73daea494a0b8f3bc0f08add3b linux-3.0/net/sched/sch_qfq.c -0144ad60d2f9b45b5ca97a572e569dab linux-3.0/net/sched/sch_prio.c -7f2a2e0343c77f847f410d33153fd18a linux-3.0/net/sched/sch_netem.c -2fd7216e30d3eea932ca7d9aeb02d171 linux-3.0/net/sched/sch_multiq.c -4eab16d620ecefc1978846021441de4d linux-3.0/net/sched/sch_mqprio.c -50f15c01d5fad7306f961d275531cde6 linux-3.0/net/sched/sch_mq.c -23f67eb239137a940b2891c95e5c771b linux-3.0/net/sched/sch_ingress.c -9319c7a598d1437224cd793e1e88eb86 linux-3.0/net/sched/sch_htb.c -318436c52c7ab314c9584115913e2dce linux-3.0/net/sched/sch_hfsc.c -b4610936062fdca1911bf8d900c53f87 linux-3.0/net/sched/sch_gred.c -b0a6b5570fda2c478342f03a139be3af linux-3.0/net/sched/sch_generic.c -b99dcf66a23ea3cc1da1a949d422ee79 linux-3.0/net/sched/sch_fifo.c -1a2c56a40e0b97e9b4e1f0989d6c42e2 linux-3.0/net/sched/sch_dsmark.c -147fb50cd49cb84354e1f6abb1dbee16 linux-3.0/net/sched/sch_drr.c -be8b608577949ef2726ae7aa5bcbb04f linux-3.0/net/sched/sch_choke.c -40545c61b241cfeb56eff9bbb4c28be1 linux-3.0/net/sched/sch_cbq.c -0649d6b388f5bcf074183968dd01dd28 linux-3.0/net/sched/sch_blackhole.c -4fae6af5e67315b99270245bfec2211d linux-3.0/net/sched/sch_atm.c -413d4b7c3019b40fabf77798e95f6417 linux-3.0/net/sched/sch_api.c -b0af1d6e3bad798cbcd5b044161ac87a linux-3.0/net/sched/ematch.c -18c90d83a92c72cc6eb666c055016b78 linux-3.0/net/sched/em_u32.c -7bb4359dfc8c8482e16a345bf469fd0f linux-3.0/net/sched/em_text.c -6af892815cc0cd9d5b495822bc1794cb linux-3.0/net/sched/em_nbyte.c -bffcaef55d3880c32a021c7a084091bd linux-3.0/net/sched/em_meta.c -40a05c3ccefca6d2ceff37910576d954 linux-3.0/net/sched/em_cmp.c -f6b411e8d2a460250b5775feb580d67c linux-3.0/net/sched/cls_u32.c -029c56413cca42e155362954ac77cc6d linux-3.0/net/sched/cls_tcindex.c -1fc58cd7f7c0c370d2bc011d29cafede linux-3.0/net/sched/cls_rsvp6.c -af9c0f1c600d960fa72c74476bf3948b linux-3.0/net/sched/cls_rsvp.h -dfb5ec095c7b9433b7fca124c1128572 linux-3.0/net/sched/cls_rsvp.c -688cc71b4e343976c4cef5ec0f283390 linux-3.0/net/sched/cls_route.c -798fc3c3676ff303b7c619815ea800ad linux-3.0/net/sched/cls_fw.c -4ae57bf0ee13e5b42dcf7e2c958127c2 linux-3.0/net/sched/cls_flow.c -d5420edff8382f516f27c207bebbafd7 linux-3.0/net/sched/cls_cgroup.c -78a2b199f737fed942d7a76ac7ae2e38 linux-3.0/net/sched/cls_basic.c -675ea119d5bf6d44d516a42ead10e8aa linux-3.0/net/sched/cls_api.c -2497c76c34e5088c5437f63f436ae452 linux-3.0/net/sched/act_skbedit.c -2db1d356972466f1dbc91262fd1f7f73 linux-3.0/net/sched/act_simple.c -69f824654c3ef4ef138f14eb311e29a3 linux-3.0/net/sched/act_police.c -e1b30c3765973915d2b41feaacf96007 linux-3.0/net/sched/act_pedit.c -5fd224d7591de7adb2abc62a9905d472 linux-3.0/net/sched/act_nat.c -458b1adb709e7b9314975e6191ecb795 linux-3.0/net/sched/act_mirred.c -a2a27e32a7956418c49837e831e461bc linux-3.0/net/sched/act_ipt.c -83d67768d4764e547392b72fdbb66060 linux-3.0/net/sched/act_gact.c -9888a2372e8e52f93d3eb60601289112 linux-3.0/net/sched/act_csum.c -e1044a74e6ef2a4aa2da07826c49be12 linux-3.0/net/sched/act_api.c -24cd64185d0e4180298c688e551dcd96 linux-3.0/net/sched/Makefile -e1e3d89626bbab9f4a59fb3bb59fef42 linux-3.0/net/sched/Kconfig -0a71f402734af3603d9cb6ff0461d7c7 linux-3.0/net/rxrpc/rxkad.c -d748bbcdfb86f61b315034869459c1b4 linux-3.0/net/rxrpc/ar-transport.c -48c87148c47fa3e47b7b4bdaa7146cc2 linux-3.0/net/rxrpc/ar-skbuff.c -2922b04323c13576cd4232ac948d3036 linux-3.0/net/rxrpc/ar-security.c -cf2851f9a3c1d55e88dcf0b7aa9e60ec linux-3.0/net/rxrpc/ar-recvmsg.c -f2c1a30b8f397815393a58fc84429a83 linux-3.0/net/rxrpc/ar-proc.c -6001ee79f63d498fcfcbab7cda236a0a linux-3.0/net/rxrpc/ar-peer.c -9635eb7a8a67610a0e3fa62d0a52ce7e linux-3.0/net/rxrpc/ar-output.c -55e4a017d7b5a8fe61d0365c4fbe9469 linux-3.0/net/rxrpc/ar-local.c -8cba3935ddc4df11cd36defd8cbba40d linux-3.0/net/rxrpc/ar-key.c -0c95458523264e33f69fafdca8c17fd3 linux-3.0/net/rxrpc/ar-internal.h -ac1bed109f03efcbfae93fefd8c12fd9 linux-3.0/net/rxrpc/ar-input.c -d022c39f6ed74a5b342ca19a6061334f linux-3.0/net/rxrpc/ar-error.c -cb75f5147f8183987450625d9747073c linux-3.0/net/rxrpc/ar-connevent.c -f50364a0bdfd47f3267f26073ed3fd4f linux-3.0/net/rxrpc/ar-connection.c -695f417ee6ebca8afa2338739f6cc9f4 linux-3.0/net/rxrpc/ar-call.c -3a1fc324616125d4186b7d8f33fb020d linux-3.0/net/rxrpc/ar-ack.c -60812eef965439cd9a47b95bd6bdb08e linux-3.0/net/rxrpc/ar-accept.c -6fafa1ab8f620ef3a4841864e7c0dc2d linux-3.0/net/rxrpc/af_rxrpc.c -104c2d2f33caddd93e4dbf44e765eaa6 linux-3.0/net/rxrpc/Makefile -fb2e918c787cdef695f1a6bf8170a50e linux-3.0/net/rxrpc/Kconfig -f24c5f65d93200d0aa134d07860f941d linux-3.0/net/rose/sysctl_net_rose.c -2cb174ddf0e9c3e7e4aa74e17094e725 linux-3.0/net/rose/rose_timer.c -dc0f9f58983a09f7999b22e6ba5ace53 linux-3.0/net/rose/rose_subr.c -aa6c3a156db26ba52028c7b05dc538b1 linux-3.0/net/rose/rose_route.c -47ac62ab62659e518ad28ab89c3e271b linux-3.0/net/rose/rose_out.c -9befcfef3ca89253bca67c98532307de linux-3.0/net/rose/rose_loopback.c -a5103f8327759a65e3665175b9589f99 linux-3.0/net/rose/rose_link.c -81d9c904e088be35016dc4d7a4237858 linux-3.0/net/rose/rose_in.c -aea6301419743d331c13bba21c7cedb8 linux-3.0/net/rose/rose_dev.c -ce03c63ac589590cd906d2700243f306 linux-3.0/net/rose/af_rose.c -76247acb228ac32e758d86ca5fd53a87 linux-3.0/net/rose/Makefile -61ba532fd3d9004832a43ac00571e492 linux-3.0/net/rfkill/rfkill.h -9cb938127dc2d40607514c4a04966c03 linux-3.0/net/rfkill/rfkill-regulator.c -41af4b798245620cba16cf3a307e1db2 linux-3.0/net/rfkill/rfkill-gpio.c -60e45657ee337276d0e1478042e044bf linux-3.0/net/rfkill/input.c -f3a3611f27d8eb260ceff54f71011648 linux-3.0/net/rfkill/core.c -c55112ab9ccef4aa5b81c6343a28496f linux-3.0/net/rfkill/Makefile -b3832a4d06c9d6f3f3d2ab5abd1bc653 linux-3.0/net/rfkill/Kconfig -23d7267078ce56d560ae85f2ecf99df6 linux-3.0/net/rds/xlist.h -1e999803bfe142b1a18f9cb428c0704a linux-3.0/net/rds/transport.c -303be9c4ad3259d8d76c0ce21b3a93e2 linux-3.0/net/rds/threads.c -c512035b8b6a2d7499aceb96127ea87e linux-3.0/net/rds/tcp_stats.c -9b8dd1392b03327d38387fc2278126d4 linux-3.0/net/rds/tcp_send.c -7e2fc0f2c72708bde9a4908eabe052d0 linux-3.0/net/rds/tcp_recv.c -824a861196a772eff70b8b78f1419835 linux-3.0/net/rds/tcp_listen.c -b3e0c4d583f5c543dc67db42b1f2b8f0 linux-3.0/net/rds/tcp_connect.c -12f7a75eb804deca3abc37aadc8ccea3 linux-3.0/net/rds/tcp.h -a63a996fe79a6aa179b23fd61ac27ee3 linux-3.0/net/rds/tcp.c -f0fb032ba3d8200cd04c46281b3835ac linux-3.0/net/rds/sysctl.c -aadd5e7710376588cca0fa5f69503bea linux-3.0/net/rds/stats.c -ae5ba96ddddde0e225d245f700105803 linux-3.0/net/rds/send.c -4200c3e18b6fdd0286761be1553b9d44 linux-3.0/net/rds/recv.c -ae3c27bd983240ba29e382914223179e linux-3.0/net/rds/rds.h -78402f9826bd3272b1d422c586d8e5b5 linux-3.0/net/rds/rdma_transport.h -01482b02dc9306e58108ea4791c9a303 linux-3.0/net/rds/rdma_transport.c -4b57763824be3a2a746cb9b7d1fa5bf6 linux-3.0/net/rds/rdma.c -dd2224bd2a72e26f96312d251adc9096 linux-3.0/net/rds/page.c -26f6e1974bd046fec7e242c85ead784d linux-3.0/net/rds/message.c -cfbc5f86c150c5d4895f6df4a88fbbd8 linux-3.0/net/rds/loop.h -e5272c33c2a3a722ececd2f2d8e72e42 linux-3.0/net/rds/loop.c -2e542cc36d37460b1c79225738bf5ef1 linux-3.0/net/rds/iw_sysctl.c -f61366303135ff57654fa0b95b2c4d47 linux-3.0/net/rds/iw_stats.c -9bb82fbf1ad42c7d082f2c2ce51058a2 linux-3.0/net/rds/iw_send.c -5c7fc7f8f85db32ac7f85e8df2c8fc98 linux-3.0/net/rds/iw_ring.c -698766286763b63fc1d7f81a54bc24ff linux-3.0/net/rds/iw_recv.c -d02ee5d10a9849c1cfcb1117c12808eb linux-3.0/net/rds/iw_rdma.c -4faa74349fc639e4556d5399e6a8ed64 linux-3.0/net/rds/iw_cm.c -4c872accee195b350667bc2d08e8f842 linux-3.0/net/rds/iw.h -82c67cd38dc1396fc7aec04379dd5d6e linux-3.0/net/rds/iw.c -326ed206f48ab7ec6bc65417e8213787 linux-3.0/net/rds/info.h -5130fe0be95291e8b1608925934b4058 linux-3.0/net/rds/info.c -7197da2a02487a38c8bcfbde8290ffd5 linux-3.0/net/rds/ib_sysctl.c -3a217206aecd54932d4a3e78907a7cc6 linux-3.0/net/rds/ib_stats.c -b8f1143e46d0ade51ea5adb719dea810 linux-3.0/net/rds/ib_send.c -3eaf413a95ea49cbb07fb4892ef40040 linux-3.0/net/rds/ib_ring.c -03fd016ec4bfcb51b110ed26dec97f47 linux-3.0/net/rds/ib_recv.c -0798749b113711f25e422ba30468c331 linux-3.0/net/rds/ib_rdma.c -5487f3762223aff2f5320dd7261fb1ec linux-3.0/net/rds/ib_cm.c -47f9c80600ebf5b8111f548a89ca1ca8 linux-3.0/net/rds/ib.h -796d87234b5ebdc66beb347c2c328e46 linux-3.0/net/rds/ib.c -c615d8e13251b8079397a37043bfdece linux-3.0/net/rds/connection.c -f5c6261d41d3174606b497b145b05691 linux-3.0/net/rds/cong.c -0704ad688ad47ab884827cc2cb7cb775 linux-3.0/net/rds/bind.c -055838fd77359a06d786ecd7d287ef2f linux-3.0/net/rds/af_rds.c -8aa7a7d82202d20124574a47bee3af7f linux-3.0/net/rds/Makefile -4b9d1dd598937632d17a987baed05f8e linux-3.0/net/rds/Kconfig -bc619ad20167d9bb43fd504c5e3abeb2 linux-3.0/net/phonet/sysctl.c -cbc000cc38a7214848fab5a376b1ad85 linux-3.0/net/phonet/socket.c -943c4ca9530d5638974c03cb5bfa7bac linux-3.0/net/phonet/pn_netlink.c -ecbbd9bb39598266a8b7348b961bad23 linux-3.0/net/phonet/pn_dev.c -323983f0fe7b4af146d888f4459cf618 linux-3.0/net/phonet/pep.c -1cc95f8a1c7fc36a560dbf7e9918141b linux-3.0/net/phonet/pep-gprs.c -75234046e6026ce49744c7cece23bedf linux-3.0/net/phonet/datagram.c -6c002f087a87c69aacbc1332597a4ea3 linux-3.0/net/phonet/af_phonet.c -8762dd55749248c58252e662142300ae linux-3.0/net/phonet/Makefile -9e3a28c87e2014461f62c19c51c810c6 linux-3.0/net/phonet/Kconfig -1199cf39c5fe3affaf269996229c03fb linux-3.0/net/packet/af_packet.c -e7ad58806f4c309763e3965a8def12f2 linux-3.0/net/packet/Makefile -15cee9c03a3552d77c26d78af9ded40e linux-3.0/net/packet/Kconfig -6f339bd1061fa5ef19a885bb027e60a3 linux-3.0/net/nonet.c -c9e1e13340a3c3dc79731412c89e1233 linux-3.0/net/netrom/sysctl_net_netrom.c -40b2cc501cffc92245956eba7f724d24 linux-3.0/net/netrom/nr_timer.c -2a091043e9d4ab13e262c254ed83ec46 linux-3.0/net/netrom/nr_subr.c -112206d18e663cec239061e09f9ff130 linux-3.0/net/netrom/nr_route.c -a7a9a3db692d6f042d352a288b73c50f linux-3.0/net/netrom/nr_out.c -5a4d3068a3dabfdb811e37a25bdd5205 linux-3.0/net/netrom/nr_loopback.c -160052e3b60b12bf2b2526b42e765518 linux-3.0/net/netrom/nr_in.c -8479fb9783f9d512c572b2311b5f12b2 linux-3.0/net/netrom/nr_dev.c -4ff79612d1764e025ab26245d41508a4 linux-3.0/net/netrom/af_netrom.c -53144c6a0918ffe0349fcb46093474f9 linux-3.0/net/netrom/Makefile -a5c00afee46a7ae03b64ae041955e4f9 linux-3.0/net/netlink/genetlink.c -3d29e91405eaa695eb4d8c0b40cfdb14 linux-3.0/net/netlink/af_netlink.c -ec169419bc890b845eaaac842ed5c505 linux-3.0/net/netlink/Makefile -db4d31ca8c62575d13dda4ecaf82bfab linux-3.0/net/netlabel/netlabel_user.h -3b48145951304a6e41db1d45ac8b6d3e linux-3.0/net/netlabel/netlabel_user.c -2b533a0b1c991d4d19d5f5dbfc32a040 linux-3.0/net/netlabel/netlabel_unlabeled.h -bee34233015b9258a2c3adfbd3ce1dcc linux-3.0/net/netlabel/netlabel_unlabeled.c -0c7c35f907dae39219a638de70a5ad34 linux-3.0/net/netlabel/netlabel_mgmt.h -6d986c97e4c82e12d8a8a139b9dea2b6 linux-3.0/net/netlabel/netlabel_mgmt.c -67a61e02c82df64baba827c1be0ddfa1 linux-3.0/net/netlabel/netlabel_kapi.c -3a31228c79644e1143f967f64ba8e917 linux-3.0/net/netlabel/netlabel_domainhash.h -97b440423905ea80d34c3062e824038b linux-3.0/net/netlabel/netlabel_domainhash.c -f4a38accb5c528347362a9f6dfa90332 linux-3.0/net/netlabel/netlabel_cipso_v4.h -ced6d5e76ea3dd43f6d58b888834cae3 linux-3.0/net/netlabel/netlabel_cipso_v4.c -7a4bb258f56cc23b4be11b7eeb05270c linux-3.0/net/netlabel/netlabel_addrlist.h -172594bb96362d7e4da838a23abac8f8 linux-3.0/net/netlabel/netlabel_addrlist.c -6928414175ba04caf44bece1db20604a linux-3.0/net/netlabel/Makefile -7fdcbfa6f5957c90b4e6df4e50a9a51c linux-3.0/net/netlabel/Kconfig -12cb8554844351aede74f08e0b812d7e linux-3.0/net/netfilter/xt_u32.c -5a39995ed9053e9a51af56b1f9fa834f linux-3.0/net/netfilter/xt_time.c -4d00030ceb8fd05a41142c5cca95b0e2 linux-3.0/net/netfilter/xt_tcpudp.c -11e4f6278e191a444eb874941b6a9e37 linux-3.0/net/netfilter/xt_tcpmss.c -029327ad49ad11e5e63e7b9f9cfb5b24 linux-3.0/net/netfilter/xt_string.c -f6154302c201714ba9cedb3f536c4e41 linux-3.0/net/netfilter/xt_statistic.c -a6832d50b210553eccac04261b8e9277 linux-3.0/net/netfilter/xt_state.c -0d04128f36a42f3dacf61861a417ef1a linux-3.0/net/netfilter/xt_socket.c -8635017d084f9dc0802544af85e75455 linux-3.0/net/netfilter/xt_set.c -67b8db39c002126c2398392eb71b1fdb linux-3.0/net/netfilter/xt_sctp.c -e0ffb0a0383e9aba43bd1782492663eb linux-3.0/net/netfilter/xt_repldata.h -c908edebd4349565648ff871074ae80c linux-3.0/net/netfilter/xt_recent.c -173924fb5333d57d8e94c7b4ad942573 linux-3.0/net/netfilter/xt_realm.c -4111205e8b8cc1a10cfc63984f574af3 linux-3.0/net/netfilter/xt_rateest.c -cdd7486ab034712bb3c9dd921b6ff1d9 linux-3.0/net/netfilter/xt_quota.c -a6fcef3aedc4208f8d26bc2c784b4710 linux-3.0/net/netfilter/xt_policy.c -5cc1c700e1083371157955fedaff2edb linux-3.0/net/netfilter/xt_pkttype.c -9ceb61a1c7e03e8214bff2984f01b30f linux-3.0/net/netfilter/xt_physdev.c -10a60854399dde788ed055077428c809 linux-3.0/net/netfilter/xt_owner.c -409eb5675386d70b63f9a8d56f599421 linux-3.0/net/netfilter/xt_osf.c -641299faf17e92f2f30e796e91bd77c8 linux-3.0/net/netfilter/xt_multiport.c -bc71ba6c8f557fcde88bc99cb729d175 linux-3.0/net/netfilter/xt_mark.c -1997f08210f3ffbfec763c86d7f555c1 linux-3.0/net/netfilter/xt_mac.c -c1083b7e8b67334de0a0d981de02a268 linux-3.0/net/netfilter/xt_limit.c -7fa3ac5558b2c6d4c92db5bfa710a659 linux-3.0/net/netfilter/xt_length.c -e38c27cb6218ff6d1e019330098a4245 linux-3.0/net/netfilter/xt_ipvs.c -9225061118902440e76b53f3bff18f3c linux-3.0/net/netfilter/xt_iprange.c -cc8afb204041ddae4689212f198ff5a0 linux-3.0/net/netfilter/xt_hl.c -cf14eab58dd61c86176427d3a16b8910 linux-3.0/net/netfilter/xt_helper.c -f506b71184b0287213ca9bf1f352e682 linux-3.0/net/netfilter/xt_hashlimit.c -1c13ed6f2c1eefb9df45575a39948c4c linux-3.0/net/netfilter/xt_esp.c -ef002096ff9f4e9c634be3090d0e3b70 linux-3.0/net/netfilter/xt_dscp.c -989e71ba0c32ef55e22a148db3663463 linux-3.0/net/netfilter/xt_devgroup.c -efa4eb2cd2054ae390c4be9bfc5654ff linux-3.0/net/netfilter/xt_dccp.c -dc13d245906747d2710ea82ab19608cd linux-3.0/net/netfilter/xt_cpu.c -ef841cf5fb319ae3ccd1ac2f14bb26c5 linux-3.0/net/netfilter/xt_conntrack.c -02009ecc856775bbde50d4cc09a84ea6 linux-3.0/net/netfilter/xt_connmark.c -aaf40a9d1866afd6639794fb957d6e8a linux-3.0/net/netfilter/xt_connlimit.c -901cb151dbf831834a025f027e67388a linux-3.0/net/netfilter/xt_connbytes.c -529111d5b8725f6784105dcfb0c33479 linux-3.0/net/netfilter/xt_comment.c -1fbf9f987c69a07b91b46f06816dc441 linux-3.0/net/netfilter/xt_cluster.c -49614c4aa6b13c32f23b747dc828afed linux-3.0/net/netfilter/xt_addrtype.c -8c520786e86991dfe685aba1a8a49fd6 linux-3.0/net/netfilter/xt_TRACE.c -c963711990fa0ff71c08b9935e263f9f linux-3.0/net/netfilter/xt_TPROXY.c -f18febe8091bc82497c7624d193de627 linux-3.0/net/netfilter/xt_TEE.c -7d4b5b97beb66c8c346b41ae6d81bee3 linux-3.0/net/netfilter/xt_TCPOPTSTRIP.c -092efc795677c181f045b2df71c72ede linux-3.0/net/netfilter/xt_TCPMSS.c -3f8c261ffdc9cd3f923ebfc0b21f654b linux-3.0/net/netfilter/xt_SECMARK.c -0d409f30c2ae9b947793d8bf30046bf1 linux-3.0/net/netfilter/xt_RATEEST.c -0c445ba79deb18d2a19646d205e5d32c linux-3.0/net/netfilter/xt_NOTRACK.c -f80974f64949991612ccafb6bac55a97 linux-3.0/net/netfilter/xt_NFQUEUE.c -d1bf3e693500ffb0f454cef249671e8b linux-3.0/net/netfilter/xt_NFLOG.c -b43e76dd050671af31327c2b46bd4d33 linux-3.0/net/netfilter/xt_LED.c -cf054278521c497b573dc77b84682558 linux-3.0/net/netfilter/xt_IDLETIMER.c -c298f93bbfaf90995fc435239026c172 linux-3.0/net/netfilter/xt_HL.c -87b10a3adbb0b30506acef768c4281aa linux-3.0/net/netfilter/xt_DSCP.c -54f96a623d69613328f0b13039f68730 linux-3.0/net/netfilter/xt_CT.c -c4f4e2cb47f0b8f75f2bab2a523d354e linux-3.0/net/netfilter/xt_CONNSECMARK.c -4804b7cc2f7ca7d3c66070a29cb2dd8f linux-3.0/net/netfilter/xt_CLASSIFY.c -f34aea4f5c29fa727687b6702be51ead linux-3.0/net/netfilter/xt_CHECKSUM.c -3717e22f29a9c8a23fe6a147f3b0a380 linux-3.0/net/netfilter/xt_AUDIT.c -ea19a63aefbce62ff8860f37901686e2 linux-3.0/net/netfilter/x_tables.c -0e45f126d476ab51d7bcc12c8dda0fee linux-3.0/net/netfilter/nfnetlink_queue.c -5089903604616c53a3be6ef000a56ca1 linux-3.0/net/netfilter/nfnetlink_log.c -160b37bd627f7c5c1d407c70fee3050a linux-3.0/net/netfilter/nfnetlink.c -449942a552f2a961fdf83294de9a16e7 linux-3.0/net/netfilter/nf_tproxy_core.c -518629e8837afb3242758db385c2da2d linux-3.0/net/netfilter/nf_sockopt.c -44e0ea96f2108b24b3e3ec148a29a1c4 linux-3.0/net/netfilter/nf_queue.c -52e8ea7a947fbe734270eb57d092fff3 linux-3.0/net/netfilter/nf_log.c -02ee8dd2d260c7c0415a4ba8d989db14 linux-3.0/net/netfilter/nf_internals.h -a9f673081fcacfe07f1d21b4af33a163 linux-3.0/net/netfilter/nf_conntrack_timestamp.c -e2fa1d62a53aff89000550df138f5263 linux-3.0/net/netfilter/nf_conntrack_tftp.c -c10d689e5687113f0c8f5e59e843b8a0 linux-3.0/net/netfilter/nf_conntrack_standalone.c -d20fc0e0d34bdf57303a26f6a35509aa linux-3.0/net/netfilter/nf_conntrack_snmp.c -ecf113c4470751da2e6d6c043c762f62 linux-3.0/net/netfilter/nf_conntrack_sip.c -9af1c31252db6bb6decee84ea368f0c3 linux-3.0/net/netfilter/nf_conntrack_sane.c -853c683f290add645b870faa4d32c4ed linux-3.0/net/netfilter/nf_conntrack_proto_udplite.c -ad3c67597d57ce2907454bde4f74a007 linux-3.0/net/netfilter/nf_conntrack_proto_udp.c -d4b36aa2ecdec760806387dfe087a961 linux-3.0/net/netfilter/nf_conntrack_proto_tcp.c -76b0ee8eaae527400512582bf3bb21f2 linux-3.0/net/netfilter/nf_conntrack_proto_sctp.c -50fd28652c22f43c3fdfe36affba283f linux-3.0/net/netfilter/nf_conntrack_proto_gre.c -efaced0a0b2303cd9ce98b4530799ee8 linux-3.0/net/netfilter/nf_conntrack_proto_generic.c -a284411efdd1e1c5b48b8a2d002bdf4d linux-3.0/net/netfilter/nf_conntrack_proto_dccp.c -4cab6623f6fe378dc4b57faa2a58a3c3 linux-3.0/net/netfilter/nf_conntrack_proto.c -59af2c36b3ee93d4c5ff9dc713c16931 linux-3.0/net/netfilter/nf_conntrack_pptp.c -3814dd50012b84a5410b7e4307830bee linux-3.0/net/netfilter/nf_conntrack_netlink.c -26035e877b4dc4b4898296e648e32271 linux-3.0/net/netfilter/nf_conntrack_netbios_ns.c -56d8c2b32e0e0a09847bd59f63055ff8 linux-3.0/net/netfilter/nf_conntrack_l3proto_generic.c -b6620ba82a3a59ecec3bbcf5cd33d825 linux-3.0/net/netfilter/nf_conntrack_irc.c -e50cba1b52ee166a05b4c5f0ef87e27b linux-3.0/net/netfilter/nf_conntrack_helper.c -0fb971065a3dfc9e128d3032bb7e2645 linux-3.0/net/netfilter/nf_conntrack_h323_types.c -651dcbcd488f9dff8b1b4881a81a3491 linux-3.0/net/netfilter/nf_conntrack_h323_main.c -74b2070e7caa687cb62e0c6c1f2625f1 linux-3.0/net/netfilter/nf_conntrack_h323_asn1.c -c08a44ae9a5a266432d008992be089b1 linux-3.0/net/netfilter/nf_conntrack_ftp.c -6bddd63125153e766aad0ed9684db620 linux-3.0/net/netfilter/nf_conntrack_extend.c -f067b9787dc74bae17e9f8e4540d6e39 linux-3.0/net/netfilter/nf_conntrack_expect.c -07ad7bb68b4e31b7176f1ffe54385129 linux-3.0/net/netfilter/nf_conntrack_ecache.c -6a470cd4ced86db6b090fc4b8693acdc linux-3.0/net/netfilter/nf_conntrack_core.c -ab496094ba78e2166cac060c85f7118c linux-3.0/net/netfilter/nf_conntrack_broadcast.c -523fe7fbbf8f46aca7c32ec7ee3a7e89 linux-3.0/net/netfilter/nf_conntrack_amanda.c -4d797760df8ee1cfc8c7bb41a67886a4 linux-3.0/net/netfilter/nf_conntrack_acct.c -6c1bcc58967137ae0a9553a9effd0b77 linux-3.0/net/netfilter/ipvs/ip_vs_xmit.c -7df2bb81051364c9103726da5d3150f8 linux-3.0/net/netfilter/ipvs/ip_vs_wrr.c -2933646601b6413d687a1f1157041c30 linux-3.0/net/netfilter/ipvs/ip_vs_wlc.c -6f8e1850f4340cb543a72c06498293ad linux-3.0/net/netfilter/ipvs/ip_vs_sync.c -dac2c13c025de69ae7d5389e31c00522 linux-3.0/net/netfilter/ipvs/ip_vs_sh.c -48bb4b92708f1be673412a14f742e6bc linux-3.0/net/netfilter/ipvs/ip_vs_sed.c -683da67e203db542532ba5628df16021 linux-3.0/net/netfilter/ipvs/ip_vs_sched.c -341fb5dbea43a050c23f8ce2dc9d354f linux-3.0/net/netfilter/ipvs/ip_vs_rr.c -824ad4b653ed8967188e73d5afdd0397 linux-3.0/net/netfilter/ipvs/ip_vs_proto_udp.c -117d03ef821f95fd799d89aa7e4a6f07 linux-3.0/net/netfilter/ipvs/ip_vs_proto_tcp.c -ea4996ec160cd88cd414d023579ac7c1 linux-3.0/net/netfilter/ipvs/ip_vs_proto_sctp.c -03a31e21ffa49fa1f16be0b557e930af linux-3.0/net/netfilter/ipvs/ip_vs_proto_ah_esp.c -fa3bd95706c28a1b612e363dbc62b8dd linux-3.0/net/netfilter/ipvs/ip_vs_proto.c -f0aecdce6bf5ff5104222e057b36346b linux-3.0/net/netfilter/ipvs/ip_vs_pe_sip.c -f110eab491f70138a8abc20e2719b31e linux-3.0/net/netfilter/ipvs/ip_vs_pe.c -8f29182fc7c102f9505d1101caa4b5e1 linux-3.0/net/netfilter/ipvs/ip_vs_nq.c -7cc582ed489c6c39556517e84c983b75 linux-3.0/net/netfilter/ipvs/ip_vs_nfct.c -ccd76d646212f26aa2c2a44da0d1bf03 linux-3.0/net/netfilter/ipvs/ip_vs_lc.c -6fe5b7eff9dbfcdec5b958287e0079d4 linux-3.0/net/netfilter/ipvs/ip_vs_lblcr.c -4fbaad71317a45735a605ba205ed8c3a linux-3.0/net/netfilter/ipvs/ip_vs_lblc.c -2ce596b3e363224c83c35a1d10cc4e2b linux-3.0/net/netfilter/ipvs/ip_vs_ftp.c -e6478707189dd76b65f7ad6912876e80 linux-3.0/net/netfilter/ipvs/ip_vs_est.c -6e78a79fc199b1a60598b83c84044f9f linux-3.0/net/netfilter/ipvs/ip_vs_dh.c -4f9b7af975680008f2b3e8a871ef9988 linux-3.0/net/netfilter/ipvs/ip_vs_ctl.c -b7e65491819c4c405652d1e43526d3b8 linux-3.0/net/netfilter/ipvs/ip_vs_core.c -fd866c956ec09e68a833ba9f5e616ae7 linux-3.0/net/netfilter/ipvs/ip_vs_conn.c -bc6cfa961d4cae5edb80dc9b85a7cd5b linux-3.0/net/netfilter/ipvs/ip_vs_app.c -64e788c604504e92b93c9e97db6bf8ab linux-3.0/net/netfilter/ipvs/Makefile -90bfd79709f715de5cbd409ad899ff5d linux-3.0/net/netfilter/ipvs/Kconfig -9d2be7af60467d502f93dfe99b14ab65 linux-3.0/net/netfilter/ipset/pfxlen.c -0f0ed3a20d39879c5513e96c56c0a919 linux-3.0/net/netfilter/ipset/ip_set_list_set.c -bd58a4ad24ae7d496ff57d7377d7c215 linux-3.0/net/netfilter/ipset/ip_set_hash_netport.c -d5b2a9cfbaa5faa15a5870ee85080167 linux-3.0/net/netfilter/ipset/ip_set_hash_net.c -aa0febecd5ad81966173d516a4b42ba1 linux-3.0/net/netfilter/ipset/ip_set_hash_ipportnet.c -cbfa01a33f0ddab3f5497556dd8bc631 linux-3.0/net/netfilter/ipset/ip_set_hash_ipportip.c -aa0a664ff82456c68e6baa77cf1084cc linux-3.0/net/netfilter/ipset/ip_set_hash_ipport.c -d6bef97dd54e897d6ff27eb736db3609 linux-3.0/net/netfilter/ipset/ip_set_hash_ip.c -c96a4bbd9d5eae12591ccf7645c8620d linux-3.0/net/netfilter/ipset/ip_set_getport.c -6943989ed5c233b19192945f2810f4a7 linux-3.0/net/netfilter/ipset/ip_set_core.c -037fcf0325243f25afbe2d525019d99e linux-3.0/net/netfilter/ipset/ip_set_bitmap_port.c -cfa1405151944b3610973cd6c90bd7d8 linux-3.0/net/netfilter/ipset/ip_set_bitmap_ipmac.c -c38abd4828cec3aa4c562aa53b855793 linux-3.0/net/netfilter/ipset/ip_set_bitmap_ip.c -7842cda93bf219115b65ea3e448b62d6 linux-3.0/net/netfilter/ipset/Makefile -2007e070cd009feed223d1dccde19562 linux-3.0/net/netfilter/ipset/Kconfig -729987df7527dbf61735f3aa4f8b7169 linux-3.0/net/netfilter/core.c -b0ebed13c17379b59db513026b362afb linux-3.0/net/netfilter/Makefile -d02ad0ed29e4b412f2abca439a76d212 linux-3.0/net/netfilter/Kconfig -3219d2faafc5cfb958653751161034c3 linux-3.0/net/mac80211/wpa.h -28b2f6c1bc15b5c4b1806ba5ad866b2d linux-3.0/net/mac80211/wpa.c -3a9baf66a0c5249db74a8751b82ec044 linux-3.0/net/mac80211/work.c -8dfcfb6b297991f5c0f6907b8933f50a linux-3.0/net/mac80211/wme.h -fcc637169586800b7ac9df58754dc27f linux-3.0/net/mac80211/wme.c -441b022cdf08b9b3690823bc8276a891 linux-3.0/net/mac80211/wep.h -dbd38b8ceab383d89b453a03b26cff0e linux-3.0/net/mac80211/wep.c -8866f8c670594e39f3242ded89468230 linux-3.0/net/mac80211/util.c -241ffbb312271e62d7a3252add7e47c8 linux-3.0/net/mac80211/tx.c -d8bab56a8023a9d2c0f7d5e5ea50f634 linux-3.0/net/mac80211/tkip.h -9dac02ef7be0a110ce3881579ff7c14d linux-3.0/net/mac80211/tkip.c -8541c08298771b2d423db771ce4440c9 linux-3.0/net/mac80211/status.c -3a151836d39775bf478e974acfeb68b3 linux-3.0/net/mac80211/sta_info.h -21a5ab36b71a63a3a66404acf37e960d linux-3.0/net/mac80211/sta_info.c -73ff12028cd0c4b39ca1a8e448dc1ca7 linux-3.0/net/mac80211/spectmgmt.c -9755cdd34f705fadb2f00f6d4777d7cd linux-3.0/net/mac80211/scan.c -916f0953d8797bc7e170996c9cc2c71e linux-3.0/net/mac80211/rx.c -d1c67f7c26d39a6dda87ac2c6e1ecf11 linux-3.0/net/mac80211/rc80211_pid_debugfs.c -8c892262116e8c99340f75522a3baafe linux-3.0/net/mac80211/rc80211_pid_algo.c -13906bfe5691545fc8365c782f60ea70 linux-3.0/net/mac80211/rc80211_pid.h -db28aaef31d95bfe576db181903bdf8d linux-3.0/net/mac80211/rc80211_minstrel_ht_debugfs.c -6f347f6d5e74bc2c4880827741528fe9 linux-3.0/net/mac80211/rc80211_minstrel_ht.h -1493a938d513470c0e2cc23432a7587b linux-3.0/net/mac80211/rc80211_minstrel_ht.c -8740d17ba5d3dad768f0cc79a016d616 linux-3.0/net/mac80211/rc80211_minstrel_debugfs.c -eea60a1490f65896d91ba9225e869174 linux-3.0/net/mac80211/rc80211_minstrel.h -0625b27ae3bd1f208159050299262adc linux-3.0/net/mac80211/rc80211_minstrel.c -b304476b43c801363d9fbf039d40d387 linux-3.0/net/mac80211/rate.h -66434172da1f566f470e6de356664862 linux-3.0/net/mac80211/rate.c -cede325a973a300ef0b066faa8a6f080 linux-3.0/net/mac80211/pm.c -d03e886b14c0ae445b01a2fb0f76e897 linux-3.0/net/mac80211/offchannel.c -10d57e2ad42d11a96c9a15603a5c29e1 linux-3.0/net/mac80211/mlme.c -216d969f606701174c8a0dd58363e729 linux-3.0/net/mac80211/michael.h -d1834be366c72e14656a559a2541bf20 linux-3.0/net/mac80211/michael.c -70e10f23b364f68e6b8d3650797f2ebb linux-3.0/net/mac80211/mesh_plink.c -ce99acc02d239e6dde1833fa01821478 linux-3.0/net/mac80211/mesh_pathtbl.c -9230bd02e96666998bdadfcc23fb5a89 linux-3.0/net/mac80211/mesh_hwmp.c -9d80f563bf185089db2cd67fb9216732 linux-3.0/net/mac80211/mesh.h -dcc38a9a1e4d25ac08774db832d7eb25 linux-3.0/net/mac80211/mesh.c -d442f264e39f80e8318a651f071164e6 linux-3.0/net/mac80211/main.c -e437ad38b52e071a8ca6db1e1aecabb9 linux-3.0/net/mac80211/led.h -2f1e4850198bb3709c152c9465ca895a linux-3.0/net/mac80211/led.c -63b514d1cd720083f82456a4ab0359d1 linux-3.0/net/mac80211/key.h -b39cfdbd2fdc22175b01339a6464bc70 linux-3.0/net/mac80211/key.c -21063b1bcf3976d34770269f2989e70c linux-3.0/net/mac80211/iface.c -d638c4ea8254cd7649bd9ee0091c82ce linux-3.0/net/mac80211/ieee80211_i.h -5b60a921221d3ce1ab185785b939366d linux-3.0/net/mac80211/ibss.c -ec2ba564e0b5d0a01400919a79359868 linux-3.0/net/mac80211/ht.c -55a3ad455ea5c70803eea0cf70896450 linux-3.0/net/mac80211/event.c -cdf3ee26f5a3588c8ab4def859733599 linux-3.0/net/mac80211/driver-trace.h -872563b9db0317c7307fd010e9a220c3 linux-3.0/net/mac80211/driver-trace.c -ea1311cc77938ce56ae0dca8f3897e13 linux-3.0/net/mac80211/driver-ops.h -4ffda39dd0d8d19c111e078ff60cb926 linux-3.0/net/mac80211/debugfs_sta.h -de37df87d8b5fd10269797076b7a8724 linux-3.0/net/mac80211/debugfs_sta.c -1a4eef429a831789d797dc01cddbf760 linux-3.0/net/mac80211/debugfs_netdev.h -ad9dd938579a3d4fc75be1a5346f2f82 linux-3.0/net/mac80211/debugfs_netdev.c -cb87d205ee6ae21208fc5daed24b59b4 linux-3.0/net/mac80211/debugfs_key.h -15e5ccfc0cb697e89cfa27a7984957f3 linux-3.0/net/mac80211/debugfs_key.c -6666f5b0771be06d455134da769bc650 linux-3.0/net/mac80211/debugfs.h -c9e906fae51c05835994744ef914f50f linux-3.0/net/mac80211/debugfs.c -e9e6e36b4b35d1fdea804a703ad38f49 linux-3.0/net/mac80211/chan.c -c1f8d57334ed1fdf696b6b7f95a8b1ef linux-3.0/net/mac80211/cfg.h -ab1ad7c54c0cac634f151555acc5210b linux-3.0/net/mac80211/cfg.c -ae0ec9a9c1b660f08aecf954c5169fed linux-3.0/net/mac80211/agg-tx.c -307dc413c505b3383bdd2ed691aaa029 linux-3.0/net/mac80211/agg-rx.c -1025b017852b13ee5d9e73d3a79b07f3 linux-3.0/net/mac80211/aes_cmac.h -4b0ad6cadc10490a9d1a0fecf3b86f97 linux-3.0/net/mac80211/aes_cmac.c -8de8e54a3452ff1e38f092447401af81 linux-3.0/net/mac80211/aes_ccm.h -8133638f47dee91cc1a4d74952b7492e linux-3.0/net/mac80211/aes_ccm.c -ba9ff99d74b145e6dfde6159887878cc linux-3.0/net/mac80211/Makefile -2d06b4e8163e6e94883a3db5018c8164 linux-3.0/net/mac80211/Kconfig -322055a6edcbc9764d50a384c703007d linux-3.0/net/llc/sysctl_net_llc.c -85db14668dd3758f74eca0af864f4b67 linux-3.0/net/llc/llc_station.c -8e5b159115c99c057f659345c67c0b2e linux-3.0/net/llc/llc_sap.c -3dfec31df4644d096abcd84c395d9374 linux-3.0/net/llc/llc_s_st.c -0aa9e998e88806a0a8bdb20aa8d89bbf linux-3.0/net/llc/llc_s_ev.c -75c041bd9b77710234be57bca0113eee linux-3.0/net/llc/llc_s_ac.c -ad73db719c264151c714acbd6e3cb619 linux-3.0/net/llc/llc_proc.c -5dc91f4e95074392c37604ddc4d8fef0 linux-3.0/net/llc/llc_pdu.c -dbda8edbe89fe7254cff19ee07f98c0a linux-3.0/net/llc/llc_output.c -65dbefbe340b804467316f6245b9abd3 linux-3.0/net/llc/llc_input.c -0f6643f00da94654803564bb38ada268 linux-3.0/net/llc/llc_if.c -6533a27cdc55b440d1ecf120c692f9ab linux-3.0/net/llc/llc_core.c -6398717b5e1026486b1abad9a06b8866 linux-3.0/net/llc/llc_conn.c -460955f2990dbdb5dba266604359d84e linux-3.0/net/llc/llc_c_st.c -f8ab5d05238c9557fe98290a8a89010b linux-3.0/net/llc/llc_c_ev.c -32628482f986a2e13119ee1943ee9ee7 linux-3.0/net/llc/llc_c_ac.c -2c7b2cae4913825fc006bdfb28f70205 linux-3.0/net/llc/af_llc.c -d6ec8619f79e08483220eec6aa9739c0 linux-3.0/net/llc/Makefile -2cb16d7af6cb8541f7362c62149b5c24 linux-3.0/net/llc/Kconfig -642ffb2377fa85bcb270195d7888a54c linux-3.0/net/lapb/lapb_timer.c -5b18721a02095bc32fc6d1542a72aff7 linux-3.0/net/lapb/lapb_subr.c -f113315ff07dfee653b6ddc98ae08699 linux-3.0/net/lapb/lapb_out.c -d7d39fd7977a24f42329429240f043c1 linux-3.0/net/lapb/lapb_in.c -82d71114c089fd06420f8833765967c0 linux-3.0/net/lapb/lapb_iface.c -f63924d541cb63ce88988a5921666e0b linux-3.0/net/lapb/Makefile -743165b344711d81f6fe31249b03d009 linux-3.0/net/lapb/Kconfig -1f490fc62b9ba57e7ec289bf3f475a32 linux-3.0/net/l2tp/l2tp_ppp.c -365401d846ab25ed99603ed9eb86cc6e linux-3.0/net/l2tp/l2tp_netlink.c -275a2cb343871cd71b7cdb20a7985f5b linux-3.0/net/l2tp/l2tp_ip.c -add6150ef7f05b7353a563997c17a947 linux-3.0/net/l2tp/l2tp_eth.c -91216e3c1c69deebb2f9f44da306481f linux-3.0/net/l2tp/l2tp_debugfs.c -47130163db34e0b7abdc17503a33a541 linux-3.0/net/l2tp/l2tp_core.h -4fe647c5b670a25be127bd54b2769ad9 linux-3.0/net/l2tp/l2tp_core.c -9e397ebd9287e4d784a78843e7ee05bd linux-3.0/net/l2tp/Makefile -a7b49ecf7d5d3060753390aacdbc981d linux-3.0/net/l2tp/Kconfig -8affb7c40878e539e7677682bee7d1c7 linux-3.0/net/key/af_key.c -b882a0e9f6d37962dcf5a8093b50cd6c linux-3.0/net/key/Makefile -779ff61acbf418961db0e7b5136fa348 linux-3.0/net/iucv/iucv.c -bc0442a145e600545b284445f79ac657 linux-3.0/net/iucv/af_iucv.c -5f1e4bb1676d50f6b98c4a09cfdcd01d linux-3.0/net/iucv/Makefile -4ba1c2f115e41fdc907ef4a6b633c495 linux-3.0/net/iucv/Kconfig -3ee91673d31aa3023728cf429fc2f955 linux-3.0/net/irda/wrapper.c -99a4be9db4e69e1cb5f4ca3d652f7a0c linux-3.0/net/irda/timer.c -01bb965f31f5cd91854b90a1407d293e linux-3.0/net/irda/qos.c -e057784df94d9eaa5f26ef0d7bf60f9f linux-3.0/net/irda/parameters.c -05e528f5814e766dc5b6381576893855 linux-3.0/net/irda/irttp.c -8b6530f1cf40f35d6968fe3add722064 linux-3.0/net/irda/irsysctl.c -a44d8781792aebd637e9c9e55acf1bcf linux-3.0/net/irda/irqueue.c -98332f475c1caf6a4d101367bb90f369 linux-3.0/net/irda/irproc.c -34f99c102e337fc8784b2610406e33b9 linux-3.0/net/irda/irnetlink.c -c75302e899d8677547025c88576e4a10 linux-3.0/net/irda/irnet/irnet_ppp.h -5aa6309c14346028edfa8e4c7acddbbf linux-3.0/net/irda/irnet/irnet_ppp.c -3dd0b9434aac855dfc1596f60c24b74a linux-3.0/net/irda/irnet/irnet_irda.h -8902b2ffbf3d64715996c9e1a8432adb linux-3.0/net/irda/irnet/irnet_irda.c -fb74f239082c51c01a1a28abb9c08078 linux-3.0/net/irda/irnet/irnet.h -8f61c006fa4a0138a997819aef53c6f8 linux-3.0/net/irda/irnet/Makefile -f0744a09e98bf5b7c8bfa3e3539096d9 linux-3.0/net/irda/irnet/Kconfig -b68539d506e63a9afe38782a13f03243 linux-3.0/net/irda/irmod.c -abcd5fcdb97b3eb9f8f5462a225dc215 linux-3.0/net/irda/irlmp_frame.c -1674b1528dc5908332f24e64a6383ec1 linux-3.0/net/irda/irlmp_event.c -9fcbaa101c213042373afbb977144990 linux-3.0/net/irda/irlmp.c -04145c2124c141f75c4587ed5c72f8a7 linux-3.0/net/irda/irlap_frame.c -0d989cb541a927fefc8e7c8b31de124e linux-3.0/net/irda/irlap_event.c -8cc412f3f2846f63c5f79dac018979d8 linux-3.0/net/irda/irlap.c -e39a16263fb088bf938c7f78c330a1f5 linux-3.0/net/irda/irlan/irlan_provider_event.c -92d1e54b70b8fadee6e4d477554203ed linux-3.0/net/irda/irlan/irlan_provider.c -97f3e7b70970d7f944972b22ac878660 linux-3.0/net/irda/irlan/irlan_filter.c -858c404211bd782328c1c4efa06c4023 linux-3.0/net/irda/irlan/irlan_event.c -c1799a41d22ebd0cb288a5ace6d9460c linux-3.0/net/irda/irlan/irlan_eth.c -10c482f03a762ac353129ccd5a23ad0b linux-3.0/net/irda/irlan/irlan_common.c -dae99005c76b5b40624fcc30683046af linux-3.0/net/irda/irlan/irlan_client_event.c -7d46222ebde6ac4db18dbd0fdb01a2d2 linux-3.0/net/irda/irlan/irlan_client.c -1565ae77f7cd0a3f3289d4b360cf06a9 linux-3.0/net/irda/irlan/Makefile -54863023f80bf977a3c00fad53150f3a linux-3.0/net/irda/irlan/Kconfig -6dc87d3b9fd0eed0567be4277db390bc linux-3.0/net/irda/irias_object.c -effe5b483e520cfc7bce0e2380128a6a linux-3.0/net/irda/iriap_event.c -41fd454b692e8e2c9d40a6d3272c8959 linux-3.0/net/irda/iriap.c -9dba306f89a5779e96fd70f557576045 linux-3.0/net/irda/irda_device.c -1a5d46aa207af70e753399b5dd1e9cf2 linux-3.0/net/irda/ircomm/ircomm_tty_ioctl.c -01eb556706e8110cad2362654f0efa7b linux-3.0/net/irda/ircomm/ircomm_tty_attach.c -ad51c898274e2bb35778180604c92bf0 linux-3.0/net/irda/ircomm/ircomm_tty.c -ca5efdb010ef374760819e6c2e95fc4d linux-3.0/net/irda/ircomm/ircomm_ttp.c -71058833fa9f69063b89550f59175fd5 linux-3.0/net/irda/ircomm/ircomm_param.c -a4e9341b1d58a537b0a7259397814275 linux-3.0/net/irda/ircomm/ircomm_lmp.c -1cd78406d2adaf8fa159568e2bbdc77b linux-3.0/net/irda/ircomm/ircomm_event.c -8228c34d1bf1f9a71c50e2aaf56e61f6 linux-3.0/net/irda/ircomm/ircomm_core.c -3413ca05a5f7bfb5c69b8a52d7068f05 linux-3.0/net/irda/ircomm/Makefile -5991befcbd98679120f87d7701a86d42 linux-3.0/net/irda/ircomm/Kconfig -ca546288963590c382ec62f25e21fed9 linux-3.0/net/irda/discovery.c -06b55a82f758399eb22fd230e519bbfd linux-3.0/net/irda/af_irda.c -3e7a25527a03725d84367b38715a8f84 linux-3.0/net/irda/Makefile -4ea5adbe31349a0ae90d53fbbe73fe0a linux-3.0/net/irda/Kconfig -4585f9feaa0baa9225ad5a32c83f4168 linux-3.0/net/ipx/sysctl_net_ipx.c -e5d6a13ca1160aab34328892ede59cc6 linux-3.0/net/ipx/ipx_route.c -20266081c10ea28692cd34f56fbffae2 linux-3.0/net/ipx/ipx_proc.c -3cae992b374f81de9388b98a7aa45ca8 linux-3.0/net/ipx/af_ipx.c -e65aac1e1142de6da6196cb693526fdd linux-3.0/net/ipx/Makefile -3c1d617f3637106a20ed86fda90ee603 linux-3.0/net/ipx/Kconfig -c9c29f89df52a7d49c4d186a1462d448 linux-3.0/net/ipv6/xfrm6_tunnel.c -91fc0be28e08b8d763048d82821ffddc linux-3.0/net/ipv6/xfrm6_state.c -fd5e2d43f9c1e07d4ca38f3d3ed15b86 linux-3.0/net/ipv6/xfrm6_policy.c -0c2722d4c5534651b829af03345ca79e linux-3.0/net/ipv6/xfrm6_output.c -c142b97ab351be906832c1abb0ab5883 linux-3.0/net/ipv6/xfrm6_mode_tunnel.c -7d2e4378bfff596249aab7f367e599c7 linux-3.0/net/ipv6/xfrm6_mode_transport.c -2e0d7dfedd88a56eee4a6bd3954ae04e linux-3.0/net/ipv6/xfrm6_mode_ro.c -d8dc224c62603c9f14028c50aaf37f47 linux-3.0/net/ipv6/xfrm6_mode_beet.c -d71b83f8472a554527b390bb73997514 linux-3.0/net/ipv6/xfrm6_input.c -4c056f22ee7510d4b7f24d814756df34 linux-3.0/net/ipv6/udplite.c -f255a94544e1e824c703ed91c3295294 linux-3.0/net/ipv6/udp_impl.h -d34064dd53b7669cde83a7991fbe31ca linux-3.0/net/ipv6/udp.c -60d887e24a57a8af45d7fd8113b7885b linux-3.0/net/ipv6/tunnel6.c -8adbcb100d37891de73f5ed5a100942f linux-3.0/net/ipv6/tcp_ipv6.c -e713f47520c5cb0348871ed20b8e895b linux-3.0/net/ipv6/sysctl_net_ipv6.c -96f0fee2344e46db7a9a64ba4e5142c5 linux-3.0/net/ipv6/syncookies.c -8b4afae4bcf616bf0a54516472182aab linux-3.0/net/ipv6/sit.c -41fdf42287cb9cace510ccbdfd94344d linux-3.0/net/ipv6/route.c -13cd7134b29a48f513ae32226222cb8f linux-3.0/net/ipv6/reassembly.c -2ce5427bb773c961e784ff1dbb511cf9 linux-3.0/net/ipv6/raw.c -466ab555d5b03d06a4e9beaed2fe4b3c linux-3.0/net/ipv6/protocol.c -f04f4d7291fcad33d9e39a03651a54fd linux-3.0/net/ipv6/proc.c -4c4404d37ec5038c552fc81d9c8631a4 linux-3.0/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c -16da28704b9af57e4c59ab3d4da3808c linux-3.0/net/ipv6/netfilter/nf_conntrack_reasm.c -5a9cbbcc276113ee1ccd4e4fb9661fec linux-3.0/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c -5fea7b1496d9f7e891736d4d747551a5 linux-3.0/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c -dfdfe10cbaa846ef62a5f05d9f74e2b7 linux-3.0/net/ipv6/netfilter/ip6table_security.c -abd423bbd08a6339e626116f68ab6395 linux-3.0/net/ipv6/netfilter/ip6table_raw.c -4cc060cc5574f437d2d31ed2d99f53e2 linux-3.0/net/ipv6/netfilter/ip6table_mangle.c -7d1ba857112e1c77a9e4e07e00acc54d linux-3.0/net/ipv6/netfilter/ip6table_filter.c -bb03c89008f24e1e20882af40220f59e linux-3.0/net/ipv6/netfilter/ip6t_rt.c -bc3cf3ad051f2034ef7cec36f770388b linux-3.0/net/ipv6/netfilter/ip6t_mh.c -714630c5a90c6da52d85f8c0bdad1df3 linux-3.0/net/ipv6/netfilter/ip6t_ipv6header.c -6ebcc812c6ea9022d8842f1ced17b8ec linux-3.0/net/ipv6/netfilter/ip6t_hbh.c -6b02b8d2591901c49f7e173a2ac757e3 linux-3.0/net/ipv6/netfilter/ip6t_frag.c -2684725bcd069a9963be92ed47e262f0 linux-3.0/net/ipv6/netfilter/ip6t_eui64.c -254288d0137b8125c4b56fb69163f8e9 linux-3.0/net/ipv6/netfilter/ip6t_ah.c -06cd531668b7238eded691358f832dc1 linux-3.0/net/ipv6/netfilter/ip6t_REJECT.c -1e51d00ef180b1392aa3407c1a2e716f linux-3.0/net/ipv6/netfilter/ip6t_LOG.c -63f5225844b8fad29c5cc2a3d65b69b7 linux-3.0/net/ipv6/netfilter/ip6_tables.c -13651988f604c97e5d4adda44d24934b linux-3.0/net/ipv6/netfilter/ip6_queue.c -431665140f08c2a642918403aa47ae0f linux-3.0/net/ipv6/netfilter/Makefile -4568dd300b104b3131b8a2bbc5859294 linux-3.0/net/ipv6/netfilter/Kconfig -454e405f615dd8c966a902801374eca7 linux-3.0/net/ipv6/netfilter.c -5d011af1182b2bbd666cf2fa3de39dd2 linux-3.0/net/ipv6/ndisc.c -93cf656eff2a78440ae1c120fe4c8fe5 linux-3.0/net/ipv6/mip6.c -60b5853f4e605fc8fdb6e744cf433493 linux-3.0/net/ipv6/mcast.c -791fcf563d3f62264ac7f7e6d35ecc96 linux-3.0/net/ipv6/ipv6_sockglue.c -b985b757d4e45f81671a7410c5a677e2 linux-3.0/net/ipv6/ipcomp6.c -d111aaef57a1961ebae95e943a966986 linux-3.0/net/ipv6/ip6mr.c -b64f396c03c5b07315fc8a7c396a9709 linux-3.0/net/ipv6/ip6_tunnel.c -3d52019c74e5a16f3a9cf53748fa1c61 linux-3.0/net/ipv6/ip6_output.c -be99839038d81fb075118e8075e3ac93 linux-3.0/net/ipv6/ip6_input.c -8fe42433c1a534f40355affa7ed398d3 linux-3.0/net/ipv6/ip6_flowlabel.c -81c8b33a40d4596f0a92e5b07100e2ea linux-3.0/net/ipv6/ip6_fib.c -be1688b4f018384c2a40f1d3998b81d3 linux-3.0/net/ipv6/inet6_hashtables.c -f32f953daf97cf2e8cba868316d4e21d linux-3.0/net/ipv6/inet6_connection_sock.c -05afae57497c2641dc0174eb0d9b44ba linux-3.0/net/ipv6/icmp.c -93415496d6bb0993f33540ce2c035080 linux-3.0/net/ipv6/fib6_rules.c -e20ee187a0a3dc5e50147e08f94204d4 linux-3.0/net/ipv6/exthdrs_core.c -734637253c0630105cde651ef7c1eaa8 linux-3.0/net/ipv6/exthdrs.c -19d79bd41edcebfd24f8a23869d97620 linux-3.0/net/ipv6/esp6.c -e2e8153dab61573d340484091df9a57c linux-3.0/net/ipv6/datagram.c -ffff2e7c8c37d5638abb899159c1e29a linux-3.0/net/ipv6/anycast.c -9e3974397e025f8bd1afe4115eca8821 linux-3.0/net/ipv6/ah6.c -24b69e80a382fdb2587bc38f254e7671 linux-3.0/net/ipv6/af_inet6.c -a97fd05df55966b57500e0025df72e62 linux-3.0/net/ipv6/addrlabel.c -3f2b7922dcd0b0ce313dff9e2aee798f linux-3.0/net/ipv6/addrconf_core.c -36f5d5be4ee5cec817c2ef695b2e84e9 linux-3.0/net/ipv6/addrconf.c -110164cb6564846718c6edbd1d01c5d8 linux-3.0/net/ipv6/Makefile -00675a0b5b597b956eda1dc5667890ba linux-3.0/net/ipv6/Kconfig -021dfff5a3c6d4d0ff5fa44f36508410 linux-3.0/net/ipv4/xfrm4_tunnel.c -3ce8bc80e42fb1d355ad1588473120a1 linux-3.0/net/ipv4/xfrm4_state.c -a6fe1c88796778ae90e0edf1eaf4136b linux-3.0/net/ipv4/xfrm4_policy.c -30287cd93e593275a2d926411fb8091a linux-3.0/net/ipv4/xfrm4_output.c -92d131bd477e95f66bfbe5380af69c4e linux-3.0/net/ipv4/xfrm4_mode_tunnel.c -da1c024ff03b0b9dcaaa28d4c83f400b linux-3.0/net/ipv4/xfrm4_mode_transport.c -469e3ba189182c79ed7fbbfe72761736 linux-3.0/net/ipv4/xfrm4_mode_beet.c -70090e0711a53edd9c15bd90d365f0ba linux-3.0/net/ipv4/xfrm4_input.c -91d9024bd6d6a90fc9bd46fe0d3b7c7a linux-3.0/net/ipv4/udplite.c -3495c6c8f58ec678bdb996330d011f3f linux-3.0/net/ipv4/udp_impl.h -d0fd8e30963af0f3a1eeb0c21c899266 linux-3.0/net/ipv4/udp.c -92c8954e0b9354d60af896f5b5fee10f linux-3.0/net/ipv4/tunnel4.c -c8478243f20691a253a63b5633dbf6ce linux-3.0/net/ipv4/tcp_yeah.c -e6be8016cb40a5bfe23882d862ad1697 linux-3.0/net/ipv4/tcp_westwood.c -b7e53cb262157c557478b904adb12dd6 linux-3.0/net/ipv4/tcp_veno.c -b43e465bbf4703fde11f8ea9479b7456 linux-3.0/net/ipv4/tcp_vegas.h -f8d9be4f7a8c5669ba86f782ef6beac1 linux-3.0/net/ipv4/tcp_vegas.c -0f8012b80c9f0022a277f618d5d97215 linux-3.0/net/ipv4/tcp_timer.c -45ab3eb007477f1f0524152f92be64ec linux-3.0/net/ipv4/tcp_scalable.c -56ddd544efe22dc37fc4056cdb1ab36a linux-3.0/net/ipv4/tcp_probe.c -432d8abcc7be0a7a7dd75a83c485b680 linux-3.0/net/ipv4/tcp_output.c -75b906b62b423b4c6d1567d87a29b980 linux-3.0/net/ipv4/tcp_minisocks.c -070d017499fa4f2eda694e9ce04428de linux-3.0/net/ipv4/tcp_lp.c -43e5bc3f92aa9a65d4a227aa5b0594cb linux-3.0/net/ipv4/tcp_ipv4.c -d5b683a3a7f52af9f71c25fce497ad69 linux-3.0/net/ipv4/tcp_input.c -87310fbc10aef42df3e81f67e8cddfeb linux-3.0/net/ipv4/tcp_illinois.c -43bae4e6420fb3b3624dad44a45b6cbc linux-3.0/net/ipv4/tcp_hybla.c -85b07440600a5c83dc537d26e85aaf9a linux-3.0/net/ipv4/tcp_htcp.c -0d0f13e32dc67a983df59424b6c9011f linux-3.0/net/ipv4/tcp_highspeed.c -c0a7351377b39a8b3380ba8135272147 linux-3.0/net/ipv4/tcp_diag.c -14b3b8a3c9c38cce19f9c7968591d211 linux-3.0/net/ipv4/tcp_cubic.c -631848e7a1401a2af7c163902d2fb923 linux-3.0/net/ipv4/tcp_cong.c -876d13e27f5930341a2a653a1e0f994b linux-3.0/net/ipv4/tcp_bic.c -4216c0cc5a6c4863996f8c31268ae17a linux-3.0/net/ipv4/tcp.c -1c1fa404d5e166b1f04d901a59df591f linux-3.0/net/ipv4/sysctl_net_ipv4.c -da79961120c58723708468eb014d2ec5 linux-3.0/net/ipv4/syncookies.c -bb9679ebc7efcaaf24a924ae84709009 linux-3.0/net/ipv4/route.c -f68aa64877655e6384f3730d3eccc175 linux-3.0/net/ipv4/raw.c -771c21201d8018b6e96e287323bed35b linux-3.0/net/ipv4/protocol.c -5e7368ce7016a61c57c3c5a556486843 linux-3.0/net/ipv4/proc.c -b9f16332819b3eb2523b290c2751cf38 linux-3.0/net/ipv4/ping.c -59af91e5d1695d8a366f4d40c299eac0 linux-3.0/net/ipv4/netfilter/nf_nat_tftp.c -fda126238be0cb015475a04a702739aa linux-3.0/net/ipv4/netfilter/nf_nat_standalone.c -abeb0fd6640a24d0a7976338a6aa1362 linux-3.0/net/ipv4/netfilter/nf_nat_snmp_basic.c -eeb70e46930de58f99efe6f7bede4653 linux-3.0/net/ipv4/netfilter/nf_nat_sip.c -45857f200279debb8acb5655b1a75dd6 linux-3.0/net/ipv4/netfilter/nf_nat_rule.c -c28a2bb9af2a6c14b0f6a284bae23bdc linux-3.0/net/ipv4/netfilter/nf_nat_proto_unknown.c -08835dfb6671709b9640336fa49192ca linux-3.0/net/ipv4/netfilter/nf_nat_proto_udplite.c -beb75faad91d9bba9d414d82ce3d7900 linux-3.0/net/ipv4/netfilter/nf_nat_proto_udp.c -563c28f2299d836445f271b7ad15a353 linux-3.0/net/ipv4/netfilter/nf_nat_proto_tcp.c -afbf3aae054a039bbae2669ce20fd1be linux-3.0/net/ipv4/netfilter/nf_nat_proto_sctp.c -8dc04ffd7ca59e0f8687974471fa627e linux-3.0/net/ipv4/netfilter/nf_nat_proto_icmp.c -f45a3f00d5783cf74cf72320078c5ab9 linux-3.0/net/ipv4/netfilter/nf_nat_proto_gre.c -bceef2018558af5eece0cbc2b436c326 linux-3.0/net/ipv4/netfilter/nf_nat_proto_dccp.c -fc1dcba7318110367ae5d49b760a3332 linux-3.0/net/ipv4/netfilter/nf_nat_proto_common.c -14fdeb525930f7d25d84ae707b7db0e7 linux-3.0/net/ipv4/netfilter/nf_nat_pptp.c -fe62211778c185e138a2b13bdde460cc linux-3.0/net/ipv4/netfilter/nf_nat_irc.c -79eadf0c41ca696157bfeb3e3759eb7b linux-3.0/net/ipv4/netfilter/nf_nat_helper.c -57d6ea37c00a7770a2521996af19d7b0 linux-3.0/net/ipv4/netfilter/nf_nat_h323.c -563ac5aee2abbdae4eec00a970bf0f08 linux-3.0/net/ipv4/netfilter/nf_nat_ftp.c -613b744fecb2da9428eb2620eb5f1678 linux-3.0/net/ipv4/netfilter/nf_nat_core.c -b5b179d5ca264d680a2e084a8ae906dc linux-3.0/net/ipv4/netfilter/nf_nat_amanda.c -15015bc0e24d49e5023c04fb66fcd51f linux-3.0/net/ipv4/netfilter/nf_defrag_ipv4.c -0fd0d394899b35339818abbba3350b80 linux-3.0/net/ipv4/netfilter/nf_conntrack_proto_icmp.c -830241c932b85d1bf22441bed7211c4b linux-3.0/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c -2f2706d9b921f40f217d3d9e2eee3a5f linux-3.0/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c -26cdd708cfb5aa0777afa67797a0f3f7 linux-3.0/net/ipv4/netfilter/iptable_security.c -c52e54ce3a6964017c489f8e2dcda89e linux-3.0/net/ipv4/netfilter/iptable_raw.c -5118f55c3286a50fbcb89fd63b891e04 linux-3.0/net/ipv4/netfilter/iptable_mangle.c -b25929550e65694b3699b5d1faf2fa71 linux-3.0/net/ipv4/netfilter/iptable_filter.c -e4bda7ac957f6fd276477b588e631ef3 linux-3.0/net/ipv4/netfilter/ipt_ecn.c -60ebe21522875ee5cc71c2781a14f570 linux-3.0/net/ipv4/netfilter/ipt_ah.c -b977287eff3ce7c207f8d37098633bfc linux-3.0/net/ipv4/netfilter/ipt_ULOG.c -f475ed47f93d8aeb6347ea5734b2fa27 linux-3.0/net/ipv4/netfilter/ipt_REJECT.c -54fac2fed7b8335835a146bfb7d73a36 linux-3.0/net/ipv4/netfilter/ipt_REDIRECT.c -e47cd111391aee1e232b27424cb99d3b linux-3.0/net/ipv4/netfilter/ipt_NETMAP.c -e5c2819beb938744a70fc925d2a5bc0b linux-3.0/net/ipv4/netfilter/ipt_MASQUERADE.c -0705e3728a82eedaf343d834374e28cc linux-3.0/net/ipv4/netfilter/ipt_LOG.c -a6b7a06ddba351635c0f6ce77ef587a1 linux-3.0/net/ipv4/netfilter/ipt_ECN.c -ee1e5816bfc620a2c4a7ad37c8bd3b02 linux-3.0/net/ipv4/netfilter/ipt_CLUSTERIP.c -77feb9c99c5fd5e6632b88f8e3b94bb7 linux-3.0/net/ipv4/netfilter/ip_tables.c -dc67e82a653d61eb34c66b899622d575 linux-3.0/net/ipv4/netfilter/ip_queue.c -f3cd9425bf64beb5ec8e68e81a2540ae linux-3.0/net/ipv4/netfilter/arptable_filter.c -2453af2b89ebe3e7e952bbd525882651 linux-3.0/net/ipv4/netfilter/arpt_mangle.c -0df08929947f655fe90488041cbcd174 linux-3.0/net/ipv4/netfilter/arp_tables.c -2a901a41b6f38e5f726b1a7cc759f026 linux-3.0/net/ipv4/netfilter/Makefile -f6b0957d3000eb4e420a69e46b2bb484 linux-3.0/net/ipv4/netfilter/Kconfig -25eda752d3b79f42e299702cb97db183 linux-3.0/net/ipv4/netfilter.c -707443f02c795264420372beb62f885f linux-3.0/net/ipv4/ipmr.c -9ddbe8d105a7ed4bc7f573b7eef721a9 linux-3.0/net/ipv4/ipip.c -8d021a1fd0538fd500f45454ef87409e linux-3.0/net/ipv4/ipconfig.c -ac1426073542445b83631717d67f9019 linux-3.0/net/ipv4/ipcomp.c -efa6b9bbbe100031a7d6ed02283a9d59 linux-3.0/net/ipv4/ip_sockglue.c -de861a24c8da8be2a243cb9e80984068 linux-3.0/net/ipv4/ip_output.c -2c3ea1f6c03f1a64b86f458d35843c6c linux-3.0/net/ipv4/ip_options.c -701be438d369e8cad3ead9015fa70f20 linux-3.0/net/ipv4/ip_input.c -e92bbc9f5929fe9d4046ff638b1f0c7a linux-3.0/net/ipv4/ip_gre.c -ce14c854a36d136332ce37dbfd52f3ba linux-3.0/net/ipv4/ip_fragment.c -bd636622bd8c45dd3ea6926f442ce2b3 linux-3.0/net/ipv4/ip_forward.c -63def26907dceeeeeb9c16be34b86a61 linux-3.0/net/ipv4/inetpeer.c -c73ad2dc4b4ac7b7ce3fdf8b65f83046 linux-3.0/net/ipv4/inet_timewait_sock.c -5eb60ff0e18d2560ea5dbad89eb3119a linux-3.0/net/ipv4/inet_lro.c -f6b7a0677af81449d304005d3ca1d134 linux-3.0/net/ipv4/inet_hashtables.c -4020ce52f127c8912f01f25b270cb3ef linux-3.0/net/ipv4/inet_fragment.c -526fa8a744209c9cb3e6286bc8df2b66 linux-3.0/net/ipv4/inet_diag.c -cf7a636df0b48d7634db07d53cd20cf5 linux-3.0/net/ipv4/inet_connection_sock.c -eca46dde39090b39e270235cbfc4177c linux-3.0/net/ipv4/igmp.c -84d07998211e24b90e7bb6368d0ae6c9 linux-3.0/net/ipv4/icmp.c -313d0d88cd94febf79ba0b62f249a1bc linux-3.0/net/ipv4/gre.c -c0e6d97b886f71512221f0ff6555c160 linux-3.0/net/ipv4/fib_trie.c -b814d73cd427f7aeecdc0d5ecc98b43b linux-3.0/net/ipv4/fib_semantics.c -850af1ca7baa4c45b9ad8cbf0106fd9c linux-3.0/net/ipv4/fib_rules.c -9285680ef9fa079be8f75a6e052d8037 linux-3.0/net/ipv4/fib_lookup.h -3d145df42e6667e4ac40dbec195ebcb5 linux-3.0/net/ipv4/fib_frontend.c -29f565b46258c44cc9867c4e96ea800a linux-3.0/net/ipv4/esp4.c -94cfc3124534b2562a6b12ed19a09b91 linux-3.0/net/ipv4/devinet.c -93d00b49ca33e4ef678b07ad660e8a44 linux-3.0/net/ipv4/datagram.c -18f6ceaffc6271ea47adcc04800ada6e linux-3.0/net/ipv4/cipso_ipv4.c -83d11ced66b1ddcd47564beed6d307db linux-3.0/net/ipv4/arp.c -61f663ec1012f98e1de4d9e9503fe8bc linux-3.0/net/ipv4/ah4.c -e19a50c2e913630b929c7b69752f69a8 linux-3.0/net/ipv4/af_inet.c -c5362e2699252676130c733d4aa45b36 linux-3.0/net/ipv4/Makefile -0f75ca4fed0dbb7043bc74a4b34959bf linux-3.0/net/ipv4/Kconfig -8cc471dd0a5153a39a5b24dcc34d22a6 linux-3.0/net/ieee802154/wpan-class.c -d25f13ad1d95da3c7c89c0f60e64757a linux-3.0/net/ieee802154/raw.c -f6ce6e76ae8cf8e56fb758a28b07bb6c linux-3.0/net/ieee802154/nl_policy.c -741f30c3679d65c9d642dffb79211408 linux-3.0/net/ieee802154/nl-phy.c -2b1a36e9015a3fb9e3681e05dbe68ec0 linux-3.0/net/ieee802154/nl-mac.c -a1e24e24de8ca5a8320682f259066f50 linux-3.0/net/ieee802154/netlink.c -43cc6a26c14fd62d4df0de81ed4bcd75 linux-3.0/net/ieee802154/ieee802154.h -9a9e3867b3706132745e476200529b8c linux-3.0/net/ieee802154/dgram.c -e3991d7406a341b9a7e05e9fcb05cbdc linux-3.0/net/ieee802154/af_ieee802154.c -a4daaae92491b75c99b9dad291d845f5 linux-3.0/net/ieee802154/af802154.h -65c8a50128876c2636ea773dc36eb177 linux-3.0/net/ieee802154/Makefile -9c192f108e7d91cc90e63ba8fa766708 linux-3.0/net/ieee802154/Kconfig -d80e0788d51bf321a8c92fa6e5e0c56e linux-3.0/net/ethernet/pe2.c -16c44f7b9b98c1026ef23ca33d646075 linux-3.0/net/ethernet/eth.c -a4afc87bfc40ba5e17e0e133f3160bb7 linux-3.0/net/ethernet/Makefile -f73400b3e22a81d4336eafe0ac912b3b linux-3.0/net/econet/af_econet.c -bc3db6f5544fa1c3b6792f88fb086cd4 linux-3.0/net/econet/Makefile -ce42d78a91994a40fb760e314592ce0d linux-3.0/net/econet/Kconfig -2949c8ebd92282722e73be4c3b2ff39e linux-3.0/net/dsa/tag_trailer.c -162305abc4880e1eb43663e9ff3ed6ae linux-3.0/net/dsa/tag_edsa.c -c5a7a353975a240ade1ef3f49a279f29 linux-3.0/net/dsa/tag_dsa.c -f84c08a59d09a735ec5192aa364b1a03 linux-3.0/net/dsa/slave.c -87a27c79bf11b0246f6bfbba34b038f7 linux-3.0/net/dsa/mv88e6xxx.h -f8f0aabd62fff4a12386f0ddd06a6003 linux-3.0/net/dsa/mv88e6xxx.c -d03934bf2f03f07e431ca2a0408fa1d4 linux-3.0/net/dsa/mv88e6131.c -dbddb839f366d7ee1e5eec378b8dab5d linux-3.0/net/dsa/mv88e6123_61_65.c -a70e366b33bd06e231e808ee08ef2ec0 linux-3.0/net/dsa/mv88e6060.c -331dcf999a0daccad60ab6eade71763b linux-3.0/net/dsa/dsa_priv.h -5c16283acc6e2817443a1fd288bab323 linux-3.0/net/dsa/dsa.c -b2f54aeb0efd88e02577924aa450dda0 linux-3.0/net/dsa/Makefile -e2f2fd70240466d6b52f023521dc8acf linux-3.0/net/dsa/Kconfig -c1c3da888314f5d9384dbf46f23d8148 linux-3.0/net/dns_resolver/internal.h -a50291cc7b42a77db7fcf7a219e244d6 linux-3.0/net/dns_resolver/dns_query.c -01fa3ce0457dc924a22bb839fa49b42f linux-3.0/net/dns_resolver/dns_key.c -338f58f3ee3387723b3c2d14656fdf92 linux-3.0/net/dns_resolver/Makefile -dd2fb428c2d9fcf597cd6b12fc7566f3 linux-3.0/net/dns_resolver/Kconfig -a3a6a84c3293b0632aa1d6344aa7297d linux-3.0/net/decnet/sysctl_net_decnet.c -8633d4f190423ba8506bd99d23338b60 linux-3.0/net/decnet/netfilter/dn_rtmsg.c -e9de586f0e9640dd0954a95d82d8bc72 linux-3.0/net/decnet/netfilter/Makefile -22f12fd4ed0e519f0393d4eed4b4d330 linux-3.0/net/decnet/netfilter/Kconfig -f08c24e46943aefa7b4e10321da70e17 linux-3.0/net/decnet/dn_timer.c -1960ab458baf9ee06aec1c833dd7c7ad linux-3.0/net/decnet/dn_table.c -2e8df5b3d400f85a3965af49aa49c593 linux-3.0/net/decnet/dn_rules.c -8c8cdfd06e25bbd73cf3a13d31d8a1b9 linux-3.0/net/decnet/dn_route.c -dd01e6684a7b7caa44557f9831089b7c linux-3.0/net/decnet/dn_nsp_out.c -b602364e1a9a184fa8e194a13f4dbbff linux-3.0/net/decnet/dn_nsp_in.c -883ede1e92aa9160ee3892af0ac988a3 linux-3.0/net/decnet/dn_neigh.c -0427d3c877abbe3391936522bd5f6d4a linux-3.0/net/decnet/dn_fib.c -81cc3404736ed6b538beb8e33933da2f linux-3.0/net/decnet/dn_dev.c -3c3f1b1dcf27bb30b94a6cb9c409a1cb linux-3.0/net/decnet/af_decnet.c -a7f38077b97ce2140b0ac891cd5bd727 linux-3.0/net/decnet/TODO -af8c51138d29f9a97ff1045808d710b4 linux-3.0/net/decnet/README -d1a6ecef5eee0a312a4fb7b1d3f74737 linux-3.0/net/decnet/Makefile -d26ac44d57f60a42d8f9000b20eacbab linux-3.0/net/decnet/Kconfig -de02047a7786e933d416faa66c01b412 linux-3.0/net/dccp/timer.c -15cf03571a18fa9dfdc9797bbabe3958 linux-3.0/net/dccp/sysctl.c -b435e548b2afa47b5b594d1aa86ba9b4 linux-3.0/net/dccp/qpolicy.c -b93545e12259bbca93598ddcbb4b18e2 linux-3.0/net/dccp/proto.c -89412fe30a67ae124e2daa213b5063fe linux-3.0/net/dccp/probe.c -5d70c1d7d629b3b6c5a6c24149f2fce3 linux-3.0/net/dccp/output.c -78b67f1abd6affaa88a59a97f2d66f11 linux-3.0/net/dccp/options.c -aec20792bf116c234779c483b1185c37 linux-3.0/net/dccp/minisocks.c -751649899e6cf7f28cb653daec73f2ed linux-3.0/net/dccp/ipv6.h -abb2ca4e6121c8e0a35f0d9fddaa8849 linux-3.0/net/dccp/ipv6.c -0e465c6a132cc80df3091f70ab46127d linux-3.0/net/dccp/ipv4.c -c7ff309992bb778cc21b897bb8056f0b linux-3.0/net/dccp/input.c -53dd0b317c14b37377440827e7f0f0db linux-3.0/net/dccp/feat.h -aa494435ba4191f88ac77611eb628c6d linux-3.0/net/dccp/feat.c -c70e00708e02a957930a1521574ef5b6 linux-3.0/net/dccp/diag.c -41619382d45d04f62d78be27bff09d5f linux-3.0/net/dccp/dccp.h -d7de5aab256e330147feec4c2dd8ecde linux-3.0/net/dccp/ccids/lib/tfrc_equation.c -7898c8ad84193fc3020c139547c6aa6a linux-3.0/net/dccp/ccids/lib/tfrc.h -e91a31c5c2b0f4e21353a59376708586 linux-3.0/net/dccp/ccids/lib/tfrc.c -cc8f2bc99503a40d8af42d32a0ef6351 linux-3.0/net/dccp/ccids/lib/packet_history.h -45f759eec0e5093d24a4dfbdf729227c linux-3.0/net/dccp/ccids/lib/packet_history.c -b219334138c7ff22e85f7f54892ec621 linux-3.0/net/dccp/ccids/lib/loss_interval.h -8843a1f21c526c4c0ae3dd446eecc870 linux-3.0/net/dccp/ccids/lib/loss_interval.c -ecb11e0c4282a141354ae5f552e29760 linux-3.0/net/dccp/ccids/ccid3.h -2333b7ea3a47f1e1e6b475e3ebf03514 linux-3.0/net/dccp/ccids/ccid3.c -1ae14c1da03a5c2a1138d0fab2f85edf linux-3.0/net/dccp/ccids/ccid2.h -43ef0a365a4e52c62237d035fd9328b7 linux-3.0/net/dccp/ccids/ccid2.c -7f8021372189bfacb3d62e6b6eecc0c9 linux-3.0/net/dccp/ccids/Kconfig -573d715b5b0e93efef49cc9058c7342a linux-3.0/net/dccp/ccid.h -b6a7d265a28e7d9c4b869c0aa82983f0 linux-3.0/net/dccp/ccid.c -598591b85c379fc4730eb9de1d8ba928 linux-3.0/net/dccp/ackvec.h -4fb64f32662a35210034d06dc4f59490 linux-3.0/net/dccp/ackvec.c -1f33ea03379e06d2ae67f8849a61704a linux-3.0/net/dccp/Makefile -b7d063cba580ef5b778d6ed9d8562d5f linux-3.0/net/dccp/Kconfig -647f85de2fb53abac90cb4063027e623 linux-3.0/net/dcb/dcbnl.c -a74408e3de09d2c620ebdc2838a2fced linux-3.0/net/dcb/dcbevent.c -1dd8c18d90a452f49ae74fe38c822e91 linux-3.0/net/dcb/Makefile -a1a763b65a79a485b6dcbdeca39cde78 linux-3.0/net/dcb/Kconfig -69c42d8eec54aed143cea60413bc70dc linux-3.0/net/core/utils.c -da75af22078038da228d4dd7e4f3158e linux-3.0/net/core/user_dma.c -06db2ee322ecde2c2353c7bb775f33d1 linux-3.0/net/core/timestamping.c -b89ccfb8e9c39652b359d4dbd74e857c linux-3.0/net/core/sysctl_net_core.c -dedaea6c14d3eaff02794f3813c3c046 linux-3.0/net/core/stream.c -8639402157a31f5d132f1e22ca351fa6 linux-3.0/net/core/sock.c -d435237bc8dbe68d10ba09509acea9e4 linux-3.0/net/core/skbuff.c -847e0f604961e37d6fbc98a0042fff2b linux-3.0/net/core/scm.c -8f8ed04530e424b2a7087b213f218f35 linux-3.0/net/core/rtnetlink.c -96bb42298314b03ae94f6fc38608b09f linux-3.0/net/core/request_sock.c -d52e5f3e90b1cee0d85c6e47fe1e6da6 linux-3.0/net/core/pktgen.c -341e4cd6ae1ee6623fdeab268a911ce3 linux-3.0/net/core/netpoll.c -f3fc17240c61fd35dd6cfbca954a5224 linux-3.0/net/core/netevent.c -540c9ca429b0a8eae6fa98f434fbcba2 linux-3.0/net/core/net_namespace.c -356e9dfa91a060a89fb2fb3140784e26 linux-3.0/net/core/net-traces.c -b34fc663e068b240d20b014bec41759d linux-3.0/net/core/net-sysfs.h -29ca3d2d5d9070cc44e462a9fa87cda2 linux-3.0/net/core/net-sysfs.c -a262a4b348e340938f4c14dcb9f4296e linux-3.0/net/core/neighbour.c -8691858e23d90505a602c445c8397ac8 linux-3.0/net/core/link_watch.c -dd4f4f93c1ab135f2d31314d41b1c373 linux-3.0/net/core/kmap_skb.h -3bf8c4f08983c768516ac5587383c683 linux-3.0/net/core/iovec.c -3c81951139cdadfd25ed9d5640f1e69e linux-3.0/net/core/gen_stats.c -a4574bad6b1ce9117d86df82363bad4b linux-3.0/net/core/gen_estimator.c -6e0fa6518cb30d7952195aaf272234d2 linux-3.0/net/core/flow.c -61a80ff78a05fb6985e1334d65cc4143 linux-3.0/net/core/filter.c -8cd7563335a6fd8c4603f47c5d3f8151 linux-3.0/net/core/fib_rules.c -3aa8f72d8415af9f45904be4969af728 linux-3.0/net/core/ethtool.c -bc70d24f5582c275a872e146fedc41ad linux-3.0/net/core/dst.c -324a1f98c8af115168c232f4d6a9b97d linux-3.0/net/core/drop_monitor.c -e290bbc0e731e0b5cba7f3d55eea121b linux-3.0/net/core/dev_addr_lists.c -cfabdb18c927e97abe60b411867e4dcc linux-3.0/net/core/dev.c -88e08bcd10e72f7a3442ff96424f9b3a linux-3.0/net/core/datagram.c -e55b7be7b4726be5aaa0e12c6a711805 linux-3.0/net/core/Makefile -39b636c8b008d5e14e61e3924a0bf29e linux-3.0/net/compat.c -cd37d1a7ff81e43ca999feaa273669e7 linux-3.0/net/ceph/pagevec.c -7047556693ec045644289becaa07162f linux-3.0/net/ceph/pagelist.c -aab59dffbe852619214caeddf4f0f554 linux-3.0/net/ceph/osdmap.c -d18ca6abebd6f8dd93e949bf642e813b linux-3.0/net/ceph/osd_client.c -3d886599199a88db90a5821a6e2d0360 linux-3.0/net/ceph/msgpool.c -5ce8a2891eb73231c39aa460edf50261 linux-3.0/net/ceph/mon_client.c -f5497c580b867f4f6490cd4d2626c0d9 linux-3.0/net/ceph/messenger.c -a8d493d5c2d9ab00646080d3a15bb419 linux-3.0/net/ceph/debugfs.c -2c328761faa738f19dd60c0a337bf352 linux-3.0/net/ceph/crypto.h -bddd994cecb8c7452ff08682c8a82ce4 linux-3.0/net/ceph/crypto.c -16797d893e3518b486706664c5a44e78 linux-3.0/net/ceph/crush/mapper.c -3441c106e3a69eefc9d19a004c552685 linux-3.0/net/ceph/crush/hash.c -3215b3eb78ae758aa83a64dcb7ee6b0c linux-3.0/net/ceph/crush/crush.c -254a81b6ab448d641625ef1ffec70512 linux-3.0/net/ceph/ceph_strings.c -d749436a04bfb1207c5eb4e68b471488 linux-3.0/net/ceph/ceph_hash.c -2e6b964972031e05cc538c592a079828 linux-3.0/net/ceph/ceph_fs.c -903ef382d3ec66ccf4233870e3699884 linux-3.0/net/ceph/ceph_common.c -800bc489cdb58cce1af621d824dd1b38 linux-3.0/net/ceph/buffer.c -d2266b7e898f0ee0887b4121cedcb557 linux-3.0/net/ceph/auth_x_protocol.h -1e1d770a782f2088289ada905fa2640b linux-3.0/net/ceph/auth_x.h -5f154739f087b0aabbe778980c9fe160 linux-3.0/net/ceph/auth_x.c -69d17cc7d297dd3ac7f24d217b4b3d8e linux-3.0/net/ceph/auth_none.h -95bf7fc22ff4c8a55b44617588887a45 linux-3.0/net/ceph/auth_none.c -8fc08e513b6340775920bf52a3f78e22 linux-3.0/net/ceph/auth.c -b7ed4e42177207e22756a8f18ba26c3e linux-3.0/net/ceph/armor.c -45a121d29de09687f1e27a6c794bf4ad linux-3.0/net/ceph/Makefile -86322ff0fe4b4336b71894b6d20b3126 linux-3.0/net/ceph/Kconfig -da6a7cdcdb3cf13e940f1185f1d7e4d2 linux-3.0/net/can/raw.c -890d259250ac8a1590401b1de3b5c7d3 linux-3.0/net/can/proc.c -ac02e09e4e66954791751d54b26217f1 linux-3.0/net/can/bcm.c -202d263eb4632dab02733ee42534ee61 linux-3.0/net/can/af_can.h -617ac14c07e3b3f89f69617311a3f333 linux-3.0/net/can/af_can.c -423bbe9e21e86bbe5ff9b90c1532da0e linux-3.0/net/can/Makefile -d50fb1166cd558299fe5022985d79343 linux-3.0/net/can/Kconfig -7ffa83c303b3cca862666c176cf904de linux-3.0/net/caif/chnl_net.c -5632a55556af53f361a706d6c6cddfdd linux-3.0/net/caif/cfvidl.c -74cb05336fdbc403f67502901d0cfab5 linux-3.0/net/caif/cfveil.c -76fa5950755193c7077640b5706ac6c8 linux-3.0/net/caif/cfutill.c -7a5412d9b0c965de798fbdfa0e6faa87 linux-3.0/net/caif/cfsrvl.c -3206432f122ff273df0fc49fdf047cf3 linux-3.0/net/caif/cfserl.c -6dce6faed08fa4240a6cc59d802fb3ab linux-3.0/net/caif/cfrfml.c -20425270c8450921f098de9bb9488f69 linux-3.0/net/caif/cfpkt_skbuff.c -81a0aee08df4e8b8f57bbd0ddb96574b linux-3.0/net/caif/cfmuxl.c -f5b8669697564cfa14717e9826c73cf3 linux-3.0/net/caif/cffrml.c -25d6aaff6294cd244ef39dfc5b95c284 linux-3.0/net/caif/cfdgml.c -691d7702941d1d24892e879b8dfca899 linux-3.0/net/caif/cfdbgl.c -6e4dfcedb5bd68d4d702f06a7be29c89 linux-3.0/net/caif/cfctrl.c -bef7716bfd596adec22e589ef9115d50 linux-3.0/net/caif/cfcnfg.c -3cde7d741ff00e1ea85c842770e09cd7 linux-3.0/net/caif/caif_socket.c -d9447a57c32fba2d4436bc714f59597e linux-3.0/net/caif/caif_dev.c -0cb873dfc46325ff80c8b10f499eb3aa linux-3.0/net/caif/Makefile -9b93e7e167b3730bb59bcb31bee629d0 linux-3.0/net/caif/Kconfig -11a7f46b9ad7bae9f2b72c8bae3d48d4 linux-3.0/net/bridge/netfilter/ebtables.c -9974e62859917d8099a6b5fc2833d141 linux-3.0/net/bridge/netfilter/ebtable_nat.c -24d6c416111fdd4b2b9d3b15a601716e linux-3.0/net/bridge/netfilter/ebtable_filter.c -c551bb0acd810f7f4d0d4c1f1e809b7d linux-3.0/net/bridge/netfilter/ebtable_broute.c -0fc2c577ed5a1236347217e8ff7aef1b linux-3.0/net/bridge/netfilter/ebt_vlan.c -816642775f31757025b3eb87ec95e928 linux-3.0/net/bridge/netfilter/ebt_ulog.c -00c83ca6b08c7e360124aff8bc1004a2 linux-3.0/net/bridge/netfilter/ebt_stp.c -52e93400dcb0d17b3da35d0f62532e08 linux-3.0/net/bridge/netfilter/ebt_snat.c -6bf93fa8622b3c28a54bea13c7ade57c linux-3.0/net/bridge/netfilter/ebt_redirect.c -890a6732591be7b79e122d43e39ef103 linux-3.0/net/bridge/netfilter/ebt_pkttype.c -ed6c3715ad3f96c3b64839bfe64d12b3 linux-3.0/net/bridge/netfilter/ebt_nflog.c -5c33ff55cafd08ed57f5990049efea94 linux-3.0/net/bridge/netfilter/ebt_mark_m.c -36687804f2456b3082d7207cc6039737 linux-3.0/net/bridge/netfilter/ebt_mark.c -ef4b0c1696a04a539d066bc243c500e3 linux-3.0/net/bridge/netfilter/ebt_log.c -e3c10e9478428f8e0fcac57d9a831299 linux-3.0/net/bridge/netfilter/ebt_limit.c -632546e2ae26fec329956becf35352ae linux-3.0/net/bridge/netfilter/ebt_ip6.c -73d2c99addda9312f95ccd9aebe1af6b linux-3.0/net/bridge/netfilter/ebt_ip.c -b77bb651f8cd02a4e59e0d6071b8c67e linux-3.0/net/bridge/netfilter/ebt_dnat.c -be86a44ed191113858f4fcf801b8c8bf linux-3.0/net/bridge/netfilter/ebt_arpreply.c -0883ffb30e02238fe2f6da7fea5ce0e6 linux-3.0/net/bridge/netfilter/ebt_arp.c -8705c3a05251316a204942aad7cf7561 linux-3.0/net/bridge/netfilter/ebt_among.c -9f36922c299ccb4614e633306b478ff1 linux-3.0/net/bridge/netfilter/ebt_802_3.c -729be4b08152646c32e95d73c7d59adc linux-3.0/net/bridge/netfilter/Makefile -cce4b6ae1458eb5dcada48f3e0a5ef17 linux-3.0/net/bridge/netfilter/Kconfig -bc9a196e8d242429cf15323ec354a831 linux-3.0/net/bridge/br_sysfs_if.c -57f8da7ae69045413a7271e710bf2f31 linux-3.0/net/bridge/br_sysfs_br.c -699cde6bc619b7a2a958a252b7ee72d5 linux-3.0/net/bridge/br_stp_timer.c -53aee3b08321cdb9b013c600dbde5b72 linux-3.0/net/bridge/br_stp_if.c -fed90c9fc06e3079405a93ad619358a2 linux-3.0/net/bridge/br_stp_bpdu.c -e5605021dc8f48e67c6e8790c89d2722 linux-3.0/net/bridge/br_stp.c -b57bb33ea363bb4ea094cb6f60fc875c linux-3.0/net/bridge/br_private_stp.h -b30a4467d7f936427c0ce38461d43b28 linux-3.0/net/bridge/br_private.h -551e9a593cf35d2c85c45c162890bbf4 linux-3.0/net/bridge/br_notify.c -d82062b8c291e4f7603fc60561fa2934 linux-3.0/net/bridge/br_netlink.c -a7440045a1c37b9f87845bbdf5a61ef1 linux-3.0/net/bridge/br_netfilter.c -5ea1e24ee3cb1d9a518452c24e0080b6 linux-3.0/net/bridge/br_multicast.c -912a93ef2803632f4fdc876861a5be3d linux-3.0/net/bridge/br_ioctl.c -b7d12621edb3ad3639c225b4ad4345e5 linux-3.0/net/bridge/br_input.c -3f65137aac6b8ad5209588b985c124b1 linux-3.0/net/bridge/br_if.c -4aff23816fc93b6628769af7e3281e02 linux-3.0/net/bridge/br_forward.c -1237ea37c87c92ad4d97c0e018f0a692 linux-3.0/net/bridge/br_fdb.c -11839134fe5fb5c9ab115302c1e1860a linux-3.0/net/bridge/br_device.c -df34480578a37c7a7119c1389eadc65c linux-3.0/net/bridge/br.c -517382ce67030b2d3510c2b76423273a linux-3.0/net/bridge/Makefile -238b3e7a5e82ec98a773b857f389ab9e linux-3.0/net/bridge/Kconfig -64efcf58768c4b909442cb8a30442dc9 linux-3.0/net/bluetooth/sco.c -e5fb2011811b3e6d596c19aa726bdc37 linux-3.0/net/bluetooth/rfcomm/tty.c -84687ee5a36713c904ccb6b626a59afe linux-3.0/net/bluetooth/rfcomm/sock.c -de2101db68d5a44a8b3f14c05608292f linux-3.0/net/bluetooth/rfcomm/core.c -426fe95248ac5a2db4649734449e17ae linux-3.0/net/bluetooth/rfcomm/Makefile -b4dbe51f420c8e424557403a1fc10dfa linux-3.0/net/bluetooth/rfcomm/Kconfig -0c097c1e217dd9485db4bd190b65a253 linux-3.0/net/bluetooth/mgmt.c -c3e2e91434481a6ed13a17e6d59eaa30 linux-3.0/net/bluetooth/lib.c -4c1e7737618b3ab020dd6cfeca19f298 linux-3.0/net/bluetooth/l2cap_sock.c -d12410770aa081208d6d8235633973f6 linux-3.0/net/bluetooth/l2cap_core.c -cdd2e03d2262b4a1279cfab1b7144296 linux-3.0/net/bluetooth/hidp/sock.c -90ccf6b27306e858db091f8298b4a0a4 linux-3.0/net/bluetooth/hidp/hidp.h -12bb3a378ca661ddd55acd709a165e2e linux-3.0/net/bluetooth/hidp/core.c -c6886e70ac71ae8b097edc6d20feac0e linux-3.0/net/bluetooth/hidp/Makefile -8a34279ad732fdf8ed87f3e8fe072d1e linux-3.0/net/bluetooth/hidp/Kconfig -fe45c5832aa72638d83bf0402b772efa linux-3.0/net/bluetooth/hci_sysfs.c -415007e00c6ef3f40cffb4ae363a8f20 linux-3.0/net/bluetooth/hci_sock.c -11787b94d47fb741bb05cf438cd60d62 linux-3.0/net/bluetooth/hci_event.c -b469020dab9da761d3ae23f338ac7010 linux-3.0/net/bluetooth/hci_core.c -7b146811d43f2a13dd1a30d26d10f93c linux-3.0/net/bluetooth/hci_conn.c -ecc3deb87a5ef82d748f817e2002c063 linux-3.0/net/bluetooth/cmtp/sock.c -baad7e50eaa273f1d02a7096e5879a9c linux-3.0/net/bluetooth/cmtp/core.c -241c09d4652245eaa06ef177d5cdb564 linux-3.0/net/bluetooth/cmtp/cmtp.h -567d5fa2a8691c14e4c7294e5d904e57 linux-3.0/net/bluetooth/cmtp/capi.c -390a2e3252f5180a6669937de657802f linux-3.0/net/bluetooth/cmtp/Makefile -f09bcae13276db151b9b5fad63c0109b linux-3.0/net/bluetooth/cmtp/Kconfig -fdb0d9c5fb07c41a6c181a40d7cf7929 linux-3.0/net/bluetooth/bnep/sock.c -a61047584fa88520d63c300c51148f1a linux-3.0/net/bluetooth/bnep/netdev.c -6b7d27b87c68efebb6fc37e60eb4e2b1 linux-3.0/net/bluetooth/bnep/core.c -589fcd7fe961305596cd0a8ce97558dd linux-3.0/net/bluetooth/bnep/bnep.h -0d7c1b5816c59d7510d81036d238bffd linux-3.0/net/bluetooth/bnep/Makefile -296b8994ee3307cc55b776b32f69531f linux-3.0/net/bluetooth/bnep/Kconfig -2e466d6de7f8c7f345822ca9315db932 linux-3.0/net/bluetooth/af_bluetooth.c -bc38f4ec39869554567c9e6ab470ff4a linux-3.0/net/bluetooth/Makefile -9e7bb9e7afe0bccda3a381de6a5881e1 linux-3.0/net/bluetooth/Kconfig -210b5a68bda4bb561ac1872960e87513 linux-3.0/net/batman-adv/vis.h -f2cd19df3001374343cae1d90332a4a4 linux-3.0/net/batman-adv/vis.c -5ec5faf7345a96d8bb47c8155d5d321e linux-3.0/net/batman-adv/unicast.h -4d81bbb9435c3a4a3e019e35b719be56 linux-3.0/net/batman-adv/unicast.c -5cf31d7818bb45897557aeb85cc0d214 linux-3.0/net/batman-adv/types.h -6a07e5fe0b00398f7dd526fdda78d113 linux-3.0/net/batman-adv/translation-table.h -5b18badc5a8de66929182202fcd150a8 linux-3.0/net/batman-adv/translation-table.c -9bf55484b86979489046ac4cf914b7bb linux-3.0/net/batman-adv/soft-interface.h -d5e51c4d3f722dc608097c463f3eb4e6 linux-3.0/net/batman-adv/soft-interface.c -11654d9ffc0f048e9d366406ee42454e linux-3.0/net/batman-adv/send.h -1be3cedfd2367f68e9e299dc1e46e1bb linux-3.0/net/batman-adv/send.c -06393bd4568ee850e5b9f8cddbb48520 linux-3.0/net/batman-adv/routing.h -f8df1ee5e6551a59d5e46fea77837e86 linux-3.0/net/batman-adv/routing.c -d312edbb84ffff59f88a3422bb3a8842 linux-3.0/net/batman-adv/ring_buffer.h -cafba747c206d5d987dc9cad773815c5 linux-3.0/net/batman-adv/ring_buffer.c -50c3d095c9117e96e670f4d8f29edfa1 linux-3.0/net/batman-adv/packet.h -5f6cecd692322c14200e7c10a2bd0718 linux-3.0/net/batman-adv/originator.h -a4ddb9fe41ec8582e2828a0338a31220 linux-3.0/net/batman-adv/originator.c -c35090b8574cbe9ded8a6acfca8261fe linux-3.0/net/batman-adv/main.h -10e8c5f5e7ec0dac7a7eef3fec4d09e9 linux-3.0/net/batman-adv/main.c -9460cafd789164072b218856cfae5320 linux-3.0/net/batman-adv/icmp_socket.h -90885cafcc44f6244820abe7c4c0c8f2 linux-3.0/net/batman-adv/icmp_socket.c -316bef6a7aef20711cfd46d3675eacb1 linux-3.0/net/batman-adv/hash.h -a25c5aa447c329e67a504ec23ed09fb2 linux-3.0/net/batman-adv/hash.c -13613ff64ee74116acbcdeb06ae4c382 linux-3.0/net/batman-adv/hard-interface.h -06809aab6b7b429b96fb2e40e04ab898 linux-3.0/net/batman-adv/hard-interface.c -c58217c58d5299aa3f566480a93c2300 linux-3.0/net/batman-adv/gateway_common.h -711f98df72431e1c1c243263bcd09252 linux-3.0/net/batman-adv/gateway_common.c -9f3a0938ed8a01758da77a38208cfefb linux-3.0/net/batman-adv/gateway_client.h -f62ad4db684c3c154efea858d6c197e8 linux-3.0/net/batman-adv/gateway_client.c -467e5a5d9a7a9f0129d8afbe8e08c7f5 linux-3.0/net/batman-adv/bitarray.h -bc8dc0371df7aa648f2692a8b298be9d linux-3.0/net/batman-adv/bitarray.c -2098298b2cd490f62af19c57f10f75da linux-3.0/net/batman-adv/bat_sysfs.h -22830d1873c316c4ad5635503475f6d6 linux-3.0/net/batman-adv/bat_sysfs.c -790a268f6e4c0f2cfe7fb999675cd510 linux-3.0/net/batman-adv/bat_debugfs.h -04709ad4595ac1b37e6e92971d36ee98 linux-3.0/net/batman-adv/bat_debugfs.c -91f48876362dbebd88ffd533306d1a39 linux-3.0/net/batman-adv/aggregation.h -67bcad144d658dd6baff144a7861e413 linux-3.0/net/batman-adv/aggregation.c -5051dc0c815cb01f8bbd5c71600de01a linux-3.0/net/batman-adv/Makefile -f4546d007976cf3fe020ee2b667dd9e9 linux-3.0/net/batman-adv/Kconfig -c8bece26f28e5ba87aa10a16a7dea1be linux-3.0/net/ax25/sysctl_net_ax25.c -a2c311b0d4917a0f43a44b911502755e linux-3.0/net/ax25/ax25_uid.c -b4a31bf88cc4a1aeaeca7d279aaee697 linux-3.0/net/ax25/ax25_timer.c -15095819973e8e67a778056a69c07783 linux-3.0/net/ax25/ax25_subr.c -75e11bbd8596bc265928195d166a8c44 linux-3.0/net/ax25/ax25_std_timer.c -460d94f92e71f3317b5bbaac6d0520b1 linux-3.0/net/ax25/ax25_std_subr.c -3ce1ed1822a67f7b50d6257907d8f2ad linux-3.0/net/ax25/ax25_std_in.c -5541b0cf1faeeb5d6d20a1599abb6099 linux-3.0/net/ax25/ax25_route.c -5f00c042c81ab352d518212dba019357 linux-3.0/net/ax25/ax25_out.c -70163a74ff7c8d68fbc9bfa752a98090 linux-3.0/net/ax25/ax25_ip.c -95c7a228e945f9f42d5d8f05ffc31f35 linux-3.0/net/ax25/ax25_in.c -13dfaac2684fc66173cd752c28fbc27c linux-3.0/net/ax25/ax25_iface.c -c2b485e0db514c480269be12ce7fcac1 linux-3.0/net/ax25/ax25_ds_timer.c -d2a393d2077071c7273af6d81ddb2574 linux-3.0/net/ax25/ax25_ds_subr.c -a2fc73ad978ff3fb3df5a78612f983d2 linux-3.0/net/ax25/ax25_ds_in.c -103db776c290c506efb9b8c45f7276a3 linux-3.0/net/ax25/ax25_dev.c -03c7779266147f0ee15c0e1a26ddd71f linux-3.0/net/ax25/ax25_addr.c -ece1e95931264b165412fe3b94610bd5 linux-3.0/net/ax25/af_ax25.c -48a71091572666ff81f062ce6761f456 linux-3.0/net/ax25/TODO -b2208b5bda15dc5ffb9414caf3fe820e linux-3.0/net/ax25/Makefile -c5feb147ba79df7096afe933a2e07272 linux-3.0/net/ax25/Kconfig -efeb4f1cb489ec8a4717a9f83e5d0515 linux-3.0/net/atm/svc.c -7585c8fd831689440c86b72dd11607a9 linux-3.0/net/atm/signaling.h -4f7faf1be72ed86fc9079ca7de157596 linux-3.0/net/atm/signaling.c -799d291eeb63e3bb84cb0405e653adb5 linux-3.0/net/atm/resources.h -b72488928a2e75ca9e3122a246427758 linux-3.0/net/atm/resources.c -87496f6107819c98d345d06935c007c9 linux-3.0/net/atm/raw.c -c9c14f0f9e738e6f7a171ed52093d183 linux-3.0/net/atm/pvc.c -97f95c2b18c4b2145364bb09c0c75b28 linux-3.0/net/atm/protocols.h -e8c501d6e790acbde09663a19831f5c0 linux-3.0/net/atm/proc.c -ceaea54c5b34f15bd3b5590350dd53e7 linux-3.0/net/atm/pppoatm.c -4c859c5498fc2baabe8e8dda5f2429f3 linux-3.0/net/atm/mpoa_proc.c -c76087d294cd9414ed07128b7e87a23a linux-3.0/net/atm/mpoa_caches.h -ff28ff999a41d6df56a39cf3b6cc346f linux-3.0/net/atm/mpoa_caches.c -1a1ad4d250ff212613e25b0822046379 linux-3.0/net/atm/mpc.h -8a60f482e7a37cfccce32ec6645b5446 linux-3.0/net/atm/mpc.c -08614428b0098b58281bd99abcba8aa0 linux-3.0/net/atm/lec_arpc.h -ecf77573fc1e4b44e537aa6dfebe7da9 linux-3.0/net/atm/lec.h -b8662844cd08f08ffb142e4b9a526c68 linux-3.0/net/atm/lec.c -67029f9a7ea6027ba1b4356b344e9b44 linux-3.0/net/atm/ioctl.c -e8cce10734d6a37496a76f1ef41d8dae linux-3.0/net/atm/common.h -923767c0a28076377c6714178e5844ab linux-3.0/net/atm/common.c -358acebb86fb5fe61b2a757041b1d680 linux-3.0/net/atm/clip.c -e3946449c9cd83c763e05fced2e8e96e linux-3.0/net/atm/br2684.c -186a088ede4f83926e3da33f44d68581 linux-3.0/net/atm/atm_sysfs.c -0f03b27ef5cee8aad58a9663b487fb90 linux-3.0/net/atm/atm_misc.c -e38e57e53024086f87c7fc4889b3ad5f linux-3.0/net/atm/addr.h -452507378be324551ff6ef82362e0b20 linux-3.0/net/atm/addr.c -954d5f669726a8ca73ebdbd62b30934b linux-3.0/net/atm/Makefile -a76399dc29f9042fd9393cefb5b1c28d linux-3.0/net/atm/Kconfig -e7ae373af7d6c650c740ced01dea339d linux-3.0/net/appletalk/sysctl_net_atalk.c -eca6692917a5730bb8b22f5f516ae41f linux-3.0/net/appletalk/dev.c -b5b693d224ebf6f670ab1c62e6d0c8c2 linux-3.0/net/appletalk/ddp.c -ee5c4d6485237f53a9a0f0788c418d31 linux-3.0/net/appletalk/atalk_proc.c -bb0257b479fa138f874170b3d7198cb6 linux-3.0/net/appletalk/aarp.c -f56187b7727f091e716e631c4a9d50d8 linux-3.0/net/appletalk/Makefile -0e3cde343ac03bdf408e31f7b9ba5a0f linux-3.0/net/TUNABLE -b3503c5993aa82ae1baba99c7541da24 linux-3.0/net/Makefile -5025e3d00221c1d2196a90ec8d4c164b linux-3.0/net/Kconfig -7cd461378686300adb17b926a89d6ab7 linux-3.0/net/9p/util.c -0af37162f913c69e5a1c6eb4604a31ae linux-3.0/net/9p/trans_virtio.c -7c7e5d21119c905e418f1701314194be linux-3.0/net/9p/trans_rdma.c -e253ea664205c61e93ef8fe26620ae09 linux-3.0/net/9p/trans_fd.c -e822955d70a3a0f65178b97db29fa5b9 linux-3.0/net/9p/t