165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (c) 2021 SUSE LLC <mdoucha@suse.cz>
|
|
*/
|
|
/*\
|
|
* [Description]
|
|
*
|
|
* CVE-2018-13405
|
|
*
|
|
* Check for possible privilege escalation through creating files with setgid
|
|
* bit set inside a setgid directory owned by a group which the user does not
|
|
* belong to.
|
|
*
|
|
* Fixed in:
|
|
*
|
|
* commit 0fa3ecd87848c9c93c2c828ef4c3a8ca36ce46c7
|
|
* Author: Linus Torvalds <torvalds@linux-foundation.org>
|
|
* Date: Tue Jul 3 17:10:19 2018 -0700
|
|
*
|
|
* Fix up non-directory creation in SGID directories
|
|
*
|
|
* This fix is incomplete if file is on xfs filesystem.
|
|
*
|
|
* Fixed in:
|
|
*
|
|
* commit 01ea173e103edd5ec41acec65b9261b87e123fc2
|
|
* Author: Christoph Hellwig <hch@lst.de>
|
|
* Date: Fri Jan 22 16:48:18 2021 -0800
|
|
*
|
|
* xfs: fix up non-directory creation in SGID directories
|
|
*
|
|
* When use acl or umask, it still has bug.
|
|
*
|
|
* Fixed in:
|
|
*
|
|
* commit 1639a49ccdce58ea248841ed9b23babcce6dbb0b
|
|
* Author: Yang Xu <xuyang2018.jy@fujitsu.com>
|
|
* Date: Thu July 14 14:11:27 2022 +0800
|
|
*
|
|
* fs: move S_ISGID stripping into the vfs_*() helpers
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
#include "tst_test.h"
|
|
#include "tst_uid.h"
|
|
|
|
#define MODE_RWX 0777
|
|
#define MODE_SGID (S_ISGID|0777)
|
|
|
|
#define MNTPOINT "mntpoint"
|
|
#define WORKDIR MNTPOINT "/testdir"
|
|
#define CREAT_FILE WORKDIR "/creat.tmp"
|
|
#define OPEN_FILE WORKDIR "/open.tmp"
|
|
|
|
static gid_t free_gid;
|
|
static int fd = -1;
|
|
|
|
static struct tcase {
|
|
const char *msg;
|
|
int mask;
|
|
} tcases[] = {
|
|
{"umask(0)", 0},
|
|
{"umask(S_IXGRP)", S_IXGRP}
|
|
};
|
|
|
|
static void setup(void)
|
|
{
|
|
struct stat buf;
|
|
struct passwd *ltpuser = SAFE_GETPWNAM("nobody");
|
|
|
|
tst_res(TINFO, "User nobody: uid = %d, gid = %d", (int)ltpuser->pw_uid,
|
|
(int)ltpuser->pw_gid);
|
|
free_gid = tst_get_free_gid(ltpuser->pw_gid);
|
|
|
|
/* Create directories and set permissions */
|
|
SAFE_MKDIR(WORKDIR, MODE_RWX);
|
|
SAFE_CHOWN(WORKDIR, ltpuser->pw_uid, free_gid);
|
|
SAFE_CHMOD(WORKDIR, MODE_SGID);
|
|
SAFE_STAT(WORKDIR, &buf);
|
|
|
|
if (!(buf.st_mode & S_ISGID))
|
|
tst_brk(TBROK, "%s: Setgid bit not set", WORKDIR);
|
|
|
|
if (buf.st_gid != free_gid) {
|
|
tst_brk(TBROK, "%s: Incorrect group, %u != %u", WORKDIR,
|
|
buf.st_gid, free_gid);
|
|
}
|
|
|
|
/* Switch user */
|
|
SAFE_SETGID(ltpuser->pw_gid);
|
|
SAFE_SETREUID(-1, ltpuser->pw_uid);
|
|
}
|
|
|
|
static void file_test(const char *name)
|
|
{
|
|
struct stat buf;
|
|
|
|
SAFE_STAT(name, &buf);
|
|
|
|
if (buf.st_gid != free_gid) {
|
|
tst_res(TFAIL, "%s: Incorrect group, %u != %u", name,
|
|
buf.st_gid, free_gid);
|
|
} else {
|
|
tst_res(TPASS, "%s: Owned by correct group", name);
|
|
}
|
|
|
|
if (buf.st_mode & S_ISGID)
|
|
tst_res(TFAIL, "%s: Setgid bit is set", name);
|
|
else
|
|
tst_res(TPASS, "%s: Setgid bit not set", name);
|
|
}
|
|
|
|
static void run(unsigned int n)
|
|
{
|
|
struct tcase *tc = &tcases[n];
|
|
|
|
umask(tc->mask);
|
|
tst_res(TINFO, "File created with %s", tc->msg);
|
|
|
|
fd = SAFE_CREAT(CREAT_FILE, MODE_SGID);
|
|
SAFE_CLOSE(fd);
|
|
file_test(CREAT_FILE);
|
|
|
|
fd = SAFE_OPEN(OPEN_FILE, O_CREAT | O_EXCL | O_RDWR, MODE_SGID);
|
|
file_test(OPEN_FILE);
|
|
SAFE_CLOSE(fd);
|
|
|
|
/* Cleanup between loops */
|
|
tst_purge_dir(WORKDIR);
|
|
}
|
|
|
|
static void cleanup(void)
|
|
{
|
|
if (fd >= 0)
|
|
SAFE_CLOSE(fd);
|
|
}
|
|
|
|
static struct tst_test test = {
|
|
.test = run,
|
|
.setup = setup,
|
|
.cleanup = cleanup,
|
|
.needs_root = 1,
|
|
.all_filesystems = 1,
|
|
.mount_device = 1,
|
|
.mntpoint = MNTPOINT,
|
|
.tcnt = ARRAY_SIZE(tcases),
|
|
.skip_filesystems = (const char*[]) {
|
|
"exfat",
|
|
"ntfs",
|
|
"vfat",
|
|
NULL
|
|
},
|
|
.tags = (const struct tst_tag[]) {
|
|
{"linux-git", "0fa3ecd87848"},
|
|
{"CVE", "2018-13405"},
|
|
{"CVE", "2021-4037"},
|
|
{"linux-git", "01ea173e103e"},
|
|
{"linux-git", "1639a49ccdce"},
|
|
{"linux-git", "426b4ca2d6a5"},
|
|
{}
|
|
},
|
|
};
|