View | Details | Raw Unified | Return to bug 51659
Collapse All | Expand All

(-)src/client.c (+13 lines)
Lines 1045-1050 call_in_directory (pathname, func, data) Link Here
1045
    int reposdirname_absolute;
1045
    int reposdirname_absolute;
1046
    int newdir = 0;
1046
    int newdir = 0;
1047
1047
1048
    /* For security reasons, if PATHNAME is absolute or attemps to ascend
1049
     * outside of the current sanbbox, we abort.  The server should not send us
1050
     * anything but relative paths which remain inside the sandbox here.
1051
     * Anything less means a trojan CVS server could create and edit arbitrary
1052
     * files on the client.
1053
     */
1054
    if (isabsolute (pathname) || pathname_levels (pathname) > 0)
1055
    {
1056
	error (0, 0,
1057
               "Server attempted to update a file via an invalid pathname:");
1058
        error (1, 0, "`%s'.", pathname);
1059
    }
1060
1048
    reposname = NULL;
1061
    reposname = NULL;
1049
    read_line (&reposname);
1062
    read_line (&reposname);
1050
    assert (reposname != NULL);
1063
    assert (reposname != NULL);
(-)src/import.c (-4 / +3 lines)
Lines 163-170 import (argc, argv) Link Here
163
     * to call it from anywhere else.
163
     * to call it from anywhere else.
164
     */
164
     */
165
    if ((cp = strstr(argv[0], "CVS")) &&   /* path contains "CVS" AND ... */
165
    if ((cp = strstr(argv[0], "CVS")) &&   /* path contains "CVS" AND ... */
166
        ((cp == argv[0]) || (*(cp-1) == '/')) && /* /^CVS/ OR m#/CVS# AND ... */
166
        ((cp == argv[0]) || ISDIRSEP(*(cp-1))) && /* /^CVS/ OR m#/CVS# AND ... */
167
        ((*(cp+3) == '\0') || (*(cp+3) == '/')) /* /CVS$/ OR m#CVS/# */
167
        ((*(cp+3) == '\0') || ISDIRSEP(*(cp+3))) /* /CVS$/ OR m#CVS/# */
168
       )
168
       )
