Skip to content

Commit 82c85df

Browse files
committed
bin/xbps-pkgdb: check file and symlink owners & perms
1 parent 0b06fcd commit 82c85df

File tree

2 files changed

+125
-28
lines changed

2 files changed

+125
-28
lines changed

bin/xbps-pkgdb/check_pkg_files.c

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@
4343
* o Check the hash for all installed files, except
4444
* configuration files (which is expected if they are modified).
4545
*
46-
* o Compares stored file modification time.
46+
* o Check the mode for all installed files, except configuration files.
47+
*
48+
* o Check the owner for all installed files, except configuration files.
49+
*
50+
* o Check the group for all installed files, except configuration files.
4751
*
4852
* Return 0 if test ran successfully, 1 otherwise and -1 on error.
4953
*/
@@ -55,10 +59,11 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
5559
xbps_object_t obj;
5660
xbps_object_iterator_t iter;
5761
xbps_dictionary_t pkg_filesd = arg;
58-
const char *file = NULL, *sha256 = NULL;
62+
const char *file = NULL, *sha256 = NULL, *owner = NULL, *group = NULL;
5963
char *path;
60-
bool mutable, test_broken = false;
64+
bool mutable, test_broken = false, noexist = false;
6165
int rv = 0, errors = 0;
66+
mode_t mode = 0;
6267

6368
array = xbps_dictionary_get(pkg_filesd, "files");
6469
if (array != NULL && xbps_array_count(array) > 0) {
@@ -67,44 +72,102 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
6772
return -1;
6873

6974
while ((obj = xbps_object_iterator_next(iter))) {
75+
noexist = mutable = false;
76+
7077
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
7178
/* skip noextract files */
7279
if (xhp->noextract && xbps_patterns_match(xhp->noextract, file))
7380
continue;
7481
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
75-
xbps_dictionary_get_cstring_nocopy(obj,
76-
"sha256", &sha256);
82+
83+
xbps_dictionary_get_bool(obj, "mutable", &mutable);
84+
85+
/* check sha256 */
86+
xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256);
7787
rv = xbps_file_sha256_check(path, sha256);
7888
switch (rv) {
7989
case 0:
80-
free(path);
8190
break;
8291
case ENOENT:
83-
xbps_error_printf("%s: unexistent file %s.\n",
84-
pkgname, file);
85-
free(path);
86-
test_broken = true;
92+
xbps_error_printf("%s: unexistent file %s.\n", pkgname, file);
93+
test_broken = noexist = true;
8794
break;
8895
case ERANGE:
89-
mutable = false;
90-
xbps_dictionary_get_bool(obj,
91-
"mutable", &mutable);
9296
if (!mutable) {
93-
xbps_error_printf("%s: hash mismatch "
94-
"for %s.\n", pkgname, file);
97+
xbps_error_printf("%s: hash mismatch for %s.\n", pkgname, file);
9598
test_broken = true;
9699
}
97-
free(path);
98100
break;
99101
default:
100-
xbps_error_printf(
101-
"%s: can't check `%s' (%s)\n",
102-
pkgname, file, strerror(rv));
103-
free(path);
102+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
104103
break;
105104
}
106-
}
107-
xbps_object_iterator_release(iter);
105+
106+
if (noexist) {
107+
free(path);
108+
continue;
109+
}
110+
111+
/* check mode */
112+
mode = 0;
113+
if (xbps_dictionary_get_uint32(obj, "mode", &mode)) {
114+
rv = xbps_file_mode_check(path, mode);
115+
switch (rv) {
116+
case 0:
117+
break;
118+
case ERANGE:
119+
if (!mutable) {
120+
xbps_error_printf("%s: mode mismatch for %s.\n", pkgname, file);
121+
test_broken = true;
122+
}
123+
break;
124+
default:
125+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
126+
break;
127+
}
128+
}
129+
130+
/* check owner */
131+
owner = NULL;
132+
if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
133+
rv = xbps_file_owner_check(path, owner);
134+
switch (rv) {
135+
case 0:
136+
break;
137+
case ERANGE:
138+
if (!mutable) {
139+
xbps_error_printf("%s: owner mismatch for %s.\n", pkgname, file);
140+
test_broken = true;
141+
}
142+
break;
143+
default:
144+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
145+
break;
146+
}
147+
}
148+
149+
/* check group */
150+
group = NULL;
151+
if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
152+
rv = xbps_file_group_check(path, group);
153+
switch (rv) {
154+
case 0:
155+
break;
156+
case ERANGE:
157+
if (!mutable) {
158+
xbps_error_printf("%s: group mismatch for %s.\n", pkgname, file);
159+
test_broken = true;
160+
}
161+
break;
162+
default:
163+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
164+
break;
165+
}
166+
}
167+
168+
free(path);
169+
}
170+
xbps_object_iterator_release(iter);
108171
}
109172
if (test_broken) {
110173
xbps_error_printf("%s: files check FAILED.\n", pkgname);

bin/xbps-pkgdb/check_pkg_symlinks.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@
4141
* The following task is accomplished in this file:
4242
*
4343
* o Check for target file in symlinks, so that we can check that
44-
* they have not been modified.
44+
* they have not been modified or broken.
4545
*
46-
* returns 0 if test ran successfully, 1 otherwise and -1 on error.
46+
* o Check for symlink ownership.
47+
*
48+
* returns 0 if test ran successfully and -1 on error.
4749
*/
4850

4951
int
@@ -52,14 +54,15 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
5254
xbps_array_t array;
5355
xbps_object_t obj;
5456
xbps_dictionary_t filesd = arg;
57+
bool test_broken = false;
5558
int rv = 0;
5659

5760
array = xbps_dictionary_get(filesd, "links");
5861
if (array == NULL)
5962
return 0;
6063

6164
for (unsigned int i = 0; i < xbps_array_count(array); i++) {
62-
const char *file = NULL, *tgt = NULL;
65+
const char *file = NULL, *tgt = NULL, *owner = NULL, *group = NULL;
6366
char path[PATH_MAX], *lnk = NULL;
6467

6568
obj = xbps_array_get(array, i);
@@ -83,16 +86,47 @@ check_pkg_symlinks(struct xbps_handle *xhp, const char *pkgname, void *arg)
8386
snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file);
8487
if ((lnk = xbps_symlink_target(xhp, path, tgt)) == NULL) {
8588
xbps_error_printf("%s: broken symlink %s (target: %s)\n", pkgname, file, tgt);
86-
rv = -1;
89+
test_broken = true;
8790
continue;
8891
}
8992
if (strcmp(lnk, tgt)) {
9093
xbps_warn_printf("%s: modified symlink %s "
9194
"points to %s (shall be %s)\n",
9295
pkgname, file, lnk, tgt);
93-
rv = -1;
96+
test_broken = true;
97+
}
98+
99+
if (xbps_dictionary_get_cstring_nocopy(obj, "owner", &owner)) {
100+
rv = xbps_file_owner_check(path, owner);
101+
switch (rv) {
102+
case 0:
103+
break;
104+
case ERANGE:
105+
xbps_error_printf("%s: owner mismatch for %s.\n", pkgname, file);
106+
test_broken = true;
107+
break;
108+
default:
109+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
110+
break;
111+
}
94112
}
113+
114+
if (xbps_dictionary_get_cstring_nocopy(obj, "group", &group)) {
115+
rv = xbps_file_group_check(path, group);
116+
switch (rv) {
117+
case 0:
118+
break;
119+
case ERANGE:
120+
xbps_error_printf("%s: group mismatch for %s.\n", pkgname, file);
121+
test_broken = true;
122+
break;
123+
default:
124+
xbps_error_printf("%s: can't check `%s' (%s)\n", pkgname, file, strerror(rv));
125+
break;
126+
}
127+
}
128+
95129
free(lnk);
96130
}
97-
return rv;
131+
return test_broken ? -1 : 0;
98132
}

0 commit comments

Comments
 (0)