Skip to content

Commit 4a76c3b

Browse files
0introevgenyz
authored andcommitted
Handle virtual packages in dpkginfo probe
This change handles virtual packages in dpkginfo probe by parsing the "Provides" field of /var/lib/dpkg/status. Instead of relying on the "Package" field exclusively, this change also matches the requested package name with the package names listed in the "Provides" field. It should allow to query virtual package names like "system-log-daemon" to actually installed packages likes "rsyslog" and so on. See deb-control(5).
1 parent 8cf1954 commit 4a76c3b

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

src/OVAL/probes/unix/linux/dpkginfo-helper.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static int version(struct dpkginfo_reply_t *reply)
6868
struct dpkginfo_reply_t* dpkginfo_get_by_name(const char *name, int *err)
6969
{
7070
FILE *f;
71-
char buf[DPKG_STATUS_BUFFER_SIZE], path[PATH_MAX], *root, *key, *value;
71+
char buf[DPKG_STATUS_BUFFER_SIZE], path[PATH_MAX], *root, *key, *value, *p;
7272
struct dpkginfo_reply_t *reply;
7373

7474
*err = 0;
@@ -93,8 +93,14 @@ struct dpkginfo_reply_t* dpkginfo_get_by_name(const char *name, int *err)
9393
if (buf[0] == '\n') {
9494
// New package entry.
9595
if (reply != NULL) {
96-
// Package found.
97-
goto out;
96+
if (reply->name != NULL) {
97+
// Package found.
98+
goto out;
99+
} else {
100+
// Package not found yet.
101+
dpkginfo_free_reply(reply);
102+
reply = NULL;
103+
}
98104
}
99105
continue;
100106
}
@@ -113,12 +119,12 @@ struct dpkginfo_reply_t* dpkginfo_get_by_name(const char *name, int *err)
113119
value = trimleft(value);
114120
// Package should be the first line.
115121
if (strcmp(key, "Package") == 0) {
122+
if (reply != NULL)
123+
continue;
124+
reply = calloc(1, sizeof(*reply));
125+
if (reply == NULL)
126+
goto err;
116127
if (strcmp(value, name) == 0) {
117-
if (reply != NULL)
118-
continue;
119-
reply = calloc(1, sizeof(*reply));
120-
if (reply == NULL)
121-
goto err;
122128
reply->name = strdup(value);
123129
if (reply->name == NULL)
124130
goto err;
@@ -142,6 +148,23 @@ struct dpkginfo_reply_t* dpkginfo_get_by_name(const char *name, int *err)
142148
goto err;
143149
if (version(reply) < 0)
144150
goto err;
151+
} else if (strcmp(key, "Provides") == 0) {
152+
// Handle virtual packages.
153+
char *s = strtok(value, ",");
154+
while (s != NULL) {
155+
s = trimleft(s);
156+
// Ignore version.
157+
p = strchr(s, ' ');
158+
if (p != NULL)
159+
*p++ = '\0';
160+
if (strcmp(s, name) == 0) {
161+
reply->name = strdup(value);
162+
if (reply->name == NULL)
163+
goto err;
164+
break;
165+
}
166+
s = strtok(NULL, ",");
167+
}
145168
}
146169
}
147170
}

0 commit comments

Comments
 (0)