summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2023-10-24 20:44:00 +0200
committerPaul Moore <paul@paul-moore.com>2023-11-13 04:54:42 +0100
commitd7cf3412a9f6c547e5ee443fa7644e08898aa3e2 (patch)
treef5ab0f4687f6d7efae5ac221906a18ddf3b11330 /security/selinux
parentlsm: correct error codes in security_getselfattr() (diff)
downloadlinux-d7cf3412a9f6c547e5ee443fa7644e08898aa3e2.tar.xz
linux-d7cf3412a9f6c547e5ee443fa7644e08898aa3e2.zip
lsm: consolidate buffer size handling into lsm_fill_user_ctx()
While we have a lsm_fill_user_ctx() helper function designed to make life easier for LSMs which return lsm_ctx structs to userspace, we didn't include all of the buffer length safety checks and buffer padding adjustments in the helper. This led to code duplication across the different LSMs and the possibility for mistakes across the different LSM subsystems. In order to reduce code duplication and decrease the chances of silly mistakes, we're consolidating all of this code into the lsm_fill_user_ctx() helper. The buffer padding is also modified from a fixed 8-byte alignment to an alignment that matches the word length of the machine (BITS_PER_LONG / 8). Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b6c7930a3ab2..942f2b8c4ebb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6486,30 +6486,32 @@ abort_change:
return error;
}
+/**
+ * selinux_getselfattr - Get SELinux current task attributes
+ * @attr: the requested attribute
+ * @ctx: buffer to receive the result
+ * @size: buffer size (input), buffer size used (output)
+ * @flags: unused
+ *
+ * Fill the passed user space @ctx with the details of the requested
+ * attribute.
+ *
+ * Returns the number of attributes on success, an error code otherwise.
+ * There will only ever be one attribute.
+ */
static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t *size, u32 flags)
{
- char *value;
- size_t total_len;
- int len;
- int rc = 0;
-
- len = selinux_lsm_getattr(attr, current, &value);
- if (len < 0)
- return len;
-
- total_len = ALIGN(struct_size(ctx, ctx, len), 8);
-
- if (total_len > *size)
- rc = -E2BIG;
- else if (ctx)
- rc = lsm_fill_user_ctx(ctx, value, len, LSM_ID_SELINUX, 0);
-
- kfree(value);
- *size = total_len;
- if (rc < 0)
- return rc;
- return 1;
+ int rc;
+ char *val;
+ int val_len;
+
+ val_len = selinux_lsm_getattr(attr, current, &val);
+ if (val_len < 0)
+ return val_len;
+ rc = lsm_fill_user_ctx(ctx, size, val, val_len, LSM_ID_SELINUX, 0);
+ kfree(val);
+ return (!rc ? 1 : rc);
}
static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx,