KaiOS System Properties

Posted by Tom Barrasso on

KaiOS Architecture
KaiOS Architecture (Source: scottiestech.info)

Reading and writing system properties on KaiOS

KaiOS is a partially open source mobile Linux distribution that, under the hood, makes significant use of Android components like the Hardware Abstraction Layer (HAL). Gonk is KaiOS’ platform denomination for a combination of the Linux kernel and Android HAL, borrowed from it’s predecessor Firefox OS.

Like Android, KaiOS has system properties that provide a convenient way to share information like configurations, system-wide. These are stored in read-only property files (.prop extension) like bootimg/ramdisk/default.prop and system/build.prop. System properties are then managed by property_service to populate its internal in-memory database at start-up.

System properties are stored in a key-value format and include useful information like the device model name (ro.product.model), whether debug mode is enabled (ro.debuggable), and the timestamp when the OS build was generated (ro.bootimage.build.date.utc).

Android Device Bridge (ADB)

Like Android, system properties are accessible using the getprop and setprop shell commands via the Android Device Bridge (ADB). Not all commercial KaiOS devices will be equip with ADB vendor keys, in which case you’ll get an unauthorized error message.

1adb shell getprop ro.build.version.sdk
2adb shell setprop ctl.stop wpa_supplicant

Low-level Access

Static libraries like libcutils (system/lib/libcutils.so) contain wrappers to access system properties via native contexts in C/C++. In KaiOS, this is abstracted via SystemProperty.cpp which lazy-loads libcutils used throughout Gonk.

1// Get system property, null default value
2Property::Get("ro.build.version.sdk", value, nullptr);
3
4// Set system property to "radvd"
5Property::Set("ctl.start", "radvd");

The second example uses another special property that communicates with [init.rc]. Control messages–ctl.start, ctl.stop, and ctl.restart–do as their name suggests: identify a service by name and start, stop, or restart it.

libcutils is also exponsed via XPCOM components from a Javascript context within the Gecko system context.

1// Get system property, with "1" as the default value
2let numClients = libcutils.property_get("ro.moz.ril.numclients", "1");
3
4// Set system property value to "1"
5libcutils.property_set("sys.boot_completed", "1");

EngMode API

System properties are also accessible to certified KaiOS apps using the Engmode API . Behind the scenes, the Engmode API uses the same libcutils component packaged with the omni.ja file.

KaiOS 2.5

1// Get system property
2let buildType = navigator.engmodeExtension.getPropertyValue("ro.build.type");
3
4// Set system property value to "b2g"
5navigator.engmodeExtension.setPropertyValue("ctl.stop", "b2g");

KaiOS 3.0

1// Get system property, returns Promise<string>
2navigator.b2g.engmodeManager.getPropertyValue("ro.operator.name")
3    .then((operator) => console.log(operator));
4
5// Set system property value to "1"
6navigator.b2g.engmodeManager.setPropertyValue("persist.service.adb.enable", "1");

Over-permissioning: In 2020, information security firm NCC Group noted that the system Browser is over-permissioned with the jrdextension and engmode permissions. These are used to determine the carrier, but inadvertently grants access the Engmode API from Javascript executed on websites. This remains true across all tested version of KaiOS 2.5.

TCT Web Server

Using the same methodology identified in CVE-2023-33294, it’s possible to access and modify system proprties from any Javascript context using XMLHttpRequest. A local HTTP server is exposed at http://127.0.0.1:2929 on KaiOS 3.0 (http://127.0.0.1:1380/engmode/ on the JioPhone Prima 4G running KaiOS 2.5.4), that accepts arbitrary commands to run as root.

1let xhr = new XMLHttpRequest();
2xhr.open("POST", "http://127.0.0.1:2929", true);
3xhr.send('cmd=shell&shellcommand=getprop ro.build.type');

However, this method isn’t recommended because it exploits a known vulnerability that doesn’t work across all KaiOS versions. Moreover, the port, path, and command syntax vary across devices.

Modifying Properties

Property namespaces (prefixes) are important, namely ro (for properties set only once), and persist (for properties that persist across reboots). Moreover, on KaiOS 2.5.4+ and KaiOS 3.0+, Security-Enhanced Linux (SELinux) property contexts apply, which may prevent certain properties from being modified even with engmode access.

Example Property Files

The following property files are from the recent JioPhone Prima 4G.

default.prop

 1#
 2# ADDITIONAL_DEFAULT_PROPERTIES
 3#
 4persist.log.tag=I
 5ro.secure=1
 6ro.allow.mock.location=0
 7ro.debuggable=0
 8ro.zygote=zygote32
 9dalvik.vm.image-dex2oat-Xms=64m
