summaryrefslogtreecommitdiff
path: root/meta/classes/insane.bbclass
blob: b3fc72a4656c595509e8f2ec486245c6c14eedb4 (plain)
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
# BB Class inspired by ebuild.sh
#
# This class will test files after installation for certain
# security issues and other kind of issues.
#
# Checks we do:
#  -Check the ownership and permissions
#  -Check the RUNTIME path for the $TMPDIR
#  -Check if .la files wrongly point to workdir
#  -Check if .pc files wrongly point to workdir
#  -Check if packages contains .debug directories  or .so files where they should be in -dev or -dbg
#


#
# We need to have the scanelf utility as soon as
# possible and this is contained within the pax-utils-native
#


# We play a special package function
inherit package
PACKAGE_DEPENDS += "pax-utils-native"
PACKAGEFUNCS += " do_package_qa "

def package_qa_check_rpath(file,name,d):
    """
    Check for dangerous RPATHs
    """
    import bb, os
    scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR_NATIVE',d,True),'scanelf')
    bad_dir = bb.data.getVar('TMPDIR', d, True) + "/work"
    if not os.path.exists(scanelf):
        bb.note("Can not check RPATH scanelf not found")
    if not bad_dir in bb.data.getVar('WORKDIR', d, True):
        bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check")

    output = os.popen("%s -Byr %s" % (scanelf,file))
    txt    = output.readline().rsplit()
    if bad_dir in txt:
        bb.fatal("QA Issue package %s contains bad RPATH %s in file %s" % (name, txt, file))

    pass

def package_qa_check_devdbg(path, name,d):
    """
    Check for debug remains inside the binary or
    non dev packages containing
    """

    import bb, os
    if not "-dev" in name:
        if path[-3:] == ".so" and os.path.islink(path):
            bb.fatal("QA Issue: non -dev package %s contains symlink .so: %s" % name)

    if not "-dbg" in name:
        if '.debug' in path:
            bb.fatal("QA Issue: non -dbg package contains .debug directory: %s" % name)

def package_qa_check_perm(path,name,d):
    """
    Check the permission of files
    """
    pass

def package_qa_check_arch(path,name,d):
    """
    Check if archs are compatible
    """
    pass

def package_qa_check_pcla(path,name,d):
    """
    .pc and .la files should not point
    """

def package_qa_check_staged(path,d):
    """
    Check staged la and pc files for sanity
      -e.g. installed being false
    """
    pass

# Walk over all files in a directory and call func
def package_qa_walk(path, funcs, package,d):
    import os
    for root, dirs, files in os.walk(path):
        for file in files:
            path = os.path.join(root,file)
            for func in funcs:
                func(path, package, d)


def package_qa_check_rdepends(pkg, workdir, d):
    import bb	
    if not "-dbg" in pkg and not "task-" in pkg and not "-image" in pkg:
        # Copied from package_ipk.bbclass
        # boiler plate to update the data
        localdata = bb.data.createCopy(d)
        root = "%s/install/%s" % (workdir, pkg)

        bb.data.setVar('ROOT', '', localdata) 
        bb.data.setVar('ROOT_%s' % pkg, root, localdata)
        pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1)
        if not pkgname:
            pkgname = pkg
        bb.data.setVar('PKG', pkgname, localdata)

        overrides = bb.data.getVar('OVERRIDES', localdata)
        if not overrides:
            raise bb.build.FuncFailed('OVERRIDES not defined')
        overrides = bb.data.expand(overrides, localdata)
        bb.data.setVar('OVERRIDES', overrides + ':' + pkg, localdata)

        bb.data.update_data(localdata)

        # Now check the RDEPENDS
        rdepends = explode_deps(bb.data.getVar('RDEPENDS', localdata, True) or "")


        # Now do the sanity check!!!
        for rdepend in rdepends:
            if "-dbg" in rdepend:
                bb.fatal("QA issue, koen give us a better msg!!!")

# The PACKAGE FUNC to scan each package
python do_package_qa () {
    bb.note("DO PACKAGE QA")
    workdir = bb.data.getVar('WORKDIR', d, True)
    packages = bb.data.getVar('PACKAGES',d, True)

    # no packages should be scanned
    if not packages:
        return

    for package in packages.split():
        # Nasty hack for now until we can mark exclusions in the packages.
        # db has a unusual versioning scheme. Cannot fix this.
        # gcc contains symlinks to other packages. Cannot fix.
        # elfutils has symlinks to point to correct .so files. Cannot fix.
        # networkmanager needs to be split into app/lib packages. Can fix.
        if package in [ 'db', 'gcc', 'elfutils', 'networkmanager' ]:
            bb.note("Package: %s (skipped)" % package)
            continue
        
        bb.note("Package: %s" % package)
        path = "%s/install/%s" % (workdir, package)
        package_qa_walk(path, [package_qa_check_rpath, package_qa_check_devdbg, package_qa_check_perm, package_qa_check_arch], package, d)
        package_qa_check_rdepends(package, workdir, d)
}


# The Staging Func, to check all staging
addtask qa_staging after do_populate_staging before do_build
python do_qa_staging() {
    bb.note("Staged!")

    package_qa_check_staged(bb.data.getVar('STAGING_DIR',d,True), d)
}