2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-05 16:55:32 +00:00

Library interface for tasks introspecting confinement.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen
2011-08-09 06:47:40 -07:00
parent 685632db0c
commit 8347fb69c2
7 changed files with 142 additions and 3 deletions

View File

@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
@@ -407,3 +408,124 @@ int (aa_change_hat_vargs)(unsigned long token, int nhats, ...)
va_end(ap);
return aa_change_hatv(argv, token);
}
/**
* aa_gettaskcon - get the confinement for task @target in an allocated buffer
* @target: task to query
* @con: pointer to returned buffer with the confinement string
* @mode: if provided will point to the mode string in @con if present
*
* Returns: length of confinement data or -1 on error and sets errno
*
* Guarentees that @con and @mode are null terminated. The length returned
* is for all data including both @con and @mode, and maybe > than strlen(@con)
* even if @mode is NULL
*
* Caller is responsible for freeing the buffer returned in @con. @mode is
* always contained within @con's buffer and so NEVER do free(@mode)
*/
int aa_gettaskcon(pid_t target, char **con, char **mode)
{
return aa_getprocattr(target, "current", con, mode);
}
/**
* aa_getcon - get the confinement for current task in an allocated buffer
* @con: pointer to return buffer with the confinement if successful
* @mode: if provided will point to the mode string in @con if present
*
* Returns: length of confinement data or -1 on error and sets errno
*
* Guarentees that @con and @mode are null terminated. The length returned
* is for all data including both @con and @mode, and may > than strlen(@con)
* even if @mode is NULL
*
* Caller is responsible for freeing the buffer returned in @con. @mode is
* always contained within @con's buffer and so NEVER do free(@mode)
*/
int aa_getcon(char **con, char **mode)
{
return aa_gettaskcon(aa_gettid(), con, mode);
}
#ifndef SO_PEERSEC
#define SO_PEERSEC 31
#endif
/**
* aa_getpeercon_raw - get the confinement of the socket's peer (other end)
* @fd: socket to get peer confinement for
* @con: pointer to buffer to store confinement string
* @size: initially contains size of the buffer, returns size of data read
*
* Returns: length of confinement data including null termination or -1 on error
* if errno == ERANGE then @size will hold the size needed
*/
int aa_getpeercon_raw(int fd, char *buffer, int *size)
{
socklen_t optlen = *size;
int rc;
if (optlen <= 0 || buffer == NULL) {
errno = EINVAL;
return -1;
}
rc = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buffer, &optlen);
if (rc == -1 || optlen <= 0)
goto out;
/* check for null termination */
if (buffer[optlen - 1] != 0) {
if (optlen < *size) {
buffer[optlen] = 0;
optlen++;
} else {
/* buffer needs to be bigger by 1 */
rc = -1;
errno = ERANGE;
optlen++;
}
}
out:
*size = optlen;
return rc;
}
/**
* aa_getpeercon - get the confinement of the socket's peer (other end)
* @fd: socket to get peer confinement for
* @con: pointer to allocated buffer with the confinement string
*
* Returns: length of confinement data including null termination or -1 on error
*
* Caller is responsible for freeing the buffer returned.
*/
int aa_getpeercon(int fd, char **con)
{
int rc, size = INITIAL_GUESS_SIZE;
char *buffer = NULL;
if (!con) {
errno = EINVAL;
return -1;
}
do {
buffer = realloc(buffer, size);
if (!buffer)
return -1;
memset(buffer, 0, size);
rc = aa_getpeercon_raw(fd, buffer, &size);
} while (rc == -1 && errno == ERANGE);
if (rc == -1) {
free(buffer);
size = -1;
} else
*con = buffer;
return size;
}