10dalvik.vm.image-dex2oat-Xmx=64m
11dalvik.vm.dex2oat-Xms=64m
12dalvik.vm.dex2oat-Xmx=512m
13ro.dalvik.vm.native.bridge=0
14debug.atrace.tags.enableflags=0
15camera.disable_zsl_mode=1
16ro.gpu.boost=0
17persist.sys.usb.config=cdrom
18sys.usb.controller=musb-hdrc.0.auto
19ro.support.auto.roam=disabled
20#
21# BOOTIMAGE_BUILD_PROPERTIES
22#
23ro.bootimage.build.date=2023年 09月 01日 星期五 15:45:31 CST
24ro.bootimage.build.date.utc=1693554331
25ro.bootimage.build.fingerprint=Jio/F491H/F491H:6.0/MRA58K/Jio-F491H-F001-04-13-310823:user/release-keys

build.prop

  1
  2# begin build properties
  3# autogenerated by buildinfo.sh
  4ro.build.id=MRA58K
  5ro.build.display.id=MRA58K release-keys
  6ro.build.version.incremental=Jio-F491H-F001-04-13-310823
  7ro.build.version.sdk=23
  8ro.build.version.preview_sdk=0
  9ro.build.version.codename=REL
 10ro.build.version.all_codenames=REL
 11ro.build.version.release=6.0
 12ro.build.version.security_patch=2016-07-01
 13ro.build.version.base_os=
 14ro.build.date=20230901日 星期五 15:42:27 CST
 15ro.build.date.utc=1693554147
 16ro.build.type=user
 17ro.build.user=serveradmin
 18ro.product.version_tag=kaios_jp4_pier_odm_20230829_10
 19ro.fota.sw_ver=F.001.04.13
 20ro.fota.cu_ref=F491H-PBJIINB
 21ro.product.base_version=SPRDROID6.0_KAIOS_17D_RLS3_W20.52.2_P1
 22ro.product.sar_value=Head SAR: 0.89 W/kg Body SAR: 1.37
 23ro.build.host=bjfih007
 24ro.build.tags=release-keys
 25ro.build.flavor=MAD-user
 26ro.product.model=F491H
 27ro.product.brand=JIO
 28ro.product.name=MAD
 29ro.product.device=F491H
 30ro.product.board=sp9820e_1h10
 31# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,
 32# use ro.product.cpu.abilist instead.
 33ro.product.cpu.abi=armeabi-v7a
 34ro.product.cpu.abi2=armeabi
 35ro.product.cpu.abilist=armeabi-v7a,armeabi
 36ro.product.cpu.abilist32=armeabi-v7a,armeabi
 37ro.product.cpu.abilist64=
 38ro.product.manufacturer=LYF-JP4
 39ro.product.locale=en-US
 40ro.wifi.channels=
 41ro.board.platform=sp9820e
 42# ro.build.product is obsolete; use ro.product.device
 43ro.build.product=MAD
 44# Do not try to parse description, fingerprint, or thumbprint
 45ro.build.description=MAD-user 6.0 MRA58K Jio-F491H-F001-04-13-310823 release-keys
 46ro.build.fingerprint=Jio/F491H/F491H:6.0/MRA58K/Jio-F491H-F001-04-13-310823:user/release-keys
 47ro.build.characteristics=default
 48# end build properties
 49#
 50# from device/sprd/sharkle/sp9820e_1h10/system.prop
 51#
 52# Default density config
 53ro.sf.lcd_density=120
 54ro.sf.lcd_width=24
 55ro.sf.lcd_height=32
 56ro.product.hardware=sp9820e_1h10
 57# Set Opengl ES Version
 58ro.opengles.version=196609
 59
 60# ro.fm.chip.port.UART.androidm=true
 61
 62# FRP property for pst device
 63ro.frp.pst=/dev/block/platform/soc/soc:ap-ahb/20600000.sdio/by-name/persist
 64
 65#disable zsl function until zsl capture is ready
 66persist.sys.cam.zsl=false
 67
 68#add for torch node
 69ro.kaios.torch_node=/sys/devices/virtual/misc/sprd_flash/test
 70ro.kaios.torch_enable_value=10
 71ro.kaios.torch_disable_value=11
 72persist.sys.aov.support=false
 73persist.sys.mmi2.support=false
 74ro.product.brand=LYF
 75
 76#enable audio nr tuning
 77ro.audio_tunning.nr=1
 78
 79ro.build.cver=UN_9820_4_4_83_SEC_1
 80
 81#
 82# ADDITIONAL_BUILD_PROPERTIES
 83#
 84ro.config.ringtone=Ring_Synth_04.ogg
 85ro.config.notification_sound=pixiedust.ogg
 86ro.carrier=unknown
 87ro.config.alarm_alert=Alarm_Classic.ogg
 88persist.sys.engpc.disable=1
 89persist.sys.sprd.modemreset=1
 90ro.product.partitionpath=/dev/block/platform/soc/soc:ap-ahb/20600000.sdio/by-name/
 91ro.modem.l.dev=/proc/cptl/
 92ro.modem.l.tty=/dev/stty_lte
 93ro.modem.l.eth=seth_lte
 94ro.modem.l.snd=1
 95ro.modem.l.diag=/dev/sdiag_lte
 96ro.modem.l.log=/dev/slog_lte
 97ro.modem.l.loop=/dev/spipe_lte0
 98ro.modem.l.nv=/dev/spipe_lte1
 99ro.modem.l.assert=/dev/spipe_lte2
