From: Ben W. <be...@va...> - 2001-02-16 07:58:38
|
> union { > struct cmsghdr cm; // seems to be only for alignment > char control[CMSG_SPACE(sizeof (int)) + > CMSG_SPACE(sizeof(struct ucred)) + 1]; > } control_un; > > ...in read_printer():src/lpd.c ... I haven't tested that but the > code in glibc looks fishy (>= instead of >). > doesn't appear to be quite that simple. I've tried +1 and +100 and neither one works. Something looks hosered. > Also lps_get_connection() only has... > > union { > struct cmsghdr cm; > char control[CMSG_SPACE(sizeof(int))]; > } control_un; > > ...you might want to change the API so the caller can specify a creds > struct to use (this way a setuid() can use the real uid/gid instead of > the effective ones). Does that work? The kernel will let you pass either your credentials or your effective credentials? The way that I have it right now, the kernel adds the credentials. I wonder what would happen if you tried to pass both your real and effective credentials. > > -- > James Antill -- ja...@va... |
From: James A. <ja...@va...> - 2001-02-16 17:05:25
|
Ben Woodard <be...@va...> writes: > > I wonder what would happen if you tried > > to pass both your real and effective credentials. > > > > I also wonder if you can guarentee the order of cmsgheaders. For > example say you pass two file descriptors. On one side you load two > FD's A and B in that order. On the other side are you guarenteed to > get A and B out in the same order. As far as I know they will come out in the right order, _however_ just as if you did 2 write() on one end and 1 read on the other the kernel is allowed to send both fd's down the same connection. So you'll need enough space to store 1 cmsgcred struct and 2 fds inside a cmsg struct (or you'll lose the second fd, I think). The only other syncronisation point is that if you change the creds for the socket, then the recvmsg() at the other end will only get the data between each cred. Ie. write cred.uid = 1, data="blah", fd=1 write cred.uid = 2, data="abcd", fd=2 Then fd 1 and 2 will come out of recvmsg() in different recvmsg() calls, because of the cred change. -- James Antill -- ja...@va... |
From: James A. <ja...@an...> - 2001-02-19 16:57:26
|
Ben Woodard <be...@va...> writes: > > Ben Woodard <be...@va...> writes: > > > > > > union { > > > > struct cmsghdr cm; // seems to be only for alignment > > > > char control[CMSG_SPACE(sizeof (int)) + > > > > CMSG_SPACE(sizeof(struct ucred)) + 1]; > > > > } control_un; > > > > > > > > ...in read_printer():src/lpd.c ... I haven't tested that but the > > > > code in glibc looks fishy (>= instead of >). > > > > > > > > > > doesn't appear to be quite that simple. I've tried +1 and +100 and > > > neither one works. Something looks hosered. > > > > I forgot the kernel writes out a new length when it's finished, so > > try doing (as well as the + 1 above)... > > > > ++msg.msg_controllen; > > > > ...after you've called recvmsg(). > > > > Ah that was it. Do you want to report the bug in glibc or should I do it? > I think that you might do a better job explaining it. I'll do it. > This is like the 3rd bug I've found in glibc. It really makes me > wonder, why these haven't been discovered before. Does this mean that > I am the only person in the the free software world who is passing two > pieces of ancillary data at the same time? I wouldn't be surprised, I've also found a whole bunch of different bugs in glibc ... I don't think that the corner cases get tested much (at all ?:) combining that with the fact that they pretty much never release new versions with just bug fixes and you get RH 7.0. Bitter, me ... nahhh :). > I wonder if I specify the real credentials will the effective ones be > appended and in which order they will be passed. In other words does > it prepend or append. I sort of like the way that it works in Stevens > book, you get a fcred structure which the effective, and real > credentials plus a list of the groups that this user belongs to. I > guess I could write a patch to make it work that way. The way it works in Linux is that you specify you pid/uid/gid to go along with the data you are sending. Thus if you change your creds at the first write to the socket then the receiving end will only see one set of credentials for that connection. However if you change it after you've already sent some stuff then it'll work just as if you'd given the socket to another task and you both wrote down the socket separately. The BSD seems to be to pass the euid and all the groups that the process belongs to, which seems clumsy but copies the behaviour from somewhere. I'm not even sure how easy/possible it is to change the euid that is sent with the data (maybe calling seteuid() just automatically works next go -- as I understand Linux this isn't the case, but I haven't tried it). -- # James Antill -- ja...@an... :0: * ^From: .*james@and\.org /dev/null |
From: Ben W. <be...@va...> - 2001-02-16 08:04:51
|
> I wonder what would happen if you tried > to pass both your real and effective credentials. > I also wonder if you can guarentee the order of cmsgheaders. For example say you pass two file descriptors. On one side you load two FD's A and B in that order. On the other side are you guarenteed to get A and B out in the same order. -ben > > > > -- > > James Antill -- ja...@va... > > > _______________________________________________ > Lpr-discuss mailing list > Lpr...@li... > http://lists.sourceforge.net/lists/listinfo/lpr-discuss |
From: James A. <ja...@va...> - 2001-02-16 17:00:47
|
Ben Woodard <be...@va...> writes: > > union { > > struct cmsghdr cm; // seems to be only for alignment > > char control[CMSG_SPACE(sizeof (int)) + > > CMSG_SPACE(sizeof(struct ucred)) + 1]; > > } control_un; > > > > ...in read_printer():src/lpd.c ... I haven't tested that but the > > code in glibc looks fishy (>= instead of >). > > > > doesn't appear to be quite that simple. I've tried +1 and +100 and > neither one works. Something looks hosered. I forgot the kernel writes out a new length when it's finished, so try doing (as well as the + 1 above)... ++msg.msg_controllen; ...after you've called recvmsg(). > > Also lps_get_connection() only has... > > > > union { > > struct cmsghdr cm; > > char control[CMSG_SPACE(sizeof(int))]; > > } control_un; > > > > ...you might want to change the API so the caller can specify a creds > > struct to use (this way a setuid() can use the real uid/gid instead of > > the effective ones). > > Does that work? The kernel will let you pass either your credentials > or your effective credentials? The way that I have it right now, the > kernel adds the credentials. I wonder what would happen if you tried > to pass both your real and effective credentials. The actual test in Linux is... if ((creds->pid == current->pid || capable(CAP_SYS_ADMIN)) && ((creds->uid == current->uid || creds->uid == current->euid || creds->uid == current->suid) || capable(CAP_SETUID)) && ((creds->gid == current->gid || creds->gid == current->egid || creds->gid == current->sgid) || capable(CAP_SETGID))) { return 0; } ...where you can basically s/capable(CAP_SYS_ADMIN)/(current->euid == 0)/; suid/sgid is the saved versions. Also note that I'm pretty sure that the effective uid/gid are the _default_ ones that are passed (can't find the code block to make sure, but I think I've read the code like that before). -- James Antill -- ja...@va... |
From: Ben W. <be...@va...> - 2001-02-16 19:48:31
|
> Ben Woodard <be...@va...> writes: > > > > union { > > > struct cmsghdr cm; // seems to be only for alignment > > > char control[CMSG_SPACE(sizeof (int)) + > > > CMSG_SPACE(sizeof(struct ucred)) + 1]; > > > } control_un; > > > > > > ...in read_printer():src/lpd.c ... I haven't tested that but the > > > code in glibc looks fishy (>= instead of >). > > > > > > > doesn't appear to be quite that simple. I've tried +1 and +100 and > > neither one works. Something looks hosered. > > I forgot the kernel writes out a new length when it's finished, so > try doing (as well as the + 1 above)... > > ++msg.msg_controllen; > > ...after you've called recvmsg(). > Ah that was it. Do you want to report the bug in glibc or should I do it? I think that you might do a better job explaining it. This is like the 3rd bug I've found in glibc. It really makes me wonder, why these haven't been discovered before. Does this mean that I am the only person in the the free software world who is passing two pieces of ancillary data at the same time? > > > Also lps_get_connection() only has... > > > > > > union { > > > struct cmsghdr cm; > > > char control[CMSG_SPACE(sizeof(int))]; > > > } control_un; > > > > > > ...you might want to change the API so the caller can specify a creds > > > struct to use (this way a setuid() can use the real uid/gid instead of > > > the effective ones). > > > > Does that work? The kernel will let you pass either your credentials > > or your effective credentials? The way that I have it right now, the > > kernel adds the credentials. I wonder what would happen if you tried > > to pass both your real and effective credentials. > > The actual test in Linux is... > > if ((creds->pid == current->pid || capable(CAP_SYS_ADMIN)) && > ((creds->uid == current->uid || creds->uid == current->euid || > creds->uid == current->suid) || capable(CAP_SETUID)) && > ((creds->gid == current->gid || creds->gid == current->egid || > creds->gid == current->sgid) || capable(CAP_SETGID))) { > return 0; > } > > ...where you can basically s/capable(CAP_SYS_ADMIN)/(current->euid == 0)/; > > suid/sgid is the saved versions. Also note that I'm pretty sure that > the effective uid/gid are the _default_ ones that are passed (can't > find the code block to make sure, but I think I've read the code like > that before). I wonder if I specify the real credentials will the effective ones be appended and in which order they will be passed. In other words does it prepend or append. I sort of like the way that it works in Stevens book, you get a fcred structure which the effective, and real credentials plus a list of the groups that this user belongs to. I guess I could write a patch to make it work that way. > > -- > James Antill -- ja...@va... |