1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#!/usr/bin/env python
#
# Note: This alternative way of doing revdep-pax only
# works on Gentoo systems where NEEDED.ELF.2 all the
# information we need generated by scanelf during emerge.
#
# See /usr/lib/portage/bin/misc-functions.sh ~line 520
# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
#
import os
import re
import getopt
import sys
import pax
def get_forward_linkings():
var_db_pkg = '/var/db/pkg'
forward_linkings = {}
for cat in os.listdir(var_db_pkg):
catdir = '%s/%s' % (var_db_pkg, cat)
for pkg in os.listdir(catdir):
pkgdir = '%s/%s' % (catdir, pkg)
need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
try:
g = open(need, 'r')
needs = g.readlines()
for line in needs:
line = line.strip()
link = re.split(';', line)
elf = link[1]
sonames = re.split(',', link[4])
forward_linkings[elf] = sonames
except IOError:
continue #File probably doesn't exist, which is okay
return forward_linkings
def run_usage():
print('Package Name : elfix')
print('Bug Reports : http://bugs.gentoo.org/')
print('Program Name : migrate')
print('Description : Migrate PT_PAX to XATTR_PAX Flags on all system ELF objects')
print(),
print('Usage : migrate -v print out all system ELF objects')
print(' : migrate -m [-v] migrate flags on all system ELF objects')
print(' : migrate [-h] print out this help')
print(' : -v be verbose when migrating')
print()
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 'mv')
except getopt.GetoptError as err:
print(str(err)) # will print something like 'option -a not recognized'
run_usage()
sys.exit(1)
verbose = False
do_migration = False
do_usage = False
opt_count = 0
for o, a in opts:
if o == '-v':
verbose = True
opt_count += 1
elif o == '-m':
do_migration = True
opt_count += 1
elif o == '-h':
do_usage = True
opt_count += 1
else:
print('Option included in getopt but not handled here!')
print('Please file a bug')
sys.exit(1)
if opt_count == 0 or do_usage:
run_usage()
sys.exit(0)
uid = os.getuid()
if uid != 0 and do_migration:
print('RUN AS ROOT: cannot migrate flags')
sys.exit(0)
forward_linkings = get_forward_linkings()
fail = []
none = []
for elf in forward_linkings:
try:
flags = pax.getflags(elf)[0]
if flags:
if verbose:
print("%s %s" % (flags, elf))
else:
none.append(elf)
if verbose:
print("NONE: %s" % elf)
if do_migration:
flags = re.sub('-','',flags)
pax.setstrflags(elf, flags)
# We should never get here, because you can
# always getflags() via pax.so since you can
# read PT_PAX even from a busy text file, and
# you can always set the pax flags with pax.so
# even on a busy text file because it will skip
# setting PT_PAX and only set the XATTR_PAX
except pax.error:
if uid == 0:
fail.append(elf)
if verbose:
print("BUSY: %s" % elf)
if verbose:
if fail:
print('\n')
print("ELF executables for which the migration failed:")
for elf in fail:
print("\t%s" % elf)
if none:
print('\n')
print("ELF executables lacking PT_PAX:")
for elf in none:
print("\t%s" % elf)
if __name__ == '__main__':
main()
|