• Jann Horn's avatar
    lsm: fix integer overflow in lsm_set_self_attr() syscall · d8bdd795
    Jann Horn authored
    security_setselfattr() has an integer overflow bug that leads to
    out-of-bounds access when userspace provides bogus input:
    `lctx->ctx_len + sizeof(*lctx)` is checked against `lctx->len` (and,
    redundantly, also against `size`), but there are no checks on
    `lctx->ctx_len`.
    Therefore, userspace can provide an `lsm_ctx` with `->ctx_len` set to a
    value between `-sizeof(struct lsm_ctx)` and -1, and this bogus `->ctx_len`
    will then be passed to an LSM module as a buffer length, causing LSM
    modules to perform out-of-bounds accesses.
    
    The following reproducer will demonstrate this under ASAN (if AppArmor is
    loaded as an LSM):
    
    ```
    
    struct lsm_ctx {
      uint64_t id;
      uint64_t flags;
      uint64_t len;
      uint64_t ctx_len;
      char ctx[];
    };
    
    int main(void) {
      size_t size = sizeof(struct lsm_ctx);
      struct lsm_ctx *ctx = malloc(size);
      ctx->id = 104/*LSM_ID_APPARMOR*/;
      ctx->flags = 0;
      ctx->len = size;
      ctx->ctx_len = -sizeof(struct lsm_ctx);
      syscall(
        460/*__NR_lsm_set_self_attr*/,
        /*attr=*/  100/*LSM_ATTR_CURRENT*/,
        /*ctx=*/   ctx,
        /*size=*/  size,
        /*flags=*/ 0
      );
    }
    ```
    
    Fixes: a04a1198 ("LSM: syscalls for current process attributes")
    Signed-off-by: default avatarJann Horn <jannh@google.com>
    Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
    [PM: subj tweak, removed ref to ASAN splat that isn't included]
    Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
    d8bdd795
security.c 160 KB