Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 81097 | Differences between
and this patch

Collapse All | Expand All

(-)pym/output.py (+1 lines)
Lines 127-132 Link Here
127
# Portage functions
127
# Portage functions
128
codes["INFORM"] = codes["darkgreen"]
128
codes["INFORM"] = codes["darkgreen"]
129
codes["UNMERGE_WARN"] = codes["red"]
129
codes["UNMERGE_WARN"] = codes["red"]
130
codes["SECURITY_WARN"] = codes["red"]
130
codes["MERGE_LIST_PROGRESS"] = codes["yellow"]
131
codes["MERGE_LIST_PROGRESS"] = codes["yellow"]
131
132
132
def parse_color_map():
133
def parse_color_map():
(-)pym/portage.py (-6 / +60 lines)
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

Return to bug 81097