Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
The Tor Project
Core
Tor
Commits
fd0c6671
Commit
fd0c6671
authored
9 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Patches
Plain Diff
Add unit tests for switch_id(), including tests for capabilities
parent
e8cc839e
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
.gitignore
+2
-0
2 additions, 0 deletions
.gitignore
src/test/include.am
+14
-3
14 additions, 3 deletions
src/test/include.am
src/test/test_switch_id.c
+181
-0
181 additions, 0 deletions
src/test/test_switch_id.c
src/test/test_switch_id.sh
+25
-0
25 additions, 0 deletions
src/test/test_switch_id.sh
with
222 additions
and
3 deletions
.gitignore
+
2
−
0
View file @
fd0c6671
...
...
@@ -172,6 +172,7 @@ cscope.*
/src/test/test-child
/src/test/test-memwipe
/src/test/test-ntor-cl
/src/test/test-switch-id
/src/test/test_workqueue
/src/test/test.exe
/src/test/test-slow.exe
...
...
@@ -179,6 +180,7 @@ cscope.*
/src/test/test-child.exe
/src/test/test-ntor-cl.exe
/src/test/test-memwipe.exe
/src/test/test-switch-id.exe
/src/test/test_workqueue.exe
/src/test/test_zero_length_keys.sh
/src/test/test_ntor.sh
...
...
This diff is collapsed.
Click to expand it.
src/test/include.am
+
14
−
3
View file @
fd0c6671
...
...
@@ -4,14 +4,16 @@ export SHELL=@SHELL@
export abs_top_srcdir=@abs_top_srcdir@
export builddir=@builddir@
TESTSCRIPTS = src/test/test_zero_length_keys.sh
TESTSCRIPTS = src/test/test_zero_length_keys.sh \
src/test/test_switch_id.sh
if USEPYTHON
TESTSCRIPTS += src/test/test_ntor.sh src/test/test_bt.sh
endif
TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
src/test/test_workqueue src/test/test_keygen.sh $(TESTSCRIPTS)
src/test/test_workqueue src/test/test_keygen.sh \
$(TESTSCRIPTS)
# These flavors are run using automake's test-driver and test-network.sh
TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-min bridges+hs
...
...
@@ -33,7 +35,8 @@ noinst_PROGRAMS+= \
src/test/test-slow \
src/test/test-memwipe \
src/test/test-child \
src/test/test_workqueue
src/test/test_workqueue \
src/test/test-switch-id
endif
src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
...
...
@@ -131,6 +134,14 @@ src_test_test_workqueue_SOURCES = \
src_test_test_workqueue_CPPFLAGS= $(src_test_AM_CPPFLAGS)
src_test_test_workqueue_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_test_test_switch_id_SOURCES = \
src/test/test_switch_id.c
src_test_test_switch_id_CPPFLAGS= $(src_test_AM_CPPFLAGS)
src_test_test_switch_id_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_test_test_switch_id_LDADD = \
src/common/libor-testing.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@
src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \
...
...
This diff is collapsed.
Click to expand it.
src/test/test_switch_id.c
0 → 100644
+
181
−
0
View file @
fd0c6671
/* Copyright (c) 2015, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include
"or.h"
#ifdef HAVE_SYS_CAPABILITY_H
#include
<sys/capability.h>
#endif
#define TEST_BUILT_WITH_CAPS 0
#define TEST_HAVE_CAPS 1
#define TEST_ROOT_CAN_BIND_LOW 2
#define TEST_SETUID 3
#define TEST_SETUID_KEEPCAPS 4
#define TEST_SETUID_STRICT 5
static
const
char
*
username
;
static
const
struct
{
const
char
*
name
;
int
test_id
;
}
which_test
[]
=
{
{
"built-with-caps"
,
TEST_BUILT_WITH_CAPS
},
{
"have-caps"
,
TEST_HAVE_CAPS
},
{
"root-bind-low"
,
TEST_ROOT_CAN_BIND_LOW
},
{
"setuid"
,
TEST_SETUID
},
{
"setuid-keepcaps"
,
TEST_SETUID_KEEPCAPS
},
{
"setuid-strict"
,
TEST_SETUID_STRICT
},
{
NULL
,
0
}
};
/* 0 on no, 1 on yes, -1 on failure. */
static
int
check_can_bind_low_ports
(
void
)
{
int
port
;
struct
sockaddr_in
sin
;
memset
(
&
sin
,
0
,
sizeof
(
sin
));
sin
.
sin_family
=
AF_INET
;
for
(
port
=
600
;
port
<
1024
;
++
port
)
{
sin
.
sin_port
=
htons
(
port
);
tor_socket_t
fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
if
(
!
SOCKET_OK
(
fd
))
{
perror
(
"socket"
);
return
-
1
;
}
int
one
=
1
;
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
one
,
sizeof
(
one
)))
{
perror
(
"setsockopt"
);
tor_close_socket_simple
(
fd
);
return
-
1
;
}
int
res
=
bind
(
fd
,
(
struct
sockaddr
*
)
&
sin
,
sizeof
(
sin
));
tor_close_socket_simple
(
fd
);
if
(
res
==
0
)
{
/* bind was successful */
return
1
;
}
else
if
(
errno
==
EACCES
||
errno
==
EPERM
)
{
/* Got a permission-denied error. */
return
0
;
}
else
if
(
errno
==
EADDRINUSE
)
{
/* Huh; somebody is using that port. */
}
else
{
perror
(
"bind"
);
}
}
return
-
1
;
}
int
main
(
int
argc
,
char
**
argv
)
{
const
char
*
testname
;
if
(
argc
!=
3
)
{
fprintf
(
stderr
,
"I want 2 arguments: a username and a command.
\n
"
);
return
1
;
}
if
(
getuid
()
!=
0
)
{
fprintf
(
stderr
,
"This test only works when it's run as root.
\n
"
);
return
1
;
}
username
=
argv
[
1
];
testname
=
argv
[
2
];
int
test_id
=
-
1
;
int
i
;
for
(
i
=
0
;
which_test
[
i
].
name
;
++
i
)
{
if
(
!
strcmp
(
which_test
[
i
].
name
,
testname
))
{
test_id
=
which_test
[
i
].
test_id
;
break
;
}
}
if
(
test_id
==
-
1
)
{
fprintf
(
stderr
,
"Unrecognized test '%s'
\n
"
,
testname
);
return
1
;
}
#ifdef HAVE_LINUX_CAPABILITIES
const
int
have_cap_support
=
1
;
#else
const
int
have_cap_support
=
0
;
#endif
int
okay
;
init_logging
(
1
);
log_severity_list_t
sev
;
memset
(
&
sev
,
0
,
sizeof
(
sev
));
set_log_severity_config
(
LOG_WARN
,
LOG_ERR
,
&
sev
);
add_stream_log
(
&
sev
,
""
,
fileno
(
stderr
));
switch
(
test_id
)
{
case
TEST_BUILT_WITH_CAPS
:
/* Succeed if we were built with capability support. */
okay
=
have_cap_support
;
break
;
case
TEST_HAVE_CAPS
:
/* Succeed if "capabilities work" == "we were built with capability
* support." */
okay
=
have_cap_support
==
have_capability_support
();
break
;
case
TEST_ROOT_CAN_BIND_LOW
:
/* Succeed if root can bind low ports. */
okay
=
check_can_bind_low_ports
()
==
1
;
break
;
case
TEST_SETUID
:
/* Succeed if we can do a setuid with no capability retention, and doing
* so makes us lose the ability to bind low ports */
case
TEST_SETUID_KEEPCAPS
:
/* Succeed if we can do a setuid with capability retention, and doing so
* does not make us lose the ability to bind low ports */
{
int
keepcaps
=
(
test_id
==
TEST_SETUID_KEEPCAPS
);
okay
=
switch_id
(
username
,
keepcaps
?
SWITCH_ID_KEEP_BINDLOW
:
0
)
==
0
;
if
(
okay
)
{
okay
=
check_can_bind_low_ports
()
==
keepcaps
;
}
break
;
}
case
TEST_SETUID_STRICT
:
/* Succeed if, after a setuid, we cannot setuid back, and we cannot
* re-grab any capabilities. */
okay
=
switch_id
(
username
,
SWITCH_ID_KEEP_BINDLOW
)
==
0
;
if
(
okay
)
{
/* We'd better not be able to setuid back! */
if
(
setuid
(
0
)
==
0
||
errno
!=
EPERM
)
{
okay
=
0
;
}
}
#ifdef HAVE_LINUX_CAPABILITIES
if
(
okay
)
{
cap_t
caps
=
cap_get_proc
();
const
cap_value_t
caplist
[]
=
{
CAP_SETUID
,
};
cap_set_flag
(
caps
,
CAP_PERMITTED
,
1
,
caplist
,
CAP_SET
);
if
(
cap_set_proc
(
caps
)
==
0
||
errno
!=
EPERM
)
{
okay
=
0
;
}
cap_free
(
caps
);
}
#endif
break
;
default:
fprintf
(
stderr
,
"Unsupported test '%s'
\n
"
,
testname
);
okay
=
0
;
break
;
}
if
(
!
okay
)
{
fprintf
(
stderr
,
"Test %s failed!
\n
"
,
testname
);
}
return
(
okay
?
0
:
1
);
}
This diff is collapsed.
Click to expand it.
src/test/test_switch_id.sh
0 → 100755
+
25
−
0
View file @
fd0c6671
#!/bin/sh
if
test
"
`
id
-u
`
"
!=
'0'
;
then
echo
"This test only works when run as root. Skipping."
>
&2
exit
77
fi
if
test
"
`
id
-u
nobody
`
"
=
""
;
then
echo
"This test requires that your system have a 'nobody' user. Sorry."
>
&2
exit
1
fi
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody setuid
||
exit
1
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody root-bind-low
||
exit
1
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody setuid-strict
||
exit
1
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody built-with-caps
||
exit
0
# ... Go beyond this point only if we were built with capability support.
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody have-caps
||
exit
1
"
${
builddir
:-
.
}
/src/test/test-switch-id"
nobody setuid-keepcaps
||
exit
1
echo
"All okay"
exit
0
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment