* [musl] get/set*ent functions and real world applications @ 2021-10-11 13:32 (GalaxyMaster) 2021-10-11 17:18 ` Érico Nogueira 0 siblings, 1 reply; 7+ messages in thread From: (GalaxyMaster) @ 2021-10-11 13:32 UTC (permalink / raw) To: musl Hello, I really enjoy the consise language used in musl, however, I think I found one place where albeit the code is corect and elegant it does not produce secure outcome. I am talking about getpwent(), getgrent(), and their counterparts: putpwent() and putgrent(). All these functions behave well, when the input is well defined. However, given the nature of the files these functions are working with and the sensitivity of the information contained within, it is a point of potential abuse. On a Glibc-based system, if an erronneous entry like "user:x::1000::/home/user:/bin/bash" it will stay that way as an erroneous entry, but will be ignored, hence being harmless. On musl-based system, on the other hand, that entry would result in a root account due to the way atou() works in getpwent_a.c: === galaxy@musl:~/musl-tests $ cat test-ent.c #include <sys/types.h> #include <pwd.h> #include <stdio.h> #include <errno.h> int main() { struct passwd *pw; printf("Reading /etc/passwd:\n"); errno = 0; while ((pw = getpwent())) { printf("%s:%s:%u:%u:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); } if (errno != 0) return errno; return 0; } galaxy@musl:~/musl-tests $ tail -1 /etc/passwd user:x::1000::/home/user/: galaxy@musl:~/musl-tests $ ./test-ent | tail -1 user:x:0:1000::/home/user/: galaxy@musl:~/musl-tests $ === It is the same story with any numeric field in both /etc/passwd and /etc/group, empty fields magically turn into 0, which has a significant meaning on Un*x systems. The whole parssing of password and group entires is quite "dumb", in terms that it always expects perfectly valid input and produces always correct output, but I would argue that these functions should be a bit smarter and should not make assumptions about the validity of the input, i.e treat it as untrusted user input. Another example, where musl exhibits a different behaviour to Glibc is parsing of erroneous group entries (below, "group" misses the final ':'): === galaxy@musl:~/musl-tests $ cat test-gent.c #include <sys/types.h> #include <grp.h> #include <stdio.h> #include <errno.h> int main() { struct group *gr; char **p; printf("Reading /etc/group:"); errno = 0; while ((gr = getgrent())) { printf("%s:%s:%u:", gr->gr_name, gr->gr_passwd, gr->gr_gid); for (p =gr->gr_mem; *p; p++) { printf("%s%c", *p, *(p+1) ? ',' : '\n'); } if (p == gr->gr_mem) printf("\n"); } if (errno != 0) return errno; return 0; } galaxy@musl:~/musl-tests $ tail -2 /etc/group galaxy:x:502:group1,group2,group3 group:x:1000 galaxy@musl:~/musl-tests $ ./test-gent | tail -2 users:x:999: galaxy:x:502:group1,group2,group3 galaxy@musl:~/musl-tests $ === Glibc, on the other hand, fixes the not-so-broken record (since it is only supplemental groups which are missing): === [galaxy@archlinux musl-tests]$ tail -2 /etc/group pkgbuilder:x:1001:linux-is-fun,musl-rulez group:x:1000 [galaxy@archlinux musl-tests]$ ./test-gent | tail -2 pkgbuilder:x:1001:linux-is-fun,musl-rulez group:x:1000: [galaxy@archlinux musl-tests]$ === With put*() functions the situation a bit better, but still could be improved to achieve better compatibility. putpwent() will output '(null)' for any NULL pointer passed for the string arguments (due to direct call to fprintf() and the UB for that situation), while Glibc would output an empty string instead. Moreover, putpwent() is inconsistent with putgrent() -- the latter locks the file before writing and unlocks afterwards, while the former is just going ahead with fprintf(). I know these funnctions are thread unsafe, but this lack of locking makes putpwent() plainly dangerous on a multiuser system. Rich, would it be acceptable to align musl behaviour with Glibc's in this regard? I mean, consider missing uid/gid fields to be a critical error, so the record is dropped, and consider missing supplemental groups (together with the last separator) to be a minor, fixable error and preserve the record? This would make (at least my) life a bit easier in porting applications to a musl-based system, but more imprtantly, it will be less dangerous if an erroneous record crawls into one of the identity files. P.S. I also think that my version (in the example above) of going through supplemental groups looks nicer than the one in putgrent() :) -- (GM) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-11 13:32 [musl] get/set*ent functions and real world applications (GalaxyMaster) @ 2021-10-11 17:18 ` Érico Nogueira 2021-10-12 0:38 ` (GalaxyMaster) 2021-10-13 6:16 ` A. Wilcox 0 siblings, 2 replies; 7+ messages in thread From: Érico Nogueira @ 2021-10-11 17:18 UTC (permalink / raw) To: musl On Mon Oct 11, 2021 at 10:32 AM -03, (GalaxyMaster) wrote: > Hello, > > I really enjoy the consise language used in musl, however, I think I > found one > place where albeit the code is corect and elegant it does not produce > secure > outcome. I am talking about getpwent(), getgrent(), and their > counterparts: > putpwent() and putgrent(). > > All these functions behave well, when the input is well defined. > However, > given the nature of the files these functions are working with and the > sensitivity of the information contained within, it is a point of > potential > abuse. > > On a Glibc-based system, if an erronneous entry like > "user:x::1000::/home/user:/bin/bash" > it will stay that way as an erroneous entry, but will be ignored, hence > being harmless. > > On musl-based system, on the other hand, that entry would result in a > root > account due to the way atou() works in getpwent_a.c: > === > galaxy@musl:~/musl-tests $ cat test-ent.c > #include <sys/types.h> > #include <pwd.h> > #include <stdio.h> > #include <errno.h> > > int main() { > struct passwd *pw; > printf("Reading /etc/passwd:\n"); > errno = 0; > while ((pw = getpwent())) { > printf("%s:%s:%u:%u:%s:%s:%s\n", > pw->pw_name, pw->pw_passwd, pw->pw_uid, > pw->pw_gid, pw->pw_gecos, pw->pw_dir, > pw->pw_shell); > } > if (errno != 0) return errno; > return 0; > } > galaxy@musl:~/musl-tests $ tail -1 /etc/passwd > user:x::1000::/home/user/: > galaxy@musl:~/musl-tests $ ./test-ent | tail -1 > user:x:0:1000::/home/user/: > galaxy@musl:~/musl-tests $ > === > > It is the same story with any numeric field in both /etc/passwd and > /etc/group, > empty fields magically turn into 0, which has a significant meaning on > Un*x > systems. > > The whole parssing of password and group entires is quite "dumb", in > terms that > it always expects perfectly valid input and produces always correct > output, but > I would argue that these functions should be a bit smarter and should > not make > assumptions about the validity of the input, i.e treat it as untrusted > user > input. There's a reason it's recommended that one only make changes to these files using tools like the ones from the shadow suite. Things in /etc can, theoretically, only be written to by root or at least trusted users, so treating as entirely untrusted seems a bit over the top... That said, erroring out/skipping such entries sounds reasonable either way. > > Another example, where musl exhibits a different behaviour to Glibc is > parsing > of erroneous group entries (below, "group" misses the final ':'): > === > galaxy@musl:~/musl-tests $ cat test-gent.c > #include <sys/types.h> > #include <grp.h> > #include <stdio.h> > #include <errno.h> > > int main() { > struct group *gr; > char **p; > printf("Reading /etc/group:"); > errno = 0; > while ((gr = getgrent())) { > printf("%s:%s:%u:", > gr->gr_name, gr->gr_passwd, gr->gr_gid); > for (p =gr->gr_mem; *p; p++) { > printf("%s%c", *p, *(p+1) ? ',' : '\n'); > } > if (p == gr->gr_mem) printf("\n"); > } > if (errno != 0) return errno; > return 0; > } > galaxy@musl:~/musl-tests $ tail -2 /etc/group > galaxy:x:502:group1,group2,group3 > group:x:1000 > galaxy@musl:~/musl-tests $ ./test-gent | tail -2 > users:x:999: > galaxy:x:502:group1,group2,group3 > galaxy@musl:~/musl-tests $ > === > > Glibc, on the other hand, fixes the not-so-broken record (since it is > only > supplemental groups which are missing): > === > [galaxy@archlinux musl-tests]$ tail -2 /etc/group > pkgbuilder:x:1001:linux-is-fun,musl-rulez > group:x:1000 > [galaxy@archlinux musl-tests]$ ./test-gent | tail -2 > pkgbuilder:x:1001:linux-is-fun,musl-rulez > group:x:1000: > [galaxy@archlinux musl-tests]$ > === It seems like both libraries are inconsistent in their own ways. glibc skips malformed entries when some fields are missing, but fixes a missing supplemental group entry. musl skips a missing supplemental group entry, but "fixes" malformed entries with fields missing. Maybe striving for consistency by either always skipping or always fixing entries seems like a more reasonable choice to me, maybe? > > With put*() functions the situation a bit better, but still could be > improved to achieve better compatibility. putpwent() will output > '(null)' for any NULL pointer passed for the string arguments (due to > direct call to fprintf() and the UB for that situation), while Glibc > would output an empty string instead. It would seem the function returns EINVAL instead of outputting anything at all, from my look at the code. I think that's reasonable behavior for musl to implement, given how badly specified the function is. > Moreover, putpwent() is inconsistent with putgrent() -- the latter > locks the file before writing and unlocks afterwards, while the former > is just going ahead with fprintf(). I know these funnctions are thread > unsafe, but this lack of locking makes putpwent() plainly dangerous on > a multiuser system. I'm pretty sure these functions are always dangerous on multiuser systems; flockfile(3) is FILE level locking, it just protects from other threads touching a given FILE object. If you want to protect yourself from multiple programs handling the file simultaneously, you need file locking, such as done with fcntl(2). Regarding the inconsistency, it seems to have been this way since their introduction in ddfb267b0e72499f6022981733264a063ec881f0. Thinking about it more, it's necessary because putgrent(3) needs to print the first part of the record and then loop through the supplemental group list, which are multiple separate fprintf calls. Since putpwent(3) is a single fprintf call, which will lock the FILE object itself, there's no risk of corrupting the entries. > > Rich, would it be acceptable to align musl behaviour with Glibc's in > this > regard? I mean, consider missing uid/gid fields to be a critical error, > so the > record is dropped, and consider missing supplemental groups (together > with the > last separator) to be a minor, fixable error and preserve the record? > > This would make (at least my) life a bit easier in porting applications > to a > musl-based system, but more imprtantly, it will be less dangerous if an > erroneous record crawls into one of the identity files. > > P.S. I also think that my version (in the example above) of going > through > supplemental groups looks nicer than the one in putgrent() :) > > -- > (GM) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-11 17:18 ` Érico Nogueira @ 2021-10-12 0:38 ` (GalaxyMaster) 2021-10-12 15:58 ` Érico Nogueira 2021-10-13 6:16 ` A. Wilcox 1 sibling, 1 reply; 7+ messages in thread From: (GalaxyMaster) @ 2021-10-12 0:38 UTC (permalink / raw) To: musl Enrico, On Mon, Oct 11, 2021 at 02:18:47PM -0300, ??rico Nogueira wrote: > On Mon Oct 11, 2021 at 10:32 AM -03, (GalaxyMaster) wrote: > > > > The whole parssing of password and group entires is quite "dumb", in > > terms that > > it always expects perfectly valid input and produces always correct > > output, but > > I would argue that these functions should be a bit smarter and should > > not make > > assumptions about the validity of the input, i.e treat it as untrusted > > user > > input. > > There's a reason it's recommended that one only make changes to these > files using tools like the ones from the shadow suite. Things in /etc > can, theoretically, only be written to by root or at least trusted > users, so treating as entirely untrusted seems a bit over the top... Well, I prefer to treat anything external to my application as untrusted input, this saves time on troubleshooting weird issues later. In your statement above you put implicit trust into these abstract "trusted users", why guess what these could or could not do if we can handle the input in a safe and deterministic way? There was an argument on this list that libc should not treat/hide developer's mistakes and that's the reason you may see segfaults on a musl-based system more often (it is less forgiving to the poorly written code). Hoowever, I would argue that this particular case requires special treatment from libc since there is no way avoiding these functions if you are working with passwd/group based files. > It seems like both libraries are inconsistent in their own ways. glibc > skips malformed entries when some fields are missing, but fixes a > missing supplemental group entry. musl skips a missing supplemental > group entry, but "fixes" malformed entries with fields missing. > > Maybe striving for consistency by either always skipping or always > fixing entries seems like a more reasonable choice to me, maybe? I am not defending Glibc, but I find their approach to this matter consistent and expected from the common sense point of view. I would rather see musl aligned with it than try to convince everyone of yet another way of doing this. > > With put*() functions the situation a bit better, but still could be > > improved to achieve better compatibility. putpwent() will output > > '(null)' for any NULL pointer passed for the string arguments (due to > > direct call to fprintf() and the UB for that situation), while Glibc > > would output an empty string instead. > > It would seem the function returns EINVAL instead of outputting anything > at all, from my look at the code. I think that's reasonable behavior for > musl to implement, given how badly specified the function is. No, it is not behaving like that, it behaves exactly as I described: === galaxy@musl:~/musl-tests $ cat test-putpwent.c #include <sys/types.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> int main() { struct passwd *pw; FILE *fp; errno = 0; fp = fopen("test-putpwent.output", "w"); if (!fp || errno != 0) return errno; pw = malloc(sizeof(struct passwd)); pw->pw_name = pw->pw_passwd = pw->pw_gecos = pw->pw_dir, pw->pw_shell = NULL; putpwent(pw, fp); fclose(fp); return 0; } galaxy@musl:~/musl-tests $ ls -ld test-putpwent.output ls: cannot access 'test-putpwent.output': No such file or directory galaxy@musl:~/musl-tests $ ./test-putpwent galaxy@musl:~/musl-tests $ cat test-putpwent.output (null):(null):0:0:(null):(null):(null) galaxy@musl:~/musl-tests $ === On a Glibc system, the putpwent() call with pw->pw_name being NULL will fail to produce a record. If the pw->pw_name field is not NULL, then it will produce a record with the name followed by empty string fields, like "user::0:0:::", which is more expected in my opinion. > > Moreover, putpwent() is inconsistent with putgrent() -- the latter > > locks the file before writing and unlocks afterwards, while the former > > is just going ahead with fprintf(). I know these funnctions are thread > > unsafe, but this lack of locking makes putpwent() plainly dangerous on > > a multiuser system. > > I'm pretty sure these functions are always dangerous on multiuser > systems; flockfile(3) is FILE level locking, it just protects from other > threads touching a given FILE object. If you want to protect yourself > from multiple programs handling the file simultaneously, you need file > locking, such as done with fcntl(2). A fair point, I was not familiar with that function and somehow thought it was at the file level. I think that it is not libc's job to do file lockingi here, so I think we are fine in this regard. Thank you for explaining why there is an inconsistency, between putpwent() and putgrent() -- it makes sense. -- (GM) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-12 0:38 ` (GalaxyMaster) @ 2021-10-12 15:58 ` Érico Nogueira 2021-10-12 17:38 ` Érico Nogueira 0 siblings, 1 reply; 7+ messages in thread From: Érico Nogueira @ 2021-10-12 15:58 UTC (permalink / raw) To: musl On Mon Oct 11, 2021 at 9:38 PM -03, (GalaxyMaster) wrote: > Enrico, > > On Mon, Oct 11, 2021 at 02:18:47PM -0300, ??rico Nogueira wrote: > > On Mon Oct 11, 2021 at 10:32 AM -03, (GalaxyMaster) wrote: > > > > > > The whole parssing of password and group entires is quite "dumb", in > > > terms that > > > it always expects perfectly valid input and produces always correct > > > output, but > > > I would argue that these functions should be a bit smarter and should > > > not make > > > assumptions about the validity of the input, i.e treat it as untrusted > > > user > > > input. > > > > There's a reason it's recommended that one only make changes to these > > files using tools like the ones from the shadow suite. Things in /etc > > can, theoretically, only be written to by root or at least trusted > > users, so treating as entirely untrusted seems a bit over the top... > > Well, I prefer to treat anything external to my application as untrusted > input, > this saves time on troubleshooting weird issues later. In your statement > above you put implicit trust into these abstract "trusted users", why > guess > what these could or could not do if we can handle the input in a safe > and > deterministic way? There was an argument on this list that libc should > not > treat/hide developer's mistakes and that's the reason you may see > segfaults > on a musl-based system more often (it is less forgiving to the poorly > written > code). Hoowever, I would argue that this particular case requires > special > treatment from libc since there is no way avoiding these functions if > you > are working with passwd/group based files. It is untrusted input in that it shouldn't cause segfaults or other UB when it's misconfigured, but expecting applications to treat misconfigured entries the same way when you have applications using libc functions, Go standard library ones, probably some Rust application doing their own thing, means that the files really should be handled with care. Most systems will have *some* application treating misconfigured files in unexpected ways. However, this is not an argument for not fixing musl, as I said right below the part you quoted: That said, erroring out/skipping such entries sounds reasonable either way. > > > It seems like both libraries are inconsistent in their own ways. glibc > > skips malformed entries when some fields are missing, but fixes a > > missing supplemental group entry. musl skips a missing supplemental > > group entry, but "fixes" malformed entries with fields missing. > > > > Maybe striving for consistency by either always skipping or always > > fixing entries seems like a more reasonable choice to me, maybe? > > I am not defending Glibc, but I find their approach to this matter > consistent > and expected from the common sense point of view. I would rather see > musl > aligned with it than try to convince everyone of yet another way of > doing this. That's a fair point. > > > > With put*() functions the situation a bit better, but still could be > > > improved to achieve better compatibility. putpwent() will output > > > '(null)' for any NULL pointer passed for the string arguments (due to > > > direct call to fprintf() and the UB for that situation), while Glibc > > > would output an empty string instead. > > > > It would seem the function returns EINVAL instead of outputting anything > > at all, from my look at the code. I think that's reasonable behavior for > > musl to implement, given how badly specified the function is. > > No, it is not behaving like that, it behaves exactly as I described: > === > galaxy@musl:~/musl-tests $ cat test-putpwent.c > #include <sys/types.h> > #include <pwd.h> > #include <stdio.h> > #include <stdlib.h> > #include <errno.h> > > int main() { > struct passwd *pw; > FILE *fp; > errno = 0; > fp = fopen("test-putpwent.output", "w"); > if (!fp || errno != 0) return errno; > pw = malloc(sizeof(struct passwd)); > pw->pw_name = pw->pw_passwd = pw->pw_gecos = pw->pw_dir, pw->pw_shell = > NULL; > putpwent(pw, fp); > fclose(fp); > return 0; > } > galaxy@musl:~/musl-tests $ ls -ld test-putpwent.output > ls: cannot access 'test-putpwent.output': No such file or directory > galaxy@musl:~/musl-tests $ ./test-putpwent > galaxy@musl:~/musl-tests $ cat test-putpwent.output > (null):(null):0:0:(null):(null):(null) > galaxy@musl:~/musl-tests $ > === > > On a Glibc system, the putpwent() call with pw->pw_name being NULL will > fail to > produce a record. If the pw->pw_name field is not NULL, then it will > produce a > record with the name followed by empty string fields, like > "user::0:0:::", > which is more expected in my opinion. Sorry, I wasn't clear. I was talking about glibc's implementation: if (p == NULL || stream == NULL || p->pw_name == NULL || !__nss_valid_field (p->pw_name) || !__nss_valid_field (p->pw_passwd) || !__nss_valid_field (p->pw_dir) || !__nss_valid_field (p->pw_shell)) { __set_errno (EINVAL); return -1; } It requires that all of pw_name, pw_passwd, pw_dir and pw_shell be non null and only contain valid characters (that's what __nss_valid_field checks for, and it seems they are checking for pw_name==NULL twice, so I will see about sending a patch their way). So, requiring some specific fields is compatible with glibc's impl, and then for the other fields we should take care to print an empty string instead of "(null)". I think that's a pretty valid change to implement. > > > > Moreover, putpwent() is inconsistent with putgrent() -- the latter > > > locks the file before writing and unlocks afterwards, while the former > > > is just going ahead with fprintf(). I know these funnctions are thread > > > unsafe, but this lack of locking makes putpwent() plainly dangerous on > > > a multiuser system. > > > > I'm pretty sure these functions are always dangerous on multiuser > > systems; flockfile(3) is FILE level locking, it just protects from other > > threads touching a given FILE object. If you want to protect yourself > > from multiple programs handling the file simultaneously, you need file > > locking, such as done with fcntl(2). > > A fair point, I was not familiar with that function and somehow thought > it was at > the file level. I think that it is not libc's job to do file lockingi > here, so I > think we are fine in this regard. Thank you for explaining why there > is an inconsistency, between putpwent() and putgrent() -- it makes > sense. No worries :) > > -- > (GM) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-12 15:58 ` Érico Nogueira @ 2021-10-12 17:38 ` Érico Nogueira 0 siblings, 0 replies; 7+ messages in thread From: Érico Nogueira @ 2021-10-12 17:38 UTC (permalink / raw) To: musl On Tue Oct 12, 2021 at 12:58 PM -03, Érico Nogueira wrote: > On Mon Oct 11, 2021 at 9:38 PM -03, (GalaxyMaster) wrote: > > On a Glibc system, the putpwent() call with pw->pw_name being NULL will > > fail to > > produce a record. If the pw->pw_name field is not NULL, then it will > > produce a > > record with the name followed by empty string fields, like > > "user::0:0:::", > > which is more expected in my opinion. > > Sorry, I wasn't clear. I was talking about glibc's implementation: > > if (p == NULL || stream == NULL > || p->pw_name == NULL || !__nss_valid_field (p->pw_name) > || !__nss_valid_field (p->pw_passwd) > || !__nss_valid_field (p->pw_dir) > || !__nss_valid_field (p->pw_shell)) > { > __set_errno (EINVAL); > return -1; > } > > It requires that all of pw_name, pw_passwd, pw_dir and pw_shell be non > null and only contain valid characters (that's what __nss_valid_field > checks for, and it seems they are checking for pw_name==NULL twice, so I > will see about sending a patch their way). > > So, requiring some specific fields is compatible with glibc's impl, and > then for the other fields we should take care to print an empty string > instead of "(null)". I think that's a pretty valid change to implement. Ugh, my mistake. __nss_valid_field is only checking for invalid characters, those strings can be null. The only required string is indeed pw_name. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-11 17:18 ` Érico Nogueira 2021-10-12 0:38 ` (GalaxyMaster) @ 2021-10-13 6:16 ` A. Wilcox 2021-10-13 13:56 ` Rich Felker 1 sibling, 1 reply; 7+ messages in thread From: A. Wilcox @ 2021-10-13 6:16 UTC (permalink / raw) To: musl [-- Attachment #1: Type: text/plain, Size: 655 bytes --] On Oct 11, 2021, at 12:41 PM, Érico Nogueira <ericonr@disroot.org> wrote: > > Things in /etc > can, theoretically, only be written to by root or at least trusted > users, so treating as entirely untrusted seems a bit over the top... My understanding is that tcb exists explicitly to make these files modifiable by non-root users, to make the shadow tools unprivileged. I don't recall if GECOS or group fields are included in tcb, or if it is only the password itself. If the other fields are included, this is a much more important bug than otherwise. Best, -arw -- A. Wilcox (Sent from my iPhone) Mac, iOS, Linux software engineer [-- Attachment #2: Type: text/html, Size: 1156 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [musl] get/set*ent functions and real world applications 2021-10-13 6:16 ` A. Wilcox @ 2021-10-13 13:56 ` Rich Felker 0 siblings, 0 replies; 7+ messages in thread From: Rich Felker @ 2021-10-13 13:56 UTC (permalink / raw) To: A. Wilcox; +Cc: musl On Wed, Oct 13, 2021 at 01:16:30AM -0500, A. Wilcox wrote: > On Oct 11, 2021, at 12:41 PM, Érico Nogueira <ericonr@disroot.org> wrote: > > > > Things in /etc > > can, theoretically, only be written to by root or at least trusted > > users, so treating as entirely untrusted seems a bit over the top... > > My understanding is that tcb exists explicitly to make these files > modifiable by non-root users, to make the shadow tools unprivileged. > > I don't recall if GECOS or group fields are included in tcb, or if > it is only the password itself. If the other fields are included, > this is a much more important bug than otherwise. Users necessarily can't change their group memberships. They can't change anything in passwd db at all, only shadow, and only for themselves, and only if permissions are set so as to allow that. Rich ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-10-13 13:56 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-10-11 13:32 [musl] get/set*ent functions and real world applications (GalaxyMaster) 2021-10-11 17:18 ` Érico Nogueira 2021-10-12 0:38 ` (GalaxyMaster) 2021-10-12 15:58 ` Érico Nogueira 2021-10-12 17:38 ` Érico Nogueira 2021-10-13 6:16 ` A. Wilcox 2021-10-13 13:56 ` Rich Felker
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/musl/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).