Lines 7023-7028
Link Here
|
7023 |
before and after this method. |
7023 |
before and after this method. |
7024 |
""" |
7024 |
""" |
7025 |
|
7025 |
|
|
|
7026 |
# When new_contents is supplied, the security check has already been |
7027 |
# done for this slot, so it shouldn't be repeated until the next |
7028 |
# replacement or unmerge operation. |
7029 |
if new_contents is None: |
7030 |
slot = self.vartree.dbapi.aux_get(self.mycpv, ["SLOT"])[0] |
7031 |
slot_matches = self.vartree.dbapi.match( |
7032 |
"%s:%s" % (dep_getkey(self.mycpv), slot)) |
7033 |
retval = self._security_check(slot_matches) |
7034 |
if retval: |
7035 |
return retval |
7036 |
|
7026 |
contents = self.getcontents() |
7037 |
contents = self.getcontents() |
7027 |
# Now, don't assume that the name of the ebuild is the same as the |
7038 |
# Now, don't assume that the name of the ebuild is the same as the |
7028 |
# name of the dir; the package may have been moved. |
7039 |
# name of the dir; the package may have been moved. |
Lines 7236-7247
Link Here
|
7236 |
writemsg_stdout("--- !md5 %s %s\n" % ("obj", obj)) |
7247 |
writemsg_stdout("--- !md5 %s %s\n" % ("obj", obj)) |
7237 |
continue |
7248 |
continue |
7238 |
try: |
7249 |
try: |
7239 |
if statobj.st_mode & (stat.S_ISUID | stat.S_ISGID): |
7250 |
# Remove permissions to ensure that any hardlinks to |
7240 |
# Always blind chmod 0 before unlinking to avoid race conditions. |
7251 |
# suid/sgid files are rendered harmless. |
7241 |
os.chmod(obj, 0000) |
7252 |
os.chmod(obj, 0) |
7242 |
if statobj.st_nlink > 1: |
|
|
7243 |
writemsg("setXid: "+str(statobj.st_nlink-1)+ \ |
7244 |
" hardlinks to '%s'\n" % obj) |
7245 |
os.unlink(obj) |
7253 |
os.unlink(obj) |
7246 |
except (OSError,IOError),e: |
7254 |
except (OSError,IOError),e: |
7247 |
pass |
7255 |
pass |
Lines 7305-7310
Link Here
|
7305 |
|
7313 |
|
7306 |
return False |
7314 |
return False |
7307 |
|
7315 |
|
|
|
7316 |
def _security_check(self, slot_matches): |
7317 |
if not slot_matches: |
7318 |
return 0 |
7319 |
file_paths = set() |
7320 |
for cpv in slot_matches: |
7321 |
file_paths.update(dblink(self.cat, catsplit(cpv)[1], |
7322 |
self.vartree.root, self.settings, |
7323 |
vartree=self.vartree).getcontents()) |
7324 |
inode_map = {} |
7325 |
for path in file_paths: |
7326 |
try: |
7327 |
s = os.lstat(path) |
7328 |
except OSError, e: |
7329 |
if e.errno != errno.ENOENT: |
7330 |
raise |
7331 |
del e |
7332 |
continue |
7333 |
if stat.S_ISREG(s.st_mode) and \ |
7334 |
s.st_nlink > 1 and \ |
7335 |
s.st_mode & (stat.S_ISUID | stat.S_ISGID): |
7336 |
k = (s.st_dev, s.st_ino) |
7337 |
inode_map.setdefault(k, []).append((path, s)) |
7338 |
suspicious_hardlinks = [] |
7339 |
for path_list in inode_map.itervalues(): |
7340 |
path, s = path_list[0] |
7341 |
if len(path_list) == s.st_nlink: |
7342 |
# All hardlinks seem to be owned by this package. |
7343 |
continue |
7344 |
suspicious_hardlinks.append(path_list) |
7345 |
if not suspicious_hardlinks: |
7346 |
return 0 |
7347 |
from output import colorize |
7348 |
prefix = colorize("SECURITY_WARN", "*") + " WARNING: " |
7349 |
writemsg(prefix + "suid/sgid file(s) " + \ |
7350 |
"with suspicious hardlink(s):\n", noiselevel=-1) |
7351 |
for path_list in suspicious_hardlinks: |
7352 |
for path, s in path_list: |
7353 |
writemsg(prefix + " '%s'\n" % path, noiselevel=-1) |
7354 |
writemsg(prefix + "See the Gentoo Security Handbook " + \ |
7355 |
"guide for advice on how to proceed.\n", noiselevel=-1) |
7356 |
return 1 |
7357 |
|
7308 |
def treewalk(self, srcroot, destroot, inforoot, myebuild, cleanup=0, |
7358 |
def treewalk(self, srcroot, destroot, inforoot, myebuild, cleanup=0, |
7309 |
mydbapi=None, prev_mtimes=None): |
7359 |
mydbapi=None, prev_mtimes=None): |
7310 |
""" |
7360 |
""" |
Lines 7352-7357
Link Here
|
7352 |
|
7402 |
|
7353 |
slot_matches = self.vartree.dbapi.match( |
7403 |
slot_matches = self.vartree.dbapi.match( |
7354 |
"%s:%s" % (self.mysplit[0], self.settings["SLOT"])) |
7404 |
"%s:%s" % (self.mysplit[0], self.settings["SLOT"])) |
|
|
7405 |
retval = self._security_check(slot_matches) |
7406 |
if retval: |
7407 |
return retval |
7408 |
|
7355 |
if slot_matches: |
7409 |
if slot_matches: |
7356 |
# Used by self.isprotected(). |
7410 |
# Used by self.isprotected(). |
7357 |
max_cpv = None |
7411 |
max_cpv = None |