100ro.modem.l.vbc=/dev/spipe_lte6
101ro.modem.l.id=0
102ro.modem.l.fixnv_size=0xc8000
103ro.modem.l.runnv_size=0xe8000
104persist.modem.l.nvp=l_
105persist.modem.l.enable=1
106ro.radio.modemtype=l
107ro.telephony.default_network=11
108ro.modem.l.count=1
109persist.msms.phone_count=1
110persist.radio.multisim.config=ssss
111keyguard.no_require_sim=true
112ro.com.android.dataroaming=false
113ro.simlock.unlock.autoshow=1
114ro.simlock.unlock.bynv=0
115ro.simlock.onekey.lock=0
116ro.storage.flash_type=2
117sys.internal.emulated=1
118persist.storage.type=2
119ro.storage.install2internal=0
120drm.service.enabled=false
121ro.treble.enabled=true
122ro.product.first_api_level=26
123ro.vendor.vndk.version=1
124persist.sys.sprd.wcnreset=1
125persist.sys.apr.enabled=0
126persist.sys.start_udpdatastall=0
127persist.sys.apr.intervaltime=1
128persist.sys.apr.testgroup=CSSLAB
129persist.sys.apr.autoupload=1
130persist.sys.heartbeat.enable=1
131persist.sys.power.touch=1
132persist.recents.sprd=1
133ro.kaios.use_timerfd=true
134ro.kaios.usb.functions_node=/config/usb_gadget/g1/configs/b.1/strings/0x409/configuration
135ro.kaios.ums.directory_node=/config/usb_gadget/g1/functions/mass_storage.gs6
136ro.kaios.mtp.directory_node=/config/usb_gadget/g1/functions/mtp.gs0
137ro.kaios.usb.state_node=/sys/class/android_usb/android0/state
138ro.wcn.hardware.product=sharkle
139ro.wcn.hardware.etcpath=/system/etc
140ro.bt.bdaddr_path=/data/misc/bluedroid/btmac.txt
141ro.hotspot.enabled=1
142reset_default_http_response=true
143ro.void_charge_tip=true
144ro.softaplte.coexist=true
145ro.vowifi.softap.ee_warning=false
146persist.sys.wifi.pocketmode=true
147ro.wcn=enabled
148ro.softap.whitelist=true
149ro.btwifisoftap.coexist=true
150persist.wifi.func.hidessid=true
151ro.wifi.softap.maxstanum=10
152ro.wifi.signal.optimized=true
153ro.support.auto.roam=disabled
154ro.wifip2p.coexist=true
155ro.modem.wcn.enable=1
156ro.modem.wcn.diag=/dev/slog_wcn
157ro.modem.wcn.id=1
158ro.modem.wcn.count=1
159ro.modem.gnss.diag=/dev/slog_gnss
160persist.sys.support.vt=false
161persist.sys.csvt=false
162persist.radio.modem.workmode=3,10
163persist.radio.modem.config=TL_LF_W_G,G
164persist.radio.ssda.mode=csfb
165persist.radio.ssda.testmode=3
166persist.radio.ssda.testmode1=10
167ro.wcn.gpschip=ge2
168persist.dbg.wfc_avail_ovr=1
169persist.sys.vowifi.voice=cp
170persist.sys.cam.refocus.enable=false
171ro.lockscreen.disable.default=true
172ro.moz.ril.numclients=1
173ro.moz.ril.query_icc_count=true
174ro.moz.ril.radio_off_wo_card=true
175ro.moz.ril.data_reg_on_demand=true
176ro.moz.ril.ipv6=true
177ro.moz.ril.0.network_types=lte
178ril.ecclist=112,911,122
179persist.user.agent=default
180persist.data.collector.enable=true
181persist.device.vowifi.supported=true
182persist.sys.volte.enable=true
183ro.product.fota=redbend
184ro.moz.nfc.enabled=false
185ro.build.cver=UN_9820_4_4_83_SEC_1
186ro.embms.enable=1
187persist.sys.dalvik.vm.lib.2=libart
188dalvik.vm.isa.arm.variant=generic
189dalvik.vm.isa.arm.features=default
190net.bt.name=Android
191dalvik.vm.stack-trace-file=/data/anr/traces.txt
192ro.expect.recovery_id=0xd65615fd4cbd808139fbedcc46c59e4481a764c4000000000000000000000000

Conclusion

KaiOS’ kernel-level component, Gonk, is built on top of Android’s board support package (BSP) and hardware abstraction layer (HAL). As a result, it retains many features like system properties. Most app developers do not need low-level access, but in rare cases, it can be useful because the necessary data isn’t exposed via other APIs. If you need an expert-level KaiOS partner, contact the author from the About page.