内容简介:Findings:Over half of your libraries are used by fewer than 0.1% of your executables.
Do your installed programs share dynamic libraries?
Findings: not really
Over half of your libraries are used by fewer than 0.1% of your executables. Number of times each dynamic library is required by a program
libs.awk
/\t.*\.so.*/ {
n=split($1, p, "/")
split(p[n], l, ".")
lib=l[1]
if (libs[lib] == "") {
libs[lib] = 0
}
libs[lib] += 1
}
END {
for (lib in libs) {
print libs[lib] "\t" lib
}
}
Usage
$ find /usr/bin -type f -executable -print \
| xargs ldd 2>/dev/null \
| awk -f libs.awk \
| sort -rn > results.txt
$ awk '{ print NR "\t" $1 }' < results.txt > nresults.txt
$ gnuplot
gnuplot> plot 'nresults.txt'
$ find /usr/bin -type f -executable -print | wc -l 5688 $ head -n20 < results.txt 4496 libc 4484 linux-vdso 4483 ld-linux-x86-64 2654 libm 2301 libdl 2216 libpthread 1419 libgcc_s 1301 libz 1144 libstdc++ 805 liblzma 785 librt 771 libXdmcp 771 libxcb 771 libXau 755 libX11 703 libpcre 667 libglib-2 658 libffi 578 libresolv 559 libXext
Is loading dynamically linked programs faster?
Findings: definitely not
| Linkage | Avg. startup time |
|---|---|
| Dynamic | 137263 ns |
| Static | 64048 ns |
ex.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
fprintf(stdout, "%ld\t", ts.tv_nsec);
fflush(stdout);
if (argc == 1) {
char *args[] = { "", "", NULL };
execvp(argv[0], args);
} else {
fprintf(stdout, "\n");
}
return 0;
}
test.sh
#!/bin/sh i=0 while [ $i -lt 1000 ] do ./ex i=$((i+1)) done
My results
$ musl-gcc -o ex ex.c
$ ./test.sh | awk 'BEGIN { sum = 0 } { sum += $2-$1 } END { print sum / NR }'
137263
$ musl-gcc -static -o ex ex.c
$ ./test.sh | awk 'BEGIN { sum = 0 } { sum += $2-$1 } END { print sum / NR }'
64048
Wouldn't statically linked executables be huge?
Findings: not really
On average, dynamically linked executables use only 4.6% of the symbols on offer from their dependencies. A good linker will remove unused symbols. % of symbols requested by dynamically linked programs from the libraries that it depends on
nsyms.go
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
)
func main() {
ldd := exec.Command("ldd", os.Args[1])
rc, err := ldd.StdoutPipe()
if err != nil {
panic(err)
}
ldd.Start()
var libpaths []string
scan := bufio.NewScanner(rc)
for scan.Scan() {
line := scan.Text()[1:] /* \t */
sp := strings.Split(line, " ")
var lib string
if strings.Contains(line, "=>") {
lib = sp[2]
} else {
lib = sp[0]
}
if !filepath.IsAbs(lib) {
lib = "/usr/lib/" + lib
}
libpaths = append(libpaths, lib)
}
ldd.Wait()
rc.Close()
syms := make(map[string]interface{})
for _, path := range libpaths {
objdump := exec.Command("objdump", "-T", path)
rc, err := objdump.StdoutPipe()
if err != nil {
panic(err)
}
objdump.Start()
scan := bufio.NewScanner(rc)
for i := 0; scan.Scan(); i++ {
if i < 4 {
continue
}
line := scan.Text()
sp := strings.Split(line, " ")
if len(sp) < 5 {
continue
}
sym := sp[len(sp)-1]
syms[sym] = nil
}
objdump.Wait()
rc.Close()
}
objdump := exec.Command("objdump", "-R", os.Args[1])
rc, err = objdump.StdoutPipe()
if err != nil {
panic(err)
}
objdump.Start()
used := make(map[string]interface{})
scan = bufio.NewScanner(rc)
for i := 0; scan.Scan(); i++ {
if i < 5 {
continue
}
sp := strings.Split(scan.Text(), " ")
if len(sp) < 3 {
continue
}
sym := sp[len(sp)-1]
used[sym] = nil
}
objdump.Wait()
rc.Close()
if len(syms) != 0 && len(used) != 0 && len(used) <= len(syms) {
fmt.Printf("%50s\t%d\t%d\t%f\n", os.Args[1], len(syms), len(used),
float64(len(used)) / float64(len(syms)))
}
}
Usage
$ find /usr/bin -type f -executable -print | xargs -n1 ./nsyms > results.txt
$ awk '{ n += $4 } END { print n / NR }' < results.txt
Will security vulnerabilities in libraries that have been statically linked cause large or unmanagable updates?
Findings: not really
Not including libc, the only libraries which had "critical" or "high" severity vulnerabilities in 2019 which affected over 100 binaries on my system were dbus, gnutls, cairo, libssh2, and curl. 265 binaries were affected by the rest.
The total download cost to upgrade all binaries on my system which were affected by these CVEs in 2019 is 3.8 GiB. This is reduced to 1.0 GiB if you eliminate glibc.
It is also unknown if any of these vulnerabilities would have been introduced after the last build date for a given statically linked binary; if so that binary would not need to be updated. Many vulnerabilities are also limited to a specific code path or use-case, and binaries which do not invoke that code path in their dependencies will not be affected. A process to ascertain this information in the wake of a vulnerability could be automated.
extractcves.py
import email.utils
import mailbox
import re
import shlex
import time
pacman_re = re.compile(r'pacman -Syu .*')
severity_re = re.compile(r'Severity: (.*)')
mbox = mailbox.mbox("arch-security.mbox")
for m in mbox.items():
m = m[1]
date = m["Date"]
for part in m.walk():
if part.is_multipart():
continue
content_type = part.get_content_type()
[charset] = part.get_charsets("utf-8")
if content_type == 'text/plain':
body = part.get_payload(decode=True).decode(charset)
break
pkgs = pacman_re.findall(body)
severity = severity_re.findall(body)
date = email.utils.parsedate(date)
if len(pkgs) == 0 or date is None:
continue
if date[0] <= 2018 or date[0] > 2019:
continue
severity = severity[0]
args = shlex.split(pkgs[0])
pkg = args[2].split(">=")[0]
print(pkg, severity)
$ python3 extractcves.py | grep Critical > cves.txt
$ xargs pacman -Ql < cves.txt | grep \\.so | awk '{print $1}' | sort -u>affected.txt
# Manually remove packages like Firefox, Thunderbird, etc; write remainder.txt
$ xargs pacman -Ql < remainder.txt | grep '/usr/lib/.*.so$' | awk '{ print $2 }' > libs.txt
$ ldd /usr/bin/* >ldd.txt
$ ./scope.sh <libs.txt | sort -nr >sobjects.txt
sobjects.txt is a sorted list of shared objects and the number of executables that link to them. To find the total size of affected binaries, I ran the following command:
# With libc $ egrep -la 'libc.so|libm.so|libdl.so|libpthread.so|librt.so|libresolv.so|libdbus-1.so|libgnutls.so|libcairo.so|libutil.so|libssh2.so|libcurl.so|libcairo-gobject.so|libcrypt.so|libspice-server.so|libarchive.so|libSDL2-2.0.so|libmvec.so|libmagic.so|libtextstyle.so|libgettextlib-0.20.2.so|libgettextsrc-0.20.2.so|libMagickWand-7.Q16HDRI.so|libMagickCore-7.Q16HDRI.so|libbfd-2.34.0.so|libpolkit-gobject-1.so|libwebkit2gtk-4.0.so|libjavascriptcoregtk-4.0.so|libpolkit-agent-1.so|libgs.so|libctf.so|libSDL.so|libopcodes-2.34.0.so|libQt5WebEngine.so|libQt5WebEngineCore.so|libctf-nobfd.so|libcairo-script-interpreter.so' /usr/bin/* | xargs wc -c # Without libc $ egrep -la 'libdbus-1.so|libgnutls.so|libcairo.so|libssh2.so|libcurl.so|libcairo-gobject.so|libcrypt.so|libspice-server.so|libarchive.so|libSDL2-2.0.so|libmvec.so|libmagic.so|libtextstyle.so|libgettextlib-0.20.2.so|libgettextsrc-0.20.2.so|libMagickWand-7.Q16HDRI.so|libMagickCore-7.Q16HDRI.so|libbfd-2.34.0.so|libpolkit-gobject-1.so|libwebkit2gtk-4.0.so|libjavascriptcoregtk-4.0.so|libpolkit-agent-1.so|libgs.so|libctf.so|libSDL.so|libopcodes-2.34.0.so|libQt5WebEngine.so|libQt5WebEngineCore.so|libctf-nobfd.so|libcairo-script-interpreter.so' /usr/bin/* | xargs wc -c
Test environment
- Arch Linux, up-to-date as of 2020-06-25
- 2188 packages installed
- gcc 10.1.0
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
创业的艺术2.0
〔美〕盖伊·川崎 / 刘悦、段歆玥 / 译言·东西文库/电子工业出版社 / 2016-9 / 68
“创业者导师”——盖伊•川崎的《创业的艺术2.0》被阿丽亚娜•赫芬顿评为“终极的创业手册”。无论您是企业家、小企业主、企业开拓者还是非盈利组织的领导人,都可以让你的产品、服务或理念获得成功。 盖伊选取了不用角度,探索前十年商界的巨大变化,并寻求解决之道。曾经所向披靡的市场巨头深陷水深火热之中,社交媒体也取代了人际关系和广告,成为营销推广的主要渠道。众筹也成为广大投资者的可行之举。“云”更是每......一起来看看 《创业的艺术2.0》 这本书的介绍吧!