Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions conf/include/package_revisions_oss.inc
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ PACKAGE_ARCH:pn-sqlite3 ?= "${OSS_LAYER_ARCH}"
PR:pn-strace ?= "r0"
PACKAGE_ARCH:pn-strace ?= "${OSS_LAYER_ARCH}"

PR:pn-stunnel ?= "r2"
PR:pn-stunnel ?= "r3"
PACKAGE_ARCH:pn-stunnel ?= "${OSS_LAYER_ARCH}"

PR:pn-sysfsutils ?= "r6"
Expand Down Expand Up @@ -921,7 +921,7 @@ PACKAGE_ARCH:pn-wireless-tools ?= "${OSS_LAYER_ARCH}"
PR:pn-woff2 ?= "r0"
PACKAGE_ARCH:pn-woff2 ?= "${OSS_LAYER_ARCH}"

PR:pn-wpa-supplicant ?= "r9"
PR:pn-wpa-supplicant ?= "r10"
PACKAGE_ARCH:pn-wpa-supplicant ?= "${OSS_LAYER_ARCH}"

PR:pn-xkeyboard-config ?= "r0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Index: wpa_supplicant-2.10/wpa_supplicant/bgscan_simple.c
===================================================================
--- wpa_supplicant-2.10.orig/wpa_supplicant/bgscan_simple.c
+++ wpa_supplicant-2.10/wpa_supplicant/bgscan_simple.c
@@ -27,6 +27,7 @@ struct bgscan_simple_data {
int short_interval; /* use if signal < threshold */
int long_interval; /* use if signal > threshold */
struct os_reltime last_bgscan;
+ int roaming_threshold_db; /* min RSSI gain (dB) required to allow roam */
};


@@ -95,6 +96,11 @@ static int bgscan_simple_get_params(stru
}
pos++;
data->long_interval = atoi(pos);
+ pos = os_strchr(pos, ':');
+ if (pos == NULL)
+ return 0;
+ pos++;
+ data->roaming_threshold_db = atoi(pos);

return 0;
}
@@ -119,11 +125,16 @@ static void * bgscan_simple_init(struct
data->short_interval = 30;
if (data->long_interval <= 0)
data->long_interval = 30;
+ if (data->roaming_threshold_db < 0)
+ data->roaming_threshold_db = 0;
Comment on lines +29 to +30
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation logic checks if roaming_threshold_db is less than 0 and sets it to 0 if so, but the patch description and variable name suggest this should be a positive threshold value in dB. A threshold of 0 dB means no RSSI improvement is required for roaming, which may not be the intended behavior. Consider whether negative values should be rejected entirely, or if the default should be a positive value that represents a meaningful RSSI delta requirement.

Suggested change
+ if (data->roaming_threshold_db < 0)
+ data->roaming_threshold_db = 0;
+ if (data->roaming_threshold_db <= 0)
+ data->roaming_threshold_db = 5;

Copilot uses AI. Check for mistakes.
+
+ wpa_s->roaming_threshold_db = data->roaming_threshold_db;

wpa_printf(MSG_DEBUG, "bgscan simple: Signal strength threshold %d "
- "Short bgscan interval %d Long bgscan interval %d",
+ "Short bgscan interval %d Long bgscan interval %d "
+ "Roaming threshold %d",
data->signal_threshold, data->short_interval,
- data->long_interval);
+ data->long_interval, data->roaming_threshold_db);

if (data->signal_threshold &&
wpa_drv_signal_monitor(wpa_s, data->signal_threshold, 4) < 0) {
Index: wpa_supplicant-2.10/wpa_supplicant/events.c
===================================================================
--- wpa_supplicant-2.10.orig/wpa_supplicant/events.c
+++ wpa_supplicant-2.10/wpa_supplicant/events.c
@@ -1927,6 +1927,22 @@ int wpa_supplicant_need_to_roam_within_e
cur_level, cur_snr, cur_est);
}

