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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
#!/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_object_needed():
var_db_pkg = '/var/db/pkg'
object_needed = {}
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])
object_needed[elf] = sonames
except IOError:
continue #File probably doesn't exist, which is okay
return object_needed
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 -d [-v] delete XATTR_PAX on all system ELF objects')
print(' : migrate [-h] print out this help')
print(' : -v be verbose when migrating')
print('')
def main():
# Are we root?
uid = os.getuid()
if uid != 0:
print('This program must be run as root')
sys.exit(1)
try:
opts, args = getopt.getopt(sys.argv[1:], 'vmdh')
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_deleteall = 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 == '-d':
do_deleteall = 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 do_usage:
run_usage()
sys.exit(0)
if opt_count == 0 or opt_count > 2 or ( do_migration and do_deleteall):
run_usage()
sys.exit(1)
# Do we have XATTR_PAX support?
if do_migration or do_deleteall:
try:
from pax import deletextpax
except ImportError:
print('ERROR: Python module pax.so was compiled without XATTR_PAX support, cannot migrate or delete XATTR_PAX')
sys.exit(1)
object_needed = get_object_needed()
fail = []
none = []
for elf in object_needed:
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)
if do_deleteall:
pax.deletextpax(elf)
# 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.PaxError:
if uid == 0:
fail.append(elf)
if verbose:
print("FAIL: %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()
|