Page MenuHomeFreeBSD

D20295.diff
No OneTemporary

D20295.diff

Index: head/sys/dev/veriexec/veriexec_ioctl.h
===================================================================
--- head/sys/dev/veriexec/veriexec_ioctl.h
+++ head/sys/dev/veriexec/veriexec_ioctl.h
@@ -46,6 +46,11 @@
unsigned char fingerprint[MAXFINGERPRINTLEN];
};
+struct verified_exec_label_params {
+ struct verified_exec_params params;
+ char label[MAXLABELLEN];
+};
+
#define VERIEXEC_LOAD _IOW('S', 0x1, struct verified_exec_params)
#define VERIEXEC_ACTIVE _IO('S', 0x2) /* start checking */
#define VERIEXEC_ENFORCE _IO('S', 0x3) /* fail exec */
@@ -55,6 +60,7 @@
#define VERIEXEC_GETSTATE _IOR('S', 0x7, int) /* get state */
#define VERIEXEC_SIGNED_LOAD _IOW('S', 0x8, struct verified_exec_params)
#define VERIEXEC_GETVERSION _IOR('S', 0x9, int) /* get version */
+#define VERIEXEC_LABEL_LOAD _IOW('S', 0xa, struct verified_exec_label_params)
#define _PATH_DEV_VERIEXEC _PATH_DEV "veriexec"
Index: head/sys/dev/veriexec/verified_exec.c
===================================================================
--- head/sys/dev/veriexec/verified_exec.c
+++ head/sys/dev/veriexec/verified_exec.c
@@ -68,6 +68,7 @@
{
struct nameidata nid;
struct vattr vattr;
+ struct verified_exec_label_params *lparams;
struct verified_exec_params *params;
int error = 0;
@@ -102,7 +103,12 @@
if (error)
return (error);
- params = (struct verified_exec_params *)data;
+ lparams = (struct verified_exec_label_params *)data;
+ if (cmd == VERIEXEC_LABEL_LOAD)
+ params = &lparams->params;
+ else
+ params = (struct verified_exec_params *)data;
+
switch (cmd) {
case VERIEXEC_ACTIVE:
mtx_lock(&ve_mutex);
@@ -158,6 +164,7 @@
return (EPERM); /* no updates when secure */
/* FALLTHROUGH */
+ case VERIEXEC_LABEL_LOAD:
case VERIEXEC_SIGNED_LOAD:
/*
* If we use a loader that will only use a
@@ -176,8 +183,9 @@
if (mac_veriexec_in_state(VERIEXEC_STATE_LOCKED))
error = EPERM;
else {
+ size_t labellen = 0;
int flags = FREAD;
- int override = (cmd == VERIEXEC_SIGNED_LOAD);
+ int override = (cmd != VERIEXEC_LOAD);
/*
* Get the attributes for the file name passed
@@ -221,13 +229,18 @@
FINGERPRINT_INVALID);
VOP_UNLOCK(nid.ni_vp, 0);
(void) vn_close(nid.ni_vp, FREAD, td->td_ucred, td);
+ if (params->flags & VERIEXEC_LABEL)
+ labellen = strnlen(lparams->label,
+ sizeof(lparams->label) - 1) + 1;
mtx_lock(&ve_mutex);
error = mac_veriexec_metadata_add_file(
((params->flags & VERIEXEC_FILE) != 0),
vattr.va_fsid, vattr.va_fileid, vattr.va_gen,
- params->fingerprint, params->flags,
- params->fp_type, override);
+ params->fingerprint,
+ (params->flags & VERIEXEC_LABEL) ?
+ lparams->label : NULL, labellen,
+ params->flags, params->fp_type, override);
mac_veriexec_set_state(VERIEXEC_STATE_LOADED);
mtx_unlock(&ve_mutex);
Index: head/sys/security/mac_veriexec/mac_veriexec.h
===================================================================
--- head/sys/security/mac_veriexec/mac_veriexec.h
+++ head/sys/security/mac_veriexec/mac_veriexec.h
@@ -1,7 +1,7 @@
/*
* $FreeBSD$
*
- * Copyright (c) 2011, 2012, 2013, 2015, 2016, Juniper Networks, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2015, 2016, 2019, Juniper Networks, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
* Enough room for the largest signature...
*/
#define MAXFINGERPRINTLEN 64 /* enough room for largest signature */
+#define MAXLABELLEN 128
/*
* Types of veriexec inodes we can have
@@ -57,8 +58,8 @@
#define VERIEXEC_FILE (1<<1) /* Fingerprint of a plain file */
#define VERIEXEC_NOTRACE (1<<2) /**< PTRACE not allowed */
#define VERIEXEC_TRUSTED (1<<3) /**< Safe to write /dev/mem */
-/* XXX these are currently unimplemented */
#define VERIEXEC_NOFIPS (1<<4) /**< Not allowed in FIPS mode */
+#define VERIEXEC_LABEL (1<<5) /**< We have a label */
#define VERIEXEC_STATE_INACTIVE 0 /**< Ignore */
#define VERIEXEC_STATE_LOADED (1<<0) /**< Sigs have been loaded */
@@ -71,7 +72,7 @@
/**
* Version of the MAC/veriexec module
*/
-#define MAC_VERIEXEC_VERSION 1
+#define MAC_VERIEXEC_VERSION 2
/* Valid states for the fingerprint flag - if signed exec is being used */
typedef enum fingerprint_status {
@@ -152,7 +153,8 @@
*/
int mac_veriexec_metadata_add_file(int file_dev, dev_t fsid, long fileid,
unsigned long gen, unsigned char fingerprint[MAXFINGERPRINTLEN],
- int flags, const char *fp_type, int override);
+ char *label, size_t labellen, int flags, const char *fp_type,
+ int override);
int mac_veriexec_metadata_has_file(dev_t fsid, long fileid,
unsigned long gen);
int mac_veriexec_proc_is_trusted(struct ucred *cred, struct proc *p);
Index: head/sys/security/mac_veriexec/mac_veriexec_internal.h
===================================================================
--- head/sys/security/mac_veriexec/mac_veriexec_internal.h
+++ head/sys/security/mac_veriexec/mac_veriexec_internal.h
@@ -1,7 +1,7 @@
/*
* $FreeBSD$
*
- * Copyright (c) 2011, 2012, 2013, 2015, 2016, Juniper Networks, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2015, 2016, 2019, Juniper Networks, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,8 @@
unsigned long gen;
struct mac_veriexec_fpops *ops;
unsigned char fingerprint[MAXFINGERPRINTLEN];
+ char *label;
+ size_t labellen;
LIST_ENTRY(mac_veriexec_file_info) entries;
};
@@ -76,6 +78,9 @@
struct proc *p, int *flags, int check_files);
int mac_veriexec_metadata_get_file_flags(dev_t fsid, long fileid,
unsigned long gen, int *flags, int check_files);
+struct mac_veriexec_file_info *
+ mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid,
+ unsigned long gen, int *found_dev, int check_files);
void mac_veriexec_metadata_init(void);
void mac_veriexec_metadata_print_db(struct sbuf *sbp);
int mac_veriexec_metadata_unmounted(dev_t fsid, struct thread *td);
Index: head/sys/security/mac_veriexec/veriexec_metadata.c
===================================================================
--- head/sys/security/mac_veriexec/veriexec_metadata.c
+++ head/sys/security/mac_veriexec/veriexec_metadata.c
@@ -1,7 +1,7 @@
/*
* $FreeBSD$
*
- * Copyright (c) 2011, 2012, 2013, 2015, 2016, Juniper Networks, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2015, 2016, 2019, Juniper Networks, Inc.
* All rights reserved.
*
* Originally derived from:
@@ -138,6 +138,8 @@
break;
/* we need to garbage collect */
LIST_REMOVE(ip, entries);
+ if (ip->label)
+ free(ip->label, M_VERIEXEC);
free(ip, M_VERIEXEC);
}
}
@@ -152,48 +154,6 @@
/**
* @internal
- * @brief Search the meta-data store for information on the specified file.
- *
- * @param fsid file system identifier to look for
- * @param fileid file to look for
- * @param gen generation of file
- * @param found_dev indicator that an entry for the file system was found
- * @param check_files if 1, check the files list first, otherwise check the
- * exectuables list first
- *
- * @return A pointer to the meta-data inforation if meta-data exists for
- * the specified file identifier, otherwise @c NULL
- */
-static struct mac_veriexec_file_info *
-find_veriexec_file(dev_t fsid, long fileid, unsigned long gen, int *found_dev,
- int check_files)
-{
- struct veriexec_devhead *search[3];
- struct mac_veriexec_file_info *ip;
- int x;
-
- /* Determine the order of the lists to search */
- if (check_files) {
- search[0] = &veriexec_file_dev_head;
- search[1] = &veriexec_dev_head;
- } else {
- search[0] = &veriexec_dev_head;
- search[1] = &veriexec_file_dev_head;
- }
- search[2] = NULL;
-
- VERIEXEC_DEBUG(3, ("%s: searching for dev %ju, file %lu\n",
- __func__, (uintmax_t)fsid, fileid));
-
- /* Search for the specified file */
- for (ip = NULL, x = 0; ip == NULL && search[x]; x++)
- ip = get_veriexec_file(search[x], fsid, fileid, gen, found_dev);
-
- return (ip);
-}
-
-/**
- * @internal
* @brief Display the fingerprint for each entry in the device list
*
* @param sbp sbuf to write output to
@@ -270,7 +230,7 @@
mac_veriexec_metadata_has_file(dev_t fsid, long fileid, unsigned long gen)
{
- return (find_veriexec_file(fsid, fileid, gen, NULL,
+ return (mac_veriexec_metadata_get_file_info(fsid, fileid, gen, NULL,
VERIEXEC_FILES_FIRST) != NULL);
}
@@ -312,6 +272,8 @@
for (ip = LIST_FIRST(&(lp->file_head)); ip != NULL; ip = nip) {
nip = LIST_NEXT(ip, entries);
LIST_REMOVE(ip, entries);
+ if (ip->label)
+ free(ip->label, M_VERIEXEC);
free(ip, M_VERIEXEC);
}
@@ -393,6 +355,38 @@
}
/**
+ * @internal
+ * @brief Allocate and initialize label record with the provided data.
+ *
+ * @param labelp Location to store the initialized label
+ * @param src Pointer to label string to copy
+ * @param srclen Length of label string to copy
+ *
+ * @return Length of resulting label
+ *
+ * @note Called with ve_mutex locked.
+ */
+static size_t
+mac_veriexec_init_label(char **labelp, size_t labellen, char *src,
+ size_t srclen)
+{
+ char *label;
+
+ label = *labelp;
+ if (labellen < srclen) {
+ mtx_unlock(&ve_mutex);
+ if (label != NULL)
+ free(label, M_VERIEXEC);
+ label = malloc(srclen, M_VERIEXEC, M_WAITOK);
+ mtx_lock(&ve_mutex);
+ labellen = srclen;
+ *labelp = label;
+ }
+ memcpy(label, src, srclen);
+ return labellen;
+}
+
+/**
* @brief When a device is unmounted, we want to toss the signatures recorded
* against it.
*
@@ -446,7 +440,8 @@
struct mac_veriexec_file_info *ip;
int found_dev;
- ip = find_veriexec_file(fsid, fileid, gen, &found_dev, check_files);
+ ip = mac_veriexec_metadata_get_file_info(fsid, fileid, gen, &found_dev,
+ check_files);
if (ip == NULL)
return (ENOENT);
@@ -518,8 +513,8 @@
status = mac_veriexec_get_fingerprint_status(vp);
if (status == FINGERPRINT_INVALID || status == FINGERPRINT_NODEV) {
found_dev = 0;
- ip = find_veriexec_file(vap->va_fsid, vap->va_fileid,
- vap->va_gen, &found_dev, check_files);
+ ip = mac_veriexec_metadata_get_file_info(vap->va_fsid,
+ vap->va_fileid, vap->va_gen, &found_dev, check_files);
if (ip == NULL) {
status = (found_dev) ? FINGERPRINT_NOENTRY :
FINGERPRINT_NODEV;
@@ -611,7 +606,7 @@
int
mac_veriexec_metadata_add_file(int file_dev, dev_t fsid, long fileid,
unsigned long gen, unsigned char fingerprint[MAXFINGERPRINTLEN],
- int flags, const char *fp_type, int override)
+ char *label, size_t labellen, int flags, const char *fp_type, int override)
{
struct mac_veriexec_fpops *fpops;
struct veriexec_dev_list *lp;
@@ -619,6 +614,10 @@
struct mac_veriexec_file_info *ip;
struct mac_veriexec_file_info *np = NULL;
+ /* Label and labellen must be set if VERIEXEC_LABEL is set */
+ if ((flags & VERIEXEC_LABEL) != 0 && (label == NULL || labellen == 0))
+ return (EINVAL);
+
/* Look up the device entry */
if (file_dev)
head = &veriexec_file_dev_head;
@@ -652,6 +651,15 @@
ip->ops = fpops;
memcpy(ip->fingerprint, fingerprint,
fpops->digest_len);
+ if (flags & VERIEXEC_LABEL) {
+ ip->labellen = mac_veriexec_init_label(
+ &ip->label, ip->labellen, label,
+ labellen);
+ } else if (ip->labellen > 0) {
+ free(ip->label, M_VERIEXEC);
+ ip->labellen = 0;
+ ip->label = NULL;
+ }
} else if ((flags & (VERIEXEC_INDIRECT|VERIEXEC_FILE)))
ip->flags |= flags;
@@ -697,6 +705,13 @@
ip->fileid = fileid;
ip->gen = gen;
memcpy(ip->fingerprint, fingerprint, fpops->digest_len);
+ if (flags & VERIEXEC_LABEL)
+ ip->labellen = mac_veriexec_init_label(&ip->label,
+ ip->labellen, label, labellen);
+ else {
+ ip->label = NULL;
+ ip->labellen = 0;
+ }
VERIEXEC_DEBUG(3, ("add file %ju.%lu (files=%d)\n",
(uintmax_t)ip->fileid,
@@ -716,6 +731,48 @@
#endif
return (0);
}
+
+/**
+ * @brief Search the meta-data store for information on the specified file.
+ *
+ * @param fsid file system identifier to look for
+ * @param fileid file to look for
+ * @param gen generation of file
+ * @param found_dev indicator that an entry for the file system was found
+ * @param check_files if 1, check the files list first, otherwise check the
+ * exectuables list first
+ *
+ * @return A pointer to the meta-data inforation if meta-data exists for
+ * the specified file identifier, otherwise @c NULL
+ */
+struct mac_veriexec_file_info *
+mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid, unsigned long gen,
+ int *found_dev, int check_files)
+{
+ struct veriexec_devhead *search[3];
+ struct mac_veriexec_file_info *ip;
+ int x;
+
+ /* Determine the order of the lists to search */
+ if (check_files) {
+ search[0] = &veriexec_file_dev_head;
+ search[1] = &veriexec_dev_head;
+ } else {
+ search[0] = &veriexec_dev_head;
+ search[1] = &veriexec_file_dev_head;
+ }
+ search[2] = NULL;
+
+ VERIEXEC_DEBUG(3, ("%s: searching for dev %ju, file %lu\n",
+ __func__, (uintmax_t)fsid, fileid));
+
+ /* Search for the specified file */
+ for (ip = NULL, x = 0; ip == NULL && search[x]; x++)
+ ip = get_veriexec_file(search[x], fsid, fileid, gen, found_dev);
+
+ return (ip);
+}
+
/**
* @brief Intialize the meta-data store

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 21, 7:04 PM (17 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15545283
Default Alt Text
D20295.diff (13 KB)

Event Timeline