使用 sysctl(3) 编写安全、可移植的代码:好主意?

Posted

技术标签:

【中文标题】使用 sysctl(3) 编写安全、可移植的代码:好主意?【英文标题】:Using sysctl(3) to write safe, portable code: good idea? 【发布时间】:2013-12-16 04:25:59 【问题描述】:

在直接用 C 语言编写安全代码时,我厌倦了随意提出 代表限制的数字 - 具体来说,最大数量 为单行文本分配的内存。我知道我总能说 像

#define MAX_LINE_LENGTH 1024

然后将该宏传递给诸如 snprintf() 之类的函数。

我在 NetBSD 中工作和编码,它有一个名为 sysctl(3) 的变量 “user.line_max”就是为此目的而设计的。所以我不需要上来 上面的 MAX_LINE_LENGTH 之类的任意数字。我刚读了 "user.line_max" sysctl 变量,顺便说一句,用户可以设置。

我的问题是,这在安全和安全方面是否正确? 可移植性。也许不同的操作系统有不同的名称 这个 sysctl,但我更感兴趣的是我是否应该使用它 技术。

为了记录,在这种情况下,“可移植性”不包括 Microsoft Windows。

【问题讨论】:

【参考方案1】:

Linux SYSCTL (2) 手册页的注释部分有这样的说法:

Glibc 没有为这个系统调用提供封装;使用 syscall(2) 调用它。 或者更确切地说......不要调用它:长期以来一直不鼓励使用这个系统调用,而且它是如此不受欢迎,以至于它很可能在未来的内核版本中消失。立即将其从您的程序中删除;请改用 /proc/sys 接口。

所以这是一个考虑因素。

【讨论】:

呃,糟糕。很高兴知道。【参考方案2】:

不是个好主意。即使不是 Duck 告诉你的,依赖运行时变量的系统范围设置也是糟糕的设计并且容易出错。如果您要麻烦让缓冲区大小限制可变(这通常需要动态分配和检查失败),那么您应该进行最后一步,使其在更本地的范围内可配置。

对于您的缓冲区大小限制示例,对于最佳做法的看法存在分歧。有些人认为您应该始终使用没有硬限制的动态增长缓冲区。其他人更喜欢足够大的固定限制,以至于合理的数据不会超过它们。或者,正如您所指出的,可配置的限制是一种选择。在选择适合您的应用程序时,我会考虑用户体验的影响。当然,用户不喜欢任意限制,但他们也不喜欢意外(或出于其他人的恶意)读取没有换行符的数据导致您的应用程序消耗无限量的内存、开始交换和/或最终使整个系统崩溃或陷入瘫痪。

【讨论】:

实际上,“user.line_max”sysctl 变量在运行时是不可更改的,至少在 NetBSD 上是这样——它是一个硬编码到操作系统内核中的常量。只有在编译新内核时才能更改它。考虑到这一点,让配置更加本地化也是一个好主意。【参考方案3】:

最接近的可移植构造是“getconf LINE_MAX”或等效的 C。

【讨论】:

【参考方案4】:

1) 查看单一 Unix 规范,关键字:“limits”

2) s/安全/安保/

【讨论】:

因此,limits.h 的注释指定“应用程序不应假定任何特定的限制值”以实现最大的可移植性。这是否意味着代码包含用户定义的限制是“错误的”(无论这意味着什么),例如我上面的示例MAX_LINE_LENGTH?我经常在野外看到这样的东西。

以上是关于使用 sysctl(3) 编写安全、可移植的代码:好主意?的主要内容,如果未能解决你的问题,请参考以下文章

编写可移植方案代码。除了 R5RS 本身还有啥“标准”吗?

编写可移植的PHP代码

C++最佳实践 | 5. 可移植性及多线程

C++最佳实践 | 5. 可移植性及多线程

可移植代码 - 每个字符的位数

C++最佳实践 | 3. 安全性