diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-07-11 19:13:53 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-07-11 19:13:53 +0000 |
commit | e27ccb2e3137137cf39fe40a041915fd871505e0 (patch) | |
tree | dc2c68c32482b8c5452f66f7b699a68f29812c49 /usr/src | |
parent | 5c9c69ecbe77572e7ad4ac8c151432fea25887dd (diff) | |
download | illumos-joyent-e27ccb2e3137137cf39fe40a041915fd871505e0.tar.gz |
OS-3194 lxbrand ifconfig and netstat -r do nothing when run as a normal user
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/brand/lx/cmd/Makefile | 2 | ||||
-rwxr-xr-x | usr/src/lib/brand/lx/cmd/ifconfig.sh | 172 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/zone/lx_boot.ksh | 58 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh | 10 |
4 files changed, 217 insertions, 25 deletions
diff --git a/usr/src/lib/brand/lx/cmd/Makefile b/usr/src/lib/brand/lx/cmd/Makefile index 5a0a81f988..07ca9ff81b 100644 --- a/usr/src/lib/brand/lx/cmd/Makefile +++ b/usr/src/lib/brand/lx/cmd/Makefile @@ -25,7 +25,7 @@ # Copyright 2014 Joyent, Inc. All rights reserved. # -PROGS = lx_lockd lx_native lx_isaexec_wrapper lx_statd lx_thunk +PROGS = lx_lockd lx_native lx_isaexec_wrapper lx_statd lx_thunk ifconfig include ../Makefile.lx diff --git a/usr/src/lib/brand/lx/cmd/ifconfig.sh b/usr/src/lib/brand/lx/cmd/ifconfig.sh new file mode 100755 index 0000000000..d8e83fadb6 --- /dev/null +++ b/usr/src/lib/brand/lx/cmd/ifconfig.sh @@ -0,0 +1,172 @@ +#!/bin/sh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. + +# +# This script uses the native ifconfig, without the thunk library linked in, +# to display NIC data in the Linux style. The native ifconfig with the thunk +# library cannot be used by non-root users since the thunk library does a +# chroot. +# +# Copyright 2014 Joyent, Inc. All rights reserved. +# + +short=0 +ifname="" + +# This is running in Linux, there is likely no getopts command +if [ $# -gt 0 ]; then + for i in "$@" + do + case "$i" in + "-a") # ignore - interfaces are brought up by the zone + ;; + "-s") + short=1 + ;; + "-v") # ignore + ;; + -*) echo "Error: unsupported option $i" + exit 1 + ;; + *) + if [ -n "$ifname" ]; then + echo "Error: interface configuration is not supported in a zone" + exit 1 + fi + ifname=$i + ;; + esac + done +fi + +LD_LIBRARY_PATH_32="/native/lib:/native/usr/lib" +LD_BIND_NOW=1 +export LD_LIBRARY_PATH_32 LD_BIND_NOW + +# Start by getting the kstats we need +/native/usr/lib/brand/lx/lx_native /native/lib/ld.so.1 \ + /native/usr/bin/kstat -m link -c net | awk '{ + if ($1 == "module:" && length(ifname) > 0) + printf("%s %s %s %s %s %s %s\n", ifname, ipckts, ierrs, rbytes, + opckts, oerrs, obytes) + + if ($1 == "name:") ifname=$2 + if ($1 == "ipackets") ipckts=$2 + if ($1 == "ierrors") ierrs=$2 + if ($1 == "rbytes") rbytes=$2 + if ($1 == "opackets") opckts=$2 + if ($1 == "oerrors") oerrs=$2 + if ($1 == "obytes") obytes=$2 +} END { + if (length(ifname) > 0) + printf("%s %s %s %s %s %s %s\n", ifname, ipckts, ierrs, rbytes, + opckts, oerrs, obytes) +}' >/tmp/ifstats.$$ + +/native/usr/lib/brand/lx/lx_native /native/lib/ld.so.1 \ + /native/usr/bin/kstat -m lo -c net | awk '{ + if ($1 == "ipackets") ipckts=$2 + if ($1 == "opackets") opckts=$2 +} END { + printf("lo0 %s 0 0 %s 0 0\n", ipckts, opckts) +}' >>/tmp/ifstats.$$ + +# Now get the interfaces and format the output +/native/usr/lib/brand/lx/lx_native /native/lib/ld.so.1 /native/sbin/ifconfig | +awk -v pid=$$ -v nm=$ifname -v short=$short 'BEGIN { + indent=" " + # load interface kstats + tfile="/tmp/ifstats." pid + while (getline < tfile > 0) { + stats[$1]=substr($0, length($1) + 2) + } + + if (short) + printf("%s %s %s %s %s %s %s %s %s %s %s %s\n", "Iface", "MTU", + "Met", "RX-OK", "RX-ERR", "RX-DRP", "RX-OVR", "TX-OK", "TX-ERR", + "TX-DRP", "TX-OVR", "Flg") +} + +function fmt() { + if (length(nm) > 0 && ifname != nm) + return + + if (ifname == "lo0") { + encap="Local Loopback" + qlen=0 + sflg="LRU" + } else { + encap="Ethernet" + qlen=1000 + sflg="BMRU" + } + + n = split(stats[ifname], s) + if (n != 6) + s[1] = s[2] = s[3] = s[4] = s[5] = s[6] = 0 + + if (short) { + printf("%-5s %5s %3s %5s %6s %6s %6s %5s %6s %6s %6s %s\n", + ifname, mtu, 0, s[1], s[2], 0, 0, s[4], s[5], 0, 0, sflg) + return + } + + printf("%-9s Link encap:%s", ifname, encap) + if (length(enetaddr) > 0) + printf(" HWaddr %s", enetaddr) + printf("\n") + printf("%9s inet addr:%s", indent, inet) + if (length(bcast) > 0) + printf(" Bcast:%s", bcast) + printf(" Mask:%s\n", mask) + printf("%9s %s MTU:%s\n", indent, flags, mtu) + printf("%9s RX packets:%s errors:%s dropped:0 overruns:0 frame:0\n", + indent, s[1], s[2]) + printf("%9s TX packets:%s errors:%s dropped:0 overruns:0 carrier:0\n", + indent, s[4], s[6]) + printf("%9s collisons:0 txqueuelen:%s\n", indent, qlen) + printf("%9s RX bytes:%s TX bytes:%s\n", indent, s[3], s[6]) + printf("\n") +} + +{ + if (substr($1, length($1), 1) == ":") { + if (length(ifname) > 0) { + # print prev entry and reset + fmt() + ifname="" + bcast="" + enetaddr="" + } + + ifname=substr($1, 1, length($1) - 1) + mtu=$4 + pos=index($2, "<") + 1 + flags=substr($2, pos, length($2) - pos) + getline + inet=$2 + mask=$4 + if (NF > 4) + bcast=$6 + else + bcast="" + } else if ($1 == "ether") { + enetaddr=$2 + } +} + +END { + if (length(ifname) > 0) { + fmt() + } +}' + +rm -f /tmp/ifstats.$$ diff --git a/usr/src/lib/brand/lx/zone/lx_boot.ksh b/usr/src/lib/brand/lx/zone/lx_boot.ksh index fa313f0ec3..3edf51f7ec 100644 --- a/usr/src/lib/brand/lx/zone/lx_boot.ksh +++ b/usr/src/lib/brand/lx/zone/lx_boot.ksh @@ -56,9 +56,19 @@ fi BRANDDIR=/native/usr/lib/brand/lx; EXIT_CODE=1 -# $1 is lx cmd, $2 is native cmd, +# All native executables must be run using the native linker. By default, the +# kernel runs the linker at /lib/ld.so.1, which doesn't exist in an lx zone. +# In lx, the linker is ld-linux.so.N. Hence when we run the native executable +# from the wrappers, we explicitly specify /native/lib/ld.so.1 as our 32-bit +# linker (or /native/lib/64/ld.so.1 as our 64-bit linker). + +# Setup a native command which uses the thunk library to access the Linux +# nameservices within the zone. +# +# $1 is lx cmd, $2 is native cmd, $3 is an optional inclusion in the script # the lx cmd path must have already be verified with safe_dir -setup_native_isaexeccmd() { +# +setup_native_thunk_cmd() { cmd_name=$ZONEROOT/$1 if [ -h $cmd_name -o \( -e $cmd_name -a ! -f $cmd_name \) ]; then @@ -69,19 +79,17 @@ setup_native_isaexeccmd() { cat <<-DONE >$ZONEROOT/$1 #!/bin/sh + $3 exec /native/usr/lib/brand/lx/lx_native \ - /native/lib/ld.so.1 \ - -e LD_NOENVIRON=1 \ - -e LD_NOCONFIG=1 \ + /native/lib/ld.so.1 -e LD_NOENVIRON=1 -e LD_NOCONFIG=1 \ -e LD_PRELOAD_32=/native/usr/lib/brand/lx/lx_thunk.so.1 \ - -e LD_LIBRARY_PATH_32="/native/lib:/native/usr/lib" \ - $2 "\$@" + -e LD_LIBRARY_PATH_32="/native/lib:/native/usr/lib" $2 "\$@" DONE chmod 755 $ZONEROOT/$1 } -# $1 is lx cmd, $2 is native cmd, $3 is an optional inclusion in the script +# $1 is lx cmd, $2 is native cmd # the lx cmd path must have already be verified with safe_dir setup_native_cmd() { cmd_name=$ZONEROOT/$1 @@ -94,13 +102,9 @@ setup_native_cmd() { cat <<-DONE >$ZONEROOT/$1 #!/bin/sh - LD_LIBRARY_PATH_32="/native/lib:/native/usr/lib" - LD_PRELOAD=/native/usr/lib/brand/lx/lx_thunk.so.1 - LD_BIND_NOW=1 - export LD_LIBRARY_PATH LD_PRELOAD LD_BIND_NOW - $3 - - exec /native/usr/lib/brand/lx/lx_native $2 "\$@" + exec /native/usr/lib/brand/lx/lx_native \ + /native/lib/ld.so.1 -e LD_NOENVIRON=1 -e LD_NOCONFIG=1 \ + -e LD_LIBRARY_PATH_32="/native/lib:/native/usr/lib" $2 "\$@" DONE chmod 755 $ZONEROOT/$1 @@ -162,6 +166,7 @@ fi # # Validate that the zone filesystem looks like we expect it to. # +safe_dir /lib safe_dir /bin safe_dir /sbin safe_dir /etc @@ -173,14 +178,29 @@ safe_dir /etc/update-motd.d # # Replace Linux binaries with native binaries. # -setup_native_isaexeccmd /sbin/ifconfig /native/sbin/ifconfig -setup_native_isaexeccmd /sbin/dladm /native/usr/sbin/dladm -setup_native_isaexeccmd /sbin/route /native/usr/sbin/route -setup_native_cmd /sbin/ipmgmtd /native/lib/inet/ipmgmtd \ +# XXX The lx_thunk code will perform a chroot, so these commands will not work +# if they are run by a non-privileged user. +# +setup_native_thunk_cmd /sbin/ipmgmtd /native/lib/inet/ipmgmtd \ "export SMF_FMRI=\"svc:/network/ip-interface-management:default\"" +setup_native_thunk_cmd /sbin/ifconfig-native /native/sbin/ifconfig +setup_native_thunk_cmd /sbin/dladm /native/usr/sbin/dladm + +setup_native_cmd /sbin/route /native/usr/sbin/route setup_native_cmd /bin/netstat /native/usr/bin/netstat # +# When plumbing and configuring the NICs the native ifconfig needs to use +# the thunk library, so we setup for that as ifconfig-native. However, the +# thunk library does a chroot so that means a non-root user can't use the +# native ifconfig to look at the NICs. Thus, we provide a basic shell script +# which can display NICs in the Linux style. +# +if [ ! -h $ZONEROOT/sbin/ifconfig ]; then + cp /usr/lib/brand/lx/ifconfig $ZONEROOT/sbin/ifconfig +fi + +# # STEP THREE # # Perform distro-specific customization. diff --git a/usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh b/usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh index 807be6bdd2..11070e73d1 100644 --- a/usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh +++ b/usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh @@ -38,7 +38,7 @@ setup_net() printf("script\n") printf(" /sbin/ipmgmtd || true\n") - printf(" /sbin/ifconfig lo0 plumb\n") + printf(" /sbin/ifconfig-native lo0 plumb\n") printf(" /sbin/initctl emit --no-wait net-device-up IFACE=lo LOGICAL=lo ADDRFAM=inet METHOD=loopback || true\n") } { @@ -61,8 +61,8 @@ setup_net() } if ($1 == "net:" && phys != "") { - printf(" /sbin/ifconfig %s plumb || true\n", phys) - printf(" /sbin/ifconfig %s %s netmask %s up || true\n", + printf(" /sbin/ifconfig-native %s plumb || true\n", phys) + printf(" /sbin/ifconfig-native %s %s netmask %s up || true\n", phys, ip, mask) printf(" /sbin/initctl emit --no-wait net-device-up IFACE=%s\n", phys) @@ -72,8 +72,8 @@ setup_net() } } END { - printf(" /sbin/ifconfig %s plumb || true\n", phys) - printf(" /sbin/ifconfig %s %s netmask %s up || true\n", + printf(" /sbin/ifconfig-native %s plumb || true\n", phys) + printf(" /sbin/ifconfig-native %s %s netmask %s up || true\n", phys, ip, mask) printf(" /sbin/initctl emit --no-wait net-device-up IFACE=%s\n", phys) |