169
    {
169
    {
170
        error (0, 0,
170
        error (0, 0,
Lines 183-190 import (argc, argv) Link Here
183
    }
183
    }
184
184
185
    /* XXX - this should be a module, not just a pathname */
185
    /* XXX - this should be a module, not just a pathname */
186
    if (! isabsolute (argv[0])
186
    if (!isabsolute (argv[0]) && pathname_levels (argv[0]) == 0)
187
	&& pathname_levels (argv[0]) == 0)
188
    {
187
    {
189
	if (current_parsed_root == NULL)
188
	if (current_parsed_root == NULL)
190
	{
189
	{
(-)src/sanity.sh (-5 / +207 lines)
Lines 25988-26012 ${PROG} \[diff aborted\]: read lock fail Link Here
25988
"${testcvs} -d ${CVSROOT1} -q co ../root2/dir2" \
25988
"${testcvs} -d ${CVSROOT1} -q co ../root2/dir2" \
25989
"${PROG} checkout: in directory \.\./root2/dir2:
25989
"${PROG} checkout: in directory \.\./root2/dir2:
25990
${PROG} checkout: .\.\..-relative repositories are not supported.
25990
${PROG} checkout: .\.\..-relative repositories are not supported.
25991
${PROG} \[checkout aborted\]: illegal source repository"
25991
${PROG} \[checkout aborted\]: illegal source repository" \
25992
"$PROG checkout: Server attempted to update a file via an invalid pathname:
25993
$PROG \[checkout aborted\]: \`\.\./root2/'\."
25992
	  rm -rf ../root2
25994
	  rm -rf ../root2
25993
	  dotest_fail multiroot3-13 \
25995
	  dotest_fail multiroot3-13 \
25994
"${testcvs} -d ${CVSROOT2} -q co ../root1/dir1" \
25996
"${testcvs} -d ${CVSROOT2} -q co ../root1/dir1" \
25995
"${PROG} checkout: in directory \.\./root1/dir1:
25997
"${PROG} checkout: in directory \.\./root1/dir1:
25996
${PROG} checkout: .\.\..-relative repositories are not supported.
25998
${PROG} checkout: .\.\..-relative repositories are not supported.
25997
${PROG} \[checkout aborted\]: illegal source repository"
25999
${PROG} \[checkout aborted\]: illegal source repository" \
26000
"$PROG checkout: Server attempted to update a file via an invalid pathname:
26001
$PROG \[checkout aborted\]: \`\.\./root1/'\."
25998
	  rm -rf ../root1
26002
	  rm -rf ../root1
25999
	  dotest_fail multiroot3-14 \
26003
	  dotest_fail multiroot3-14 \
26000
"${testcvs} -d ${CVSROOT1} -q co ./../root2/dir2" \
26004
"${testcvs} -d ${CVSROOT1} -q co ./../root2/dir2" \
26001
"${PROG} checkout: in directory \./\.\./root2/dir2:
26005
"${PROG} checkout: in directory \./\.\./root2/dir2:
26002
${PROG} checkout: .\.\..-relative repositories are not supported.
26006
${PROG} checkout: .\.\..-relative repositories are not supported.
26003
${PROG} \[checkout aborted\]: illegal source repository"
26007
${PROG} \[checkout aborted\]: illegal source repository" \
26008
"$PROG checkout: Server attempted to update a file via an invalid pathname:
26009
$PROG \[checkout aborted\]: \`\./\.\./root2/'\."
26004
	  rm -rf ../root2
26010
	  rm -rf ../root2
26005
	  dotest_fail multiroot3-15 \
26011
	  dotest_fail multiroot3-15 \
26006
"${testcvs} -d ${CVSROOT2} -q co ./../root1/dir1" \
26012
"${testcvs} -d ${CVSROOT2} -q co ./../root1/dir1" \
26007
"${PROG} checkout: in directory \./\.\./root1/dir1:
26013
"${PROG} checkout: in directory \./\.\./root1/dir1:
26008
${PROG} checkout: .\.\..-relative repositories are not supported.
26014
${PROG} checkout: .\.\..-relative repositories are not supported.
26009
${PROG} \[checkout aborted\]: illegal source repository"
26015
${PROG} \[checkout aborted\]: illegal source repository" \
26016
"$PROG checkout: Server attempted to update a file via an invalid pathname:
26017
$PROG \[checkout aborted\]: \`\./\.\./root1/'\."
26010
	  rm -rf ../root1
26018
	  rm -rf ../root1
26011
26019
26012
	  cd ../..
26020
	  cd ../..
Lines 27045-27054 u=rw,g=r,o=r Link Here
27045
abc
27053
abc
27046
update"
27054
update"
27047
27055
27056
	    # The following test tests what was a potential client update in
27057
	    # CVS versions 1.11.14 and CVS versions 1.12.6 and earlier.  This
27058
	    # exploit would allow a trojan server to create arbitrary files,
27059
	    # anywhere the user had write permissions, even outside of the
27060
	    # user's sandbox.
27061
	    cat >$HOME/.bashrc <<EOF
27062
#!$TESTSHELL
27063
# This is where login scripts would usually be
27064
# stored.
27065
EOF
27066
	    cat >$TESTDIR/serveme <<EOF
27067
#!$TESTSHELL
27068
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27069
echo "ok"
27070
echo "Rcs-diff $HOME/"
27071
echo "$HOME/.bashrc"
27072
echo "/.bashrc/73.50///"
27073
echo "u=rw,g=rw,o=rw"
27074
echo "20"
27075
echo "a1 1"
27076
echo "echo 'gotcha!'"
27077
echo "ok"
27078
cat >/dev/null
27079
EOF
27080
	    
27081
	    # If I don't run the following sleep between the above cat and
27082
	    # the following calls to dotest, sometimes the serveme file isn't
27083
	    # completely written yet by the time CVS tries to execute it,
27084
	    # causing the shell to intermittantly report syntax errors (usually
27085
	    # early EOF).  There's probably a new race condition here, but this
27086
	    # works.
27087
	    #
27088
	    # Incidentally, I can reproduce this behavior with Linux 2.4.20 and
27089
	    # Bash 2.05 or Bash 2.05b.
27090
	    sleep 1
27091
	    dotest_fail client-10 "$testcvs update" \
27092
"$PROG update: Server attempted to update a file via an invalid pathname:
27093
$PROG \[update aborted\]: \`$HOME/'\."
27094
27095
	    # A second try at a client exploit.  This one never actually
27096
	    # failed in the past, but I thought it wouldn't hurt to add a test.
27097
	    cat >$TESTDIR/serveme <<EOF
27098
#!$TESTSHELL
27099
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27100
echo "ok"
27101
echo "Rcs-diff ./"
27102
echo "$HOME/.bashrc"
27103
echo "/.bashrc/73.50///"
27104
echo "u=rw,g=rw,o=rw"
27105
echo "20"
27106
echo "a1 1"
27107
echo "echo 'gotcha!'"
27108
echo "ok"
27109
cat >/dev/null
27110
EOF
27111
	    sleep 1
27112
	    dotest_fail client-11 "$testcvs update" \
27113
"$PROG \[update aborted\]: patch original file \./\.bashrc does not exist"
27114
27115
	    # A third try at a client exploit.  This one did used to fail like
27116
	    # client-10.
27117
	    cat >$TESTDIR/serveme <<EOF
27118
#!$TESTSHELL
27119
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27120
echo "ok"
27121
echo "Rcs-diff ../../home/"
27122
echo "../../.bashrc"
27123
echo "/.bashrc/73.50///"
27124
echo "u=rw,g=rw,o=rw"
27125
echo "20"
27126
echo "a1 1"
27127
echo "echo 'gotcha!'"
27128
echo "ok"
27129
cat >/dev/null
27130
EOF
27131
	    sleep 1
27132
	    dotest_fail client-12 "$testcvs update" \
27133
"$PROG update: Server attempted to update a file via an invalid pathname:
27134
$PROG \[update aborted\]: \`\.\./\.\./home/'\."
27135
27136
	    # Try the same exploit using the Created response.
27137
	    cat >$TESTDIR/serveme <<EOF
27138
#!$TESTSHELL
27139
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27140
echo "ok"
27141
echo "Created $HOME/"
27142
echo "$HOME/.bashrc"
27143
echo "/.bashrc/73.50///"
27144
echo "u=rw,g=rw,o=rw"
27145
echo "26"
27146
echo "#! /bin/sh"
27147
echo "echo 'gotcha!'"
27148
echo "ok"
27149
cat >/dev/null
27150
EOF
27151
	    sleep 1
27152
	    dotest_fail client-13 "$testcvs update" \
27153
"$PROG update: Server attempted to update a file via an invalid pathname:
27154
$PROG \[update aborted\]: \`$HOME/'\."
27155
27156
	    # Now try using the Update-existing response
27157
	    cat >$TESTDIR/serveme <<EOF
27158
#!$TESTSHELL
27159
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27160
echo "ok"
27161
echo "Update-existing ../../home/"
27162
echo "../../home/.bashrc"
27163
echo "/.bashrc/73.50///"
27164
echo "u=rw,g=rw,o=rw"
27165
echo "26"
27166
echo "#! /bin/sh"
27167
echo "echo 'gotcha!'"
27168
echo "ok"
27169
cat >/dev/null
27170
EOF
27171
	    sleep 1
27172
	    dotest_fail client-14 "$testcvs update" \
27173
"$PROG update: Server attempted to update a file via an invalid pathname:
27174
$PROG \[update aborted\]: \`\.\./\.\./home/'\."
27175
27176
	    # Try the same exploit using the Merged response.
27177
	    cat >$TESTDIR/serveme <<EOF
27178
#!$TESTSHELL
27179
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27180
echo "ok"
27181
echo "Merged $HOME/"
27182
echo "$HOME/.bashrc"
27183
echo "/.bashrc/73.50///"
27184
echo "u=rw,g=rw,o=rw"
27185
echo "26"
27186
echo "#! /bin/sh"
27187
echo "echo 'gotcha!'"
27188
echo "ok"
27189
cat >/dev/null
27190
EOF
27191
	    sleep 1
27192
	    dotest_fail client-15 "$testcvs update" \
27193
"$PROG update: Server attempted to update a file via an invalid pathname:
27194
$PROG \[update aborted\]: \`$HOME/'\."
27195
27196
	    # Now try using the Updated response
27197
	    cat >$TESTDIR/serveme <<EOF
27198
#!$TESTSHELL
27199
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27200
echo "ok"
27201
echo "Updated ../../home/"
27202
echo "../../home/.bashrc"
27203
echo "/.bashrc/73.50///"
27204
echo "u=rw,g=rw,o=rw"
27205
echo "26"
27206
echo "#! /bin/sh"
27207
echo "echo 'gotcha!'"
27208
echo "ok"
27209
cat >/dev/null
27210
EOF
27211
	    sleep 1
27212
	    dotest_fail client-16 "$testcvs update" \
27213
"$PROG update: Server attempted to update a file via an invalid pathname:
27214
$PROG \[update aborted\]: \`\.\./\.\./home/'\."
27215
27216
	    # Try the same exploit using the Copy-file response.
27217
	    # As far as I know, Copy-file was never exploitable either.
27218
	    cat >$TESTDIR/serveme <<EOF
27219
#!$TESTSHELL
27220
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
27221
echo "ok"
27222
echo "Created ."
27223
echo "./innocuous"
27224
echo "/innocuous/73.50///"
27225
echo "u=rw,g=rw,o=rw"
27226
echo "26"
27227
echo "#! /bin/sh"
27228
echo "echo 'gotcha!'"
27229
echo "Copy-file ."
27230
echo "./innocuous"
27231
echo "$HOME/innocuous"
27232
echo "ok"
27233
cat >/dev/null
27234
EOF
27235
	    sleep 1
27236
	    dotest_fail client-18 "$testcvs update" \
27237
"$PROG \[update aborted\]: protocol error: Copy-file tried to specify directory"
27238
27239
	    # And verify that none of the exploits was successful.
27240
	    dotest client-19 "cat $HOME/.bashrc" \
27241
"#!$TESTSHELL
27242
# This is where login scripts would usually be
27243
# stored\."
27244
27245
	    if $keep; then
27246
	      echo Keeping $TESTDIR and exiting due to --keep
27247
	      exit 0
27248
	    fi
27249
27048
	    cd ../..
27250
	    cd ../..
27049
	    rm -r 1
27251
	    rm -r 1
27050
	    rmdir ${TESTDIR}/bogus
27252
	    rmdir ${TESTDIR}/bogus
27051
	    rm ${TESTDIR}/serveme
27253
	    rm $TESTDIR/serveme $HOME/.bashrc
27052
	    CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER
27254
	    CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER
27053
	  fi # skip the whole thing for local
27255
	  fi # skip the whole thing for local
27054
	  ;;
27256
	  ;;

Return to bug 51659