Mercurial > hg > dhcpcd
changeset 1601:ed0524dd1004 draft
Escape | and & characters when passing to the shell.
Add functions for hooks to check validity of domain names and paths.
Ensure we set a valid hostname, DNS domain and NIS domain.
Document the need for input validation in dhcpcd-run-hooks(8).
Fixes CVE-2011-996.
Based on patches to dhcpcd-3 by Marius Tomaschewski <mt@suse.de>.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Wed, 06 Apr 2011 08:16:32 +0000 |
| parents | 9c96a554b838 |
| children | a4828c7eceaf |
| files | dhcp.c dhcpcd-hooks/20-resolv.conf dhcpcd-hooks/30-hostname dhcpcd-hooks/50-yp.conf dhcpcd-hooks/50-ypbind dhcpcd-run-hooks.8.in dhcpcd-run-hooks.in |
| diffstat | 7 files changed, 84 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcp.c Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcp.c Wed Apr 06 08:16:32 2011 +0000 @@ -1143,7 +1143,9 @@ case '\'': /* FALLTHROUGH */ case '$': /* FALLTHROUGH */ case '`': /* FALLTHROUGH */ - case '\\': + case '\\': /* FALLTHROUGH */ + case '|': /* FALLTHROUGH */ + case '&': if (s) { if (len < 3) { errno = ENOBUFS;
--- a/dhcpcd-hooks/20-resolv.conf Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-hooks/20-resolv.conf Wed Apr 06 08:16:32 2011 +0000 @@ -81,14 +81,22 @@ if [ -n "$new_domain_name" ]; then set -- $new_domain_name new_domain_name="$1" - conf="${conf}domain $new_domain_name\n" + if valid_domainname "$new_domain_name"; then + conf="${conf}domain $new_domain_name\n" + else + syslog err "Invalid domain name: $new_domain_name" + fi # Support RFC violating search in domain if [ -z "$new_domain_search" -a -n "$2" ]; then new_domain_search="$@" fi fi if [ -n "$new_domain_search" ]; then - conf="${conf}search $new_domain_search\n" + if valid_domainname_list; then + conf="${conf}search $new_domain_search\n" + else + syslog err "Invalid domain name in list: $new_domain_search" + fi fi for x in ${new_domain_name_servers}; do conf="${conf}nameserver $x\n"
--- a/dhcpcd-hooks/30-hostname Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-hooks/30-hostname Wed Apr 06 08:16:32 2011 +0000 @@ -18,13 +18,22 @@ esac } +try_hostname() +{ + if valid_domainname "$1"; then + hostname "$1" + else + syslog err "Invalid hostname: $1" + fi +} + set_hostname() { if need_hostname; then if [ -n "$new_host_name" ]; then - hostname "$new_host_name" + try_hostname "$new_host_name" elif [ -n "$new_fqdn_name" ]; then - hostname "$new_fqdn_name" + try_hostname "$new_fqdn_name" fi fi }
--- a/dhcpcd-hooks/50-yp.conf Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-hooks/50-yp.conf Wed Apr 06 08:16:32 2011 +0000 @@ -13,6 +13,11 @@ rm -f "$cf" echo "$signature" > "$cf" if [ -n "$new_nis_domain" ]; then + if ! valid_domainname "$new_nis_domain"; then + syslog err "Invalid NIS domain name: $new_nis_domain" + rm -f "$cf" + return 1 + fi domainname "$new_nis_domain" if [ -n "$new_nis_servers" ]; then prefix="domain $new_nis_domain server "
--- a/dhcpcd-hooks/50-ypbind Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-hooks/50-ypbind Wed Apr 06 08:16:32 2011 +0000 @@ -67,7 +67,11 @@ rm -f "$ypbind_dir/$interface" elif $if_up || $if_down; then if [ -n "$new_nis_domain" ]; then - make_yp_binding + if valid_domainname "$new_nis_domain"; then + make_yp_binding + else + syslog err "Invalid NIS domain name: $new_nis_domain" + fi elif [ -n "$old_nis_domain" ]; then restore_yp_binding fi
--- a/dhcpcd-run-hooks.8.in Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-run-hooks.8.in Wed Apr 06 08:16:32 2011 +0000 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2006-2010 Roy Marples +.\" Copyright (c) 2006-2011 Roy Marples .\" All rights reserved .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 24, 2010 +.Dd March 23, 2011 .Dt DHCPCD-RUN-HOOKS 8 SMM .Os .Sh NAME @@ -135,3 +135,11 @@ .An Roy Marples Aq roy@marples.name .Sh BUGS Please report them to http://roy.marples.name/projects/dhcpcd +.Sh SECURITY CONSIDERATIONS +Little validation of DHCP options is done in dhcpcd itself. +Instead, it is up to the hooks to handle any validation needed. +To this end, some helper functions are provided, such as valid_domainname as +used by the +.Pa 20-resolv.conf +hook to ensure that the hostname is not set to an invalid value. +valid_path is also provided, but is currently unused by a stock hook script.
--- a/dhcpcd-run-hooks.in Tue Mar 29 10:36:17 2011 +0000 +++ b/dhcpcd-run-hooks.in Wed Apr 06 08:16:32 2011 +0000 @@ -147,6 +147,46 @@ fi } +# Check for a valid domain name as per RFC1123 with the exception of +# allowing - and _ as they seem to be widely used. +valid_domainname() +{ + local name="$1" label + + [ -z "$name" -o ${#name} -gt 255 ] && return 1 + + while [ -n "$name" ]; do + label="${name%%.*}" + [ -z "$label" -o ${#label} -gt 63 ] && return 1 + case "$label" in + -*|_*|*-|*_) return 1;; + *[![:alnum:]-_]*) return 1;; + esac + [ "$name" = "${name#*.}" ] && break + name="${name#*.}" + done + return 0 +} + +valid_domainname_list() +{ + local name + + for name in $@; do + valid_domainname "$name" || return $? + done + return 0 +} + +# Check for a valid path +valid_path() +{ + case "$@" in + *[![:alnum:]#%+-_:\.,@~\\/\[\]=\ ]*) return 1;; + esac + return 0 +} + # Check a system service exists service_exists() {
