summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2014-07-11 19:13:53 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2014-07-11 19:13:53 +0000
commite27ccb2e3137137cf39fe40a041915fd871505e0 (patch)
treedc2c68c32482b8c5452f66f7b699a68f29812c49 /usr/src
parent5c9c69ecbe77572e7ad4ac8c151432fea25887dd (diff)
downloadillumos-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/Makefile2
-rwxr-xr-xusr/src/lib/brand/lx/cmd/ifconfig.sh172
-rw-r--r--usr/src/lib/brand/lx/zone/lx_boot.ksh58
-rw-r--r--usr/src/lib/brand/lx/zone/lx_boot_zone_ubuntu.ksh10
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)