+ /* Enforce RSSI delta >= roaming_threshold_db before allowing reassociation */
+ if (wpa_s->roaming_threshold_db > 0) {
+ int delta_db = selected->level - cur_level; /* dBm; delta>0 => candidate stronger */
+ if (delta_db < wpa_s->roaming_threshold_db) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Skip roam - RSSI delta=%d dB < threshold=%d dB",
+ delta_db, wpa_s->roaming_threshold_db);
+ /* Prevent the reassociation for this scan */
+ return 0;
+ /* Option A: clear candidate … */
+// selected = NULL;
+ /* Option B: or ensure the local 'allow_reassoc' variable stays false */
+ /* allow_reassoc = 0; */
Comment on lines +59 to +64
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out code on lines 59-62 appears to be alternative implementation options that were left in the patch. These comments should either be removed if they're not needed, or converted to proper documentation explaining why one approach was chosen over another. Leaving multiple implementation options commented out can confuse future maintainers.

Suggested change
+ /* Prevent the reassociation for this scan */
+ return 0;
+ /* Option A: clear candidate … */
+// selected = NULL;
+ /* Option B: or ensure the local 'allow_reassoc' variable stays false */
+ /* allow_reassoc = 0; */
+ /* Prevent reassociation for this scan if RSSI gain is too small */
+ return 0;

Copilot uses AI. Check for mistakes.
+ }
+ }
+
if (sel_est > cur_est + 5000) {
wpa_dbg(wpa_s, MSG_DEBUG,
"Allow reassociation - selected BSS has better estimated throughput");
Index: wpa_supplicant-2.10/wpa_supplicant/wpa_supplicant_i.h
===================================================================
--- wpa_supplicant-2.10.orig/wpa_supplicant/wpa_supplicant_i.h
+++ wpa_supplicant-2.10/wpa_supplicant/wpa_supplicant_i.h
@@ -1178,6 +1178,7 @@ struct wpa_supplicant {
struct wpa_ssid *bgscan_ssid;
const struct bgscan_ops *bgscan;
void *bgscan_priv;
+ int roaming_threshold_db; /* >=0: required RSSI delta (dB) to allow roam */

const struct autoscan_ops *autoscan;
struct wpa_driver_scan_params *autoscan_params;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SRC_URI += "file://openssl_no_md4_2.10.patch"
SRC_URI += "file://fix_HS20_build_with_INTERWORKING.patch"
SRC_URI += "file://increase_wpa_ctrl_return_buffer.patch"
SRC_URI += "file://suppress_no_eap_session_id_log.patch"
SRC_URI += "file://roaming_threshold.patch"

inherit syslog-ng-config-gen logrotate_config
#inherit breakpad-logmapper
Expand Down Expand Up @@ -38,7 +39,6 @@ do_configure:append () {
fi

sed -i -- 's/CONFIG_DRIVER_HOSTAP=y/\#CONFIG_DRIVER_HOSTAPAP=y/' wpa_supplicant/.config
sed -i -- 's/#CONFIG_NO_ROAMING=y/\CONFIG_NO_ROAMING=y/' wpa_supplicant/.config
sed -i -- 's/#CONFIG_IEEE80211W=y/\CONFIG_IEEE80211W=y/' wpa_supplicant/.config

#Enable the following supplicant options:
Expand Down
40 changes: 40 additions & 0 deletions recipes-support/libp11/libp11_0.4.17.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
SUMMARY = "Library for using PKCS"
DESCRIPTION = "\
Libp11 is a library implementing a small layer on top of PKCS \
make using PKCS"
Comment on lines +3 to +4
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DESCRIPTION field on lines 2-4 is incomplete and appears to be truncated. It starts with "Libp11 is a library implementing a small layer on top of PKCS make using PKCS" but doesn't complete the thought. This should be a complete, meaningful description of the library's purpose, such as "Libp11 is a library implementing a small layer on top of PKCS#11 to make using PKCS#11 easier for applications."

Suggested change
Libp11 is a library implementing a small layer on top of PKCS \
make using PKCS"
Libp11 is a library implementing a small layer on top of PKCS#11 to make using PKCS#11 easier for applications.\
"

Copilot uses AI. Check for mistakes.
HOMEPAGE = "https://github.com/OpenSC/libp11"
BUGTRACKER = "https://github.com/OpenSC/libp11/issues"
SECTION = "Development/Libraries"
LICENSE = "LGPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://COPYING;md5=fad9b3332be894bab9bc501572864b29"
DEPENDS = "libtool openssl"

SRC_URI = "git://github.com/OpenSC/libp11.git;branch=master;protocol=https"

SRCREV = "1ad1efdffc90df5dcd69822f3f593898acc1aa78"

UPSTREAM_CHECK_GITTAGREGEX = "libp11-(?P<pver>\d+(\.\d+)+)"


inherit autotools pkgconfig

EXTRA_OECONF = "--disable-static"
EXTRA_OECONF:append:class-native = "\
--with-enginesdir=${RECIPE_SYSROOT_NATIVE}/usr/lib/engines-3 \
--with-modulesdir=${RECIPE_SYSROOT_NATIVE}/usr/lib/ossl-modules \
"

do_install:append () {
rm -rf ${D}${docdir}/${BPN}
}

FILES:${PN} += "\
${libdir}/engines*/pkcs11.so \
${libdir}/ossl-modules/pkcs11prov.so \
"
FILES:${PN}-dev += "\
${libdir}/engines*/libpkcs11${SOLIBSDEV} \
${libdir}/ossl-modules/libpkcs11${SOLIBSDEV} \
"

BBCLASSEXTEND = "native"
121 changes: 121 additions & 0 deletions recipes-support/stunnel/stunnel/fd_credential.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
From 91880074f52d9392dac8d658a9b48dca3f824ea0 Mon Sep 17 00:00:00 2001
From: ldonth501 <LasyaPrakarsha_DonthiVenkata@comcast.com>
Date: Sat, 5 Oct 2024 15:32:26 +0000

Subject: [PATCH] stunnel: Non-interactive passcode for p12 cert

Upstream-Status: Pending

Recognize .pk12 extension as p12 cert.
Attempt to obtain the passcode for p12 cert from fd environment variable.

Signed-off-by: ldonth501 <LasyaPrakarsha_DonthiVenkata@comcast.com>
---
src/ctx.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)

Index: stunnel-5.65/src/ctx.c
===================================================================
--- stunnel-5.65.orig/src/ctx.c
+++ stunnel-5.65/src/ctx.c
@@ -767,12 +767,14 @@ PSK_KEYS *psk_find(const PSK_TABLE *tabl

NOEXPORT int pkcs12_extension(const char *filename) {
const char *ext=strrchr(filename, '.');
- return ext && (!strcasecmp(ext, ".p12") || !strcasecmp(ext, ".pfx"));
+ return ext && (!strcasecmp(ext, ".p12") || !strcasecmp(ext, ".pfx") || !strcasecmp(ext, ".pk12"));
}

+#define FD_READ_TIMEOUT_SECONDS 5
+
NOEXPORT int load_pkcs12_file(SERVICE_OPTIONS *section) {
size_t len;
- int i, success;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of 'success' to 0 on line 33 changes the original code behavior. In the original code, 'success' was uninitialized and would be set by the first PKCS12_parse call. With this initialization, if the non-interactive path is never taken (e.g., FD_NUMBER not set), success remains 0 and the subsequent logic at line 102 behaves differently. However, this appears to be intentional as it allows the code to fall through to the interactive path when the non-interactive path fails. The issue is that the check on line 102 should probably still ensure cert and pkey are valid before proceeding to interactive_end.

Copilot uses AI. Check for mistakes.
+ int i, success = 0;
BIO *bio=NULL;
PKCS12 *p12=NULL;
X509 *cert=NULL;
@@ -798,6 +800,74 @@ NOEXPORT int load_pkcs12_file(SERVICE_OP
}
BIO_free(bio);

+ const char *fd_str = getenv("FD_NUMBER");
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using getenv for retrieving sensitive file descriptors is potentially insecure. Consider using secure_getenv instead, which prevents access to the environment variable if the process is running with elevated privileges (setuid/setgid). This prevents privilege escalation attacks where an attacker might control environment variables.

Suggested change
+ const char *fd_str = getenv("FD_NUMBER");
+ const char *fd_str = secure_getenv("FD_NUMBER");

Copilot uses AI. Check for mistakes.
+ if (!fd_str) {
+ s_log(LOG_ERR, "FD_NUMBER environment variable not set");
+ goto interactive_start;
+ }
+
+ int fd = atoi(fd_str);
+ s_log(LOG_INFO,"FD_NUMBER is %d", fd);
+
+ /* Ensure the file descriptor is greater than or equal to 3, since 0, 1, and 2 are standard streams */
+ /* Validate FD range for select()/FD_SET() */
+ if (fd < 3 || fd >= FD_SETSIZE) {
+ s_log(LOG_ERR, "Invalid FD_NUMBER %d (must be >= 3 and < FD_SETSIZE=%d)", fd, FD_SETSIZE);
+ goto interactive_start;
+ }
+
+ /* Set up the file descriptor set for select() */
+ fd_set read_fds;
+ FD_ZERO(&read_fds);
+ FD_SET(fd, &read_fds);
+
+ /* Set a timeout for select() to avoid waiting indefinitely; use FD_READ_TIMEOUT_SECONDS to handle problems during high load averages */
+ struct timeval timeout;
+ timeout.tv_sec = FD_READ_TIMEOUT_SECONDS;
+ timeout.tv_usec = 0;
+
+ /* Wait until the file descriptor is ready for reading */
+ int result = select(fd + 1, &read_fds, NULL, NULL, &timeout);
+ if (result == -1) {
+ s_log(LOG_ERR, "select error: %s", strerror(errno));
+ goto interactive_start;
+ }
+ else if (result == 0) {
+ /* Timeout occurred, file descriptor not ready */
+ s_log(LOG_ERR, "Timeout: File descriptor not ready for reading");
+ goto interactive_start;
+ }
+
+ char p12_passcode[64] = {0};
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer size of 64 bytes for the passcode is arbitrary and may be insufficient for some use cases or excessive for others. Consider defining this as a named constant (e.g., MAX_P12_PASSCODE_LEN) to improve maintainability and make it easier to adjust if needed.

Suggested change
+ char p12_passcode[64] = {0};
+#ifndef MAX_P12_PASSCODE_LEN
+#define MAX_P12_PASSCODE_LEN 64
+#endif
+
+ char p12_passcode[MAX_P12_PASSCODE_LEN] = {0};

Copilot uses AI. Check for mistakes.
+ ssize_t bytes_read = read(fd, p12_passcode, sizeof(p12_passcode) - 1);
+ if (bytes_read > 0) {
+ if (p12_passcode[bytes_read - 1] == '\n') {
+ p12_passcode[bytes_read - 1] = '\0';
+ } else {
+ p12_passcode[bytes_read] = '\0';
+ }
+ } else if (bytes_read == 0) {
+ s_log(LOG_INFO, "EOF encountered, no more data to read.");
+ } else {
+ s_log(LOG_ERR, "read error: %s", strerror(errno));
Comment on lines +89 to +91
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When bytes_read equals 0 (EOF), only an info log is generated and execution continues. However, p12_passcode will be empty (all zeros from initialization), which will cause the PKCS12_parse on line 97 to fail with an empty password. This path should jump to interactive_start since no password was read, similar to the error case.

Suggested change
+ s_log(LOG_INFO, "EOF encountered, no more data to read.");
+ } else {
+ s_log(LOG_ERR, "read error: %s", strerror(errno));
+ s_log(LOG_INFO, "EOF encountered, no more data to read.");
+ close(fd);
+ goto interactive_start;
+ } else {
+ s_log(LOG_ERR, "read error: %s", strerror(errno));
+ close(fd);

Copilot uses AI. Check for mistakes.
+ goto interactive_start;
+ }
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file descriptor is closed unconditionally on line 93, even when read fails or returns 0 bytes. However, if the select call times out or fails (lines 73-77), execution jumps to interactive_start before reaching the close call, which will leave the file descriptor open and cause a resource leak. The close call should be moved before the goto interactive_start statements or handled in all error paths.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +93
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The read call on line 80 could potentially read partial data if the full passcode hasn't been written to the file descriptor yet. While select indicates readiness, it doesn't guarantee that all expected data is available. Consider implementing a loop to read until a newline is encountered or the buffer is full, or document the assumption that the entire passcode will be written atomically.

Suggested change
+ ssize_t bytes_read = read(fd, p12_passcode, sizeof(p12_passcode) - 1);
+ if (bytes_read > 0) {
+ if (p12_passcode[bytes_read - 1] == '\n') {
+ p12_passcode[bytes_read - 1] = '\0';
+ } else {
+ p12_passcode[bytes_read] = '\0';
+ }
+ } else if (bytes_read == 0) {
+ s_log(LOG_INFO, "EOF encountered, no more data to read.");
+ } else {
+ s_log(LOG_ERR, "read error: %s", strerror(errno));
+ goto interactive_start;
+ }
+ ssize_t total_read = 0;
+ ssize_t bytes_read;
+ int done = 0;
+
+ /* Read until newline, buffer full, EOF, or error */
+ while (total_read < (ssize_t)sizeof(p12_passcode) - 1 && !done) {
+ bytes_read = read(fd, p12_passcode + total_read,
+ sizeof(p12_passcode) - 1 - total_read);
+ if (bytes_read > 0) {
+ ssize_t i;
+ for (i = total_read; i < total_read + bytes_read; ++i) {
+ if (p12_passcode[i] == '\n') {
+ p12_passcode[i] = '\0';
+ done = 1;
+ break;
+ }
+ }
+ total_read += bytes_read;
+ } else if (bytes_read == 0) {
+ s_log(LOG_INFO, "EOF encountered, no more data to read.");
+ break;
+ } else {
+ if (errno == EINTR) {
+ continue;
+ }
+ s_log(LOG_ERR, "read error: %s", strerror(errno));
+ goto interactive_start;
+ }
+ }
+
+ if (!done) {
+ /* Ensure null termination if no newline encountered */
+ p12_passcode[total_read] = '\0';
+ }
+

Copilot uses AI. Check for mistakes.
+ close(fd);
+
+ /* try obtaining the passcode non-interactively*/
+ if(p12_passcode[0] != '\0') {
+ success=PKCS12_parse(p12, p12_passcode, &pkey, &cert, &ca);
+ }
+ /* clear sensitive passcode data */
+ memset(p12_passcode, 0, sizeof(p12_passcode));
+
+ if(!success) {
+ goto interactive_start;
+ }
+ goto interactive_end;
+
+interactive_start:
+ s_log(LOG_ERR, "Unable to obtain passcode non-interactively");
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging passwords or password-related errors at LOG_ERR level on line 108 after all non-interactive methods fail could leak sensitive information in system logs. Consider using a more generic error message that doesn't reveal password-related details, or ensure that the interactive fallback is logged at a less severe level like LOG_INFO or LOG_DEBUG.

Suggested change
+ s_log(LOG_ERR, "Unable to obtain passcode non-interactively");
+ s_log(LOG_INFO, "Unable to obtain passcode non-interactively");

Copilot uses AI. Check for mistakes.
/* try the cached value first */
set_prompt(section->cert);
len=(size_t)cache_passwd_get_cb(pass, sizeof pass, 0, NULL);
@@ -828,7 +898,7 @@ NOEXPORT int load_pkcs12_file(SERVICE_OP
PKCS12_free(p12);
return 1; /* FAILED */
}
-
+interactive_end:
PKCS12_free(p12);

if(!SSL_CTX_use_certificate(section->ctx, cert)) {
1 change: 1 addition & 0 deletions recipes-support/stunnel/stunnel_%.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ do_install:append() {

FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
SRC_URI += "file://separate_keying_for_dev_prod_vm_stunnel.patch"
SRC_URI += "file://fd_credential.patch"

inherit logrotate_config

Expand Down
Loading