Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
BIND
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
635
Issues
635
List
Boards
Labels
Service Desk
Milestones
Merge Requests
107
Merge Requests
107
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
BIND
Commits
134ba0e0
Commit
134ba0e0
authored
Apr 11, 2000
by
Bob Halley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Linux PR_SET_KEEPCAPS support
parent
8469ee37
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
149 additions
and
24 deletions
+149
-24
CHANGES
CHANGES
+6
-0
README
README
+13
-7
bin/named/main.c
bin/named/main.c
+10
-0
bin/named/unix/include/named/os.h
bin/named/unix/include/named/os.h
+3
-0
bin/named/unix/os.c
bin/named/unix/os.c
+72
-11
config.h.in
config.h.in
+4
-4
configure
configure
+39
-0
configure.in
configure.in
+2
-2
No files found.
CHANGES
View file @
134ba0e0
41. [feature] Use PR_SET_KEEPCAPS on Linux 2.3.99-pre3 and later
to allow 'named' to run as a non-root user while
retaining the ability to bind() to privileged
ports.
40. [feature] Introduced new logging category "dnssec" and
logging module "dns/validator".
...
...
README
View file @
134ba0e0
...
...
@@ -220,13 +220,19 @@ Bug Reports and Mailing Lists
enhance security on most systems. The way chroot() is defined
allows a process with root privileges to escape the chroot jail.
The "-u" option is not currently useful on Linux. Linux threads
are actually processes sharing a common address space. An unfortunate
side effect of this is that some system calls, e.g. setuid() that
in a typical pthreads environment would affect all threads only affect
the calling thread/process on Linux. The good news is that BIND 9
uses the Linux kernel's capability mechanism to drop all root
powers except the ability to bind() to a privileged port.
The "-u" option is not currently useful on Linux kernels older
than 2.3.99-pre3. Linux threads are actually processes sharing a
common address space. An unfortunate side effect of this is that
some system calls, e.g. setuid() that in a typical pthreads
environment would affect all threads only affect the calling
thread/process on Linux. The good news is that BIND 9 uses the
Linux kernel's capability mechanism to drop all root powers except
the ability to bind() to a privileged port. 2.3.99-pre3 and later
kernels allow a process to say that its capabilities should be
retained after setuid(). If BIND 9 is compiled with 2.3.99-pre3 or
later kernel .h files, the "-u" option will cause the server to
run with the specified user id, but it will retain the capability
to bind() to privileged ports.
On systems with more than one CPU, the "-n" option should be used
to indicate how many CPUs there are.
...
...
bin/named/main.c
View file @
134ba0e0
...
...
@@ -289,6 +289,16 @@ setup() {
ns_os_chroot
(
ns_g_chrootdir
);
/*
* For operating systems which have a capability mechanism, now
* is the time to switch to minimal privs and change our user id.
* On traditional UNIX systems, this call will be a no-op, and we
* will change the user ID after reading the config file the first
* time. (We need to read the config file to know which possibly
* privileged ports to bind() to.)
*/
ns_os_minprivs
(
ns_g_username
);
result
=
ns_log_init
();
if
(
result
!=
ISC_R_SUCCESS
)
ns_main_earlyfatal
(
"ns_log_init() failed: %s"
,
...
...
bin/named/unix/include/named/os.h
View file @
134ba0e0
...
...
@@ -32,6 +32,9 @@ ns_os_chroot(const char *root);
void
ns_os_changeuser
(
const
char
*
username
);
void
ns_os_minprivs
(
const
char
*
username
);
void
ns_os_writepidfile
(
const
char
*
filename
);
...
...
bin/named/unix/os.c
View file @
134ba0e0
...
...
@@ -40,6 +40,7 @@
static
char
*
pidfile
=
NULL
;
#ifdef HAVE_LINUXTHREADS
static
pid_t
mainpid
=
0
;
static
isc_boolean_t
non_root_caps
=
ISC_FALSE
;
#endif
#ifdef HAVE_LINUX_CAPABILITY_H
...
...
@@ -55,6 +56,10 @@ static pid_t mainpid = 0;
#include <sys/syscall.h>
#include <linux/capability.h>
#ifdef HAVE_LINUX_PRCTL_H
#include <sys/prctl.h>
#endif
#ifndef SYS_capset
#define SYS_capset __NR_capset
#endif
...
...
@@ -64,7 +69,7 @@ linux_setcaps(unsigned int caps) {
struct
__user_cap_header_struct
caphead
;
struct
__user_cap_data_struct
cap
;
if
(
getuid
()
!=
0
)
if
(
getuid
()
!=
0
&&
!
non_root_caps
)
return
;
memset
(
&
caphead
,
0
,
sizeof
caphead
);
...
...
@@ -83,17 +88,41 @@ linux_initialprivs(void) {
unsigned
int
caps
;
/*
* Drop all privileges except the abilities to bind() to privileged
* ports and chroot().
* We don't need most privileges, so we drop them right away.
* Later on linux_minprivs() will be called, which will drop our
* capabilities to the minimum needed to run the server.
*/
caps
=
0
;
/*
* We need to be able to bind() to privileged ports, notably port 53!
*/
caps
|=
(
1
<<
CAP_NET_BIND_SERVICE
);
/*
* We need chroot() initially too.
*/
caps
|=
(
1
<<
CAP_SYS_CHROOT
);
#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
/*
* If the kernel supports keeping capabilities after setuid(), we
* also want the setuid and setgid capabilities.
*
* There's no point turning these on if we don't have PR_SET_KEEPCAPS,
* because changing user ids only works right with linuxthreads if
* we can do it early (before creating threads).
*/
caps
|=
(
1
<<
CAP_SETGID
);
caps
|=
(
1
<<
CAP_SETUID
);
#endif
/*
* XXX We might want to add CAP_SYS_RESOURCE, though it's not
* clear it would work right given the way linuxthreads work.
*/
linux_setcaps
(
caps
);
}
...
...
@@ -102,8 +131,11 @@ linux_minprivs(void) {
unsigned
int
caps
;
/*
* Drop all privileges except the abilit
ies
to bind() to privileged
* Drop all privileges except the abilit
y
to bind() to privileged
* ports.
*
* It's important that we drop CAP_SYS_CHROOT. If we didn't, it
* chroot() could be used to escape from the chrooted area.
*/
caps
=
0
;
...
...
@@ -112,6 +144,23 @@ linux_minprivs(void) {
linux_setcaps
(
caps
);
}
#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
static
void
linux_keepcaps
(
void
)
{
/*
* Ask the kernel to allow us to keep our capabilities after we
* setuid().
*/
if
(
prctl
(
PR_SET_KEEPCAPS
,
1
,
0
,
0
,
0
)
<
0
)
{
if
(
errno
!=
EINVAL
)
ns_main_earlyfatal
(
"prctl() failed: %s"
,
strerror
(
errno
));
}
else
non_root_caps
=
ISC_TRUE
;
}
#endif
#endif
/* HAVE_LINUX_CAPABILITY_H */
...
...
@@ -196,13 +245,6 @@ ns_os_chroot(const char *root) {
if
(
chdir
(
"/"
)
<
0
)
ns_main_earlyfatal
(
"chdir(/): %s"
,
strerror
(
errno
));
}
#ifdef HAVE_LINUX_CAPABILITY_H
/*
* We must drop the chroot() capability, otherwise it could be used
* to escape.
*/
linux_minprivs
();
#endif
}
void
...
...
@@ -212,6 +254,10 @@ ns_os_changeuser(const char *username) {
if
(
username
==
NULL
||
getuid
()
!=
0
)
return
;
if
(
!
non_root_caps
)
ns_main_earlyfatal
(
"-u not supported on Linux kernels older than 2.3.99-pre3"
);
if
(
all_digits
(
username
))
pw
=
getpwuid
((
uid_t
)
atoi
(
username
));
else
...
...
@@ -227,6 +273,21 @@ ns_os_changeuser(const char *username) {
ns_main_earlyfatal
(
"setuid(): %s"
,
strerror
(
errno
));
}
void
ns_os_minprivs
(
const
char
*
username
)
{
#ifdef HAVE_LINUX_CAPABILITY_H
#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
linux_keepcaps
();
ns_os_changeuser
(
username
);
#else
(
void
)
username
;
#endif
linux_minprivs
();
#else
(
void
)
username
;
#endif
/* HAVE_LINUX_CAPABILITY_H */
}
static
int
safe_open
(
const
char
*
filename
)
{
struct
stat
sb
;
...
...
config.h.in
View file @
134ba0e0
/* config.h.in. Generated automatically from configure.in by autoheader. */
/*
* Copyright (C) 1999 Internet Software Consortium.
* Copyright (C) 1999
, 2000
Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
...
...
@@ -66,6 +66,9 @@
/* Define if you have the <linux/capability.h> header file. */
#undef HAVE_LINUX_CAPABILITY_H
/* Define if you have the <linux/prctl.h> header file. */
#undef HAVE_LINUX_PRCTL_H
/* Define if you have the <netinet6/in6.h> header file. */
#undef HAVE_NETINET6_IN6_H
...
...
@@ -78,9 +81,6 @@
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the c_r library (-lc_r). */
#undef HAVE_LIBC_R
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
...
...
configure
View file @
134ba0e0
...
...
@@ -3784,6 +3784,45 @@ else
fi
done
for
ac_hdr
in
linux/prctl.h
do
ac_safe
=
`
echo
"
$ac_hdr
"
|
sed
'y%./+-%__p_%'
`
echo
$ac_n
"checking for
$ac_hdr
""...
$ac_c
"
1>&6
echo
"configure:3786: checking for
$ac_hdr
"
>
&5
if
eval
"test
\"
`
echo
'$''{'
ac_cv_header_
$ac_safe
'+set}'
`
\"
= set"
;
then
echo
$ac_n
"(cached)
$ac_c
"
1>&6
else
cat
>
conftest.
$ac_ext
<<
EOF
#line 3791 "configure"
#include "confdefs.h"
#include <
$ac_hdr
>
EOF
ac_try
=
"
$ac_cpp
conftest.
$ac_ext
>/dev/null 2>conftest.out"
{
(
eval echo
configure:3796:
\"
$ac_try
\"
)
1>&5
;
(
eval
$ac_try
)
2>&5
;
}
ac_err
=
`
grep
-v
'^ *+'
conftest.out |
grep
-v
"^conftest.
${
ac_ext
}
\$
"
`
if
test
-z
"
$ac_err
"
;
then
rm
-rf
conftest
*
eval
"ac_cv_header_
$ac_safe
=yes"
else
echo
"
$ac_err
"
>
&5
echo
"configure: failed program was:"
>
&5
cat
conftest.
$ac_ext
>
&5
rm
-rf
conftest
*
eval
"ac_cv_header_
$ac_safe
=no"
fi
rm
-f
conftest
*
fi
if
eval
"test
\"
`
echo
'$ac_cv_header_'
$ac_safe
`
\"
= yes"
;
then
echo
"
$ac_t
""yes"
1>&6
ac_tr_hdr
=
HAVE_
`
echo
$ac_hdr
|
sed
'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'
`
cat
>>
confdefs.h
<<
EOF
#define
$ac_tr_hdr
1
EOF
else
echo
"
$ac_t
""no"
1>&6
fi
done
#
...
...
configure.in
View file @
134ba0e0
...
...
@@ -13,7 +13,7 @@ dnl PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dnl ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dnl SOFTWARE.
AC_REVISION($Revision: 1.11
3
$)
AC_REVISION($Revision: 1.11
4
$)
AC_PREREQ(2.13)
...
...
@@ -709,7 +709,7 @@ AC_SUBST(ISC_PLATFORM_LONGLONGEQUALLONG)
#
AC_CHECK_FUNC(chroot, AC_DEFINE(HAVE_CHROOT))
AC_CHECK_HEADERS(linux/capability.h)
AC_CHECK_HEADERS(linux/prctl.h)
#
# Substitutions
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment