Skip to content
This repository was archived by the owner on Sep 16, 2022. It is now read-only.

Detect and send kernel metapackages#276

Merged
vpetersson merged 13 commits into
WoTTsecurity:masterfrom
GreatFruitOmsk:750-show-kernel-meta-package
Mar 19, 2020
Merged

Detect and send kernel metapackages#276
vpetersson merged 13 commits into
WoTTsecurity:masterfrom
GreatFruitOmsk:750-show-kernel-meta-package

Conversation

@rptrchv

@rptrchv rptrchv commented Mar 9, 2020

Copy link
Copy Markdown
Contributor

Closes #268

@cla-bot cla-bot Bot added the cla-signed label Mar 9, 2020
@rptrchv
rptrchv requested a review from a-martynovich March 9, 2020 08:08
@vpetersson

Copy link
Copy Markdown
Contributor

@rptrchv Check the Codacity errors. It's complaining about code quality.

@a-martynovich a-martynovich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many issues with this.
First, you use regexes for parsing the version from the package name. This will easily break because the package name may contain more dashes than your regex expects (look at https://packages.debian.org/jessie/linux-image-3.16.0-10-amd64 section "similar packages). Second, you're assuming that you can simply compare those packages by one number in their name, which will also break in many cases.

There is an easier and more robust solution. For every installed linux-image-... find its parent (the package which depends on it). Kernels which are not the latest version won't have a parent. Only the kernel of the latest version will have a parent, and that (or a level higher, if Ubuntu) is the meta-package. Also this way you can find out if the currently running kernel package does not match the meta-package, which means reboot is required (the new kernel was just installed).

@rptrchv

rptrchv commented Mar 12, 2020

Copy link
Copy Markdown
Contributor Author

@a-martynovich

First, you use regexes for parsing the version from the package name. This will easily break because the package name may contain more dashes than your regex expects (look at https://packages.debian.org/jessie/linux-image-3.16.0-10-amd64 section "similar packages).

Those kernels (that don't match my re pattern) are very exotic. Besides, this re pattern can be easily adjusted to support them too: r'(.+-\d+.\d+.\d+-)(\d+)([\.-].+)'.

Second, you're assuming that you can simply compare those packages by one number in their name, which will also break in many cases.

For kernels of all (available to me for check) platforms and distro versions it works. So this solution is not perfect (will not cover non-standard versions naming) but more than satisfactory.

There is an easier and more robust solution. For every installed linux-image-... find its parent (the package which depends on it). Kernels which are not the latest version won't have a parent. Only the kernel of the latest version will have a parent, and that (or a level higher, if Ubuntu) is the meta-package.

We can't simply check all installed "linux-image-..." packages because there might be installed several different kernel types on a machine, e.g. "linux-image-4.15.0-XXX-aws" and "linux-image-4.15.0-XXX-generic". So we need to check for parents existence only kernel image packages of the same type as our running kernel (that's what my "get_latest_same_kernel_deb" function does now). Which again relies on re patterns matching, which in turn is not 100% reliable (as you pointed out). So your proposed solution has the same potential issue as mine.

@a-martynovich

Copy link
Copy Markdown
Contributor

@rptrchv I see your point and I can't come up with any easier solution now.
I won't ask you to write unit tests because I guess it's going to be more code than the real code itself. But please list which distros and which kernel packages you've tested on.

@rptrchv
rptrchv force-pushed the 750-show-kernel-meta-package branch from 69e04f3 to ffdeed3 Compare March 19, 2020 06:25
@rptrchv
rptrchv requested a review from a-martynovich March 19, 2020 06:53

@a-martynovich a-martynovich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Codacy shows 12 new issues, some of which you told me to correct in my PRs.
  2. I suggest renaming is_amazon2() to smth like is_rhel() (and changing detection accordingly to match RHEL, CentOS and Amazon Linux) because the logic will most probably be the same for RHEL, CentOS and Amazon Linux when it comes to RPM packages.
  3. Codacy shows 12 new issues, some of which you told me to correct in my PRs.

Comment thread agent/os_helper.py Outdated
# No systemd - probably yum-cron is not running
# TODO: use "service" executable which also works without systemd and on older systems
return False
from sh import systemctl

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this so it wouldn't fail if running in container. Why did you change this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest renaming is_amazon2()

I don't agree. We can do that only after testing everything on RHEL and CentOS, not beforehand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you replied to a different comment

Comment thread agent/os_helper.py
if match:
name_parts = match.groups() # E.g. ('linux-image-4.4.0-', '174', '-generic')
latest_kernel_pkg = get_latest_same_kernel_deb(name_parts[0], name_parts[2])
return apt_pkg.version_compare(latest_kernel_pkg.installed.version, kernel_pkg.installed.version) > 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only newer? Can't we install older version? I think this should be != 0 i.e. not equal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need reboot only when we have a newer version of the running kernel package installed. That exactly what my code does. I don't catch your point.

Comment thread agent/os_helper.py
if kernel_pkg is not None:
match = DEBIAN_KERNEL_PKG_NAME_RE.match(kernel_pkg.name)
if match:
name_parts = match.groups() # E.g. ('linux-image-4.4.0-', '174', '-generic')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we change this regex to linux-image-\d+\.\d+\.\d+\.-\d+-.+ since we actually expect it to look like that? This way we don't accidentally catch packets which we don't know.

Comment thread agent/os_helper.py Outdated
if __file__.encode() in package_header[rpm.RPMTAG_FILENAMES]:
return Installation.RPM
# Other.
import agent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from agent import __version__?

Comment thread agent/os_helper.py
'version': kernel_pkg.installed.version,
'source_name': kernel_pkg.installed.source_name,
'source_version': kernel_pkg.installed.source_version,
'arch': kernel_pkg.installed.architecture

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need .installed because get_kernel_deb_package already checks for that (is_installed).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.installed here is a quite different thing

Comment thread agent/os_helper.py
match = DEBIAN_KERNEL_PKG_NAME_RE.match(kernel_pkg.name)
if match:
name_parts = match.groups() # E.g. ('linux-image-4.4.0-', '174', '-generic')
latest_kernel_pkg = get_latest_same_kernel_deb(name_parts[0], name_parts[2])

@a-martynovich a-martynovich Mar 19, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may break in case of linux-gcp to linux-gcp-edge upgrade. Basically it will be linux-image-5.0.0-xxxx-gcp -> linux-image-5.3.0-xxxx-gcp.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But it's not that simple to properly handle it. That's why I believe the major kernel version upgrade case is out of the scope of this task and deserves a separate task.

@a-martynovich
a-martynovich self-requested a review March 19, 2020 16:01

@a-martynovich a-martynovich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still do not agree with the way this task was done, but it should work, so I'm not holding it any longer.

@vpetersson

Copy link
Copy Markdown
Contributor

@a-martynovich can you give me a tl;dr how you think this should be redesigned? In the meantime, I'm merging this.

@vpetersson
vpetersson merged commit 9e3184c into WoTTsecurity:master Mar 19, 2020
@a-martynovich

Copy link
Copy Markdown
Contributor

I think it should build a dependency tree from any known kernel meta-package down to a concrete kernel package and not rely on package names. This also has some edge cases, though.

@vpetersson

Copy link
Copy Markdown
Contributor

Ok, I'll create a new ticket for that.

@a-martynovich

Copy link
Copy Markdown
Contributor

@vpetersson we still need to expand this on Debian support, so yes, a ticket is needed.
On Debian everything is completely different, as we've recently learned.

@vpetersson vpetersson mentioned this pull request Mar 19, 2020
2 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect and send kernel metapacakages

4 participants