Skip to content

Commit 95fa0c7

Browse files
aharivelbonzini
authored andcommitted
qio: add support for SO_PEERCRED for socket channel
The function qio_channel_get_peercred() returns a pointer to the credentials of the peer process connected to this socket. This credentials structure is defined in <sys/socket.h> as follows: struct ucred { pid_t pid; /* Process ID of the sending process */ uid_t uid; /* User ID of the sending process */ gid_t gid; /* Group ID of the sending process */ }; The use of this function is possible only for connected AF_UNIX stream sockets and for AF_UNIX stream and datagram socket pairs. On platform other than Linux, the function return 0. Signed-off-by: Anthony Harivel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 13be929 commit 95fa0c7

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

include/io/channel.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ struct QIOChannelClass {
160160
void *opaque);
161161
int (*io_flush)(QIOChannel *ioc,
162162
Error **errp);
163+
int (*io_peerpid)(QIOChannel *ioc,
164+
unsigned int *pid,
165+
Error **errp);
163166
};
164167

165168
/* General I/O handling functions */
@@ -981,4 +984,22 @@ int coroutine_mixed_fn qio_channel_writev_full_all(QIOChannel *ioc,
981984
int qio_channel_flush(QIOChannel *ioc,
982985
Error **errp);
983986

987+
/**
988+
* qio_channel_get_peercred:
989+
* @ioc: the channel object
990+
* @pid: pointer to pid
991+
* @errp: pointer to a NULL-initialized error object
992+
*
993+
* Returns the pid of the peer process connected to this socket.
994+
*
995+
* The use of this function is possible only for connected
996+
* AF_UNIX stream sockets and for AF_UNIX stream and datagram
997+
* socket pairs on Linux.
998+
* Return -1 on error with pid -1 for the non-Linux OS.
999+
*
1000+
*/
1001+
int qio_channel_get_peerpid(QIOChannel *ioc,
1002+
unsigned int *pid,
1003+
Error **errp);
1004+
9841005
#endif /* QIO_CHANNEL_H */

io/channel-socket.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,33 @@ qio_channel_socket_set_cork(QIOChannel *ioc,
841841
socket_set_cork(sioc->fd, v);
842842
}
843843

844+
static int
845+
qio_channel_socket_get_peerpid(QIOChannel *ioc,
846+
unsigned int *pid,
847+
Error **errp)
848+
{
849+
#ifdef CONFIG_LINUX
850+
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
851+
Error *err = NULL;
852+
socklen_t len = sizeof(struct ucred);
853+
854+
struct ucred cred;
855+
if (getsockopt(sioc->fd,
856+
SOL_SOCKET, SO_PEERCRED,
857+
&cred, &len) == -1) {
858+
error_setg_errno(&err, errno, "Unable to get peer credentials");
859+
error_propagate(errp, err);
860+
*pid = -1;
861+
return -1;
862+
}
863+
*pid = (unsigned int)cred.pid;
864+
return 0;
865+
#else
866+
error_setg(errp, "Unsupported feature");
867+
*pid = -1;
868+
return -1;
869+
#endif
870+
}
844871

845872
static int
846873
qio_channel_socket_close(QIOChannel *ioc,
@@ -938,6 +965,7 @@ static void qio_channel_socket_class_init(ObjectClass *klass,
938965
#ifdef QEMU_MSG_ZEROCOPY
939966
ioc_klass->io_flush = qio_channel_socket_flush;
940967
#endif
968+
ioc_klass->io_peerpid = qio_channel_socket_get_peerpid;
941969
}
942970

943971
static const TypeInfo qio_channel_socket_info = {

io/channel.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,19 @@ void qio_channel_set_cork(QIOChannel *ioc,
548548
}
549549
}
550550

551+
int qio_channel_get_peerpid(QIOChannel *ioc,
552+
unsigned int *pid,
553+
Error **errp)
554+
{
555+
QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
556+
557+
if (!klass->io_peerpid) {
558+
error_setg(errp, "Channel does not support peer pid");
559+
return -1;
560+
}
561+
klass->io_peerpid(ioc, pid, errp);
562+
return 0;
563+
}
551564

552565
off_t qio_channel_io_seek(QIOChannel *ioc,
553566
off_t offset,

0 commit comments

Comments
